Index: /release-kits/shared/ant-tasks/tasks/antelope/ChangeLog.txt
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/ChangeLog.txt (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/ChangeLog.txt (revision 15058)
@@ -0,0 +1,348 @@
+Antelope Change Log
+Version: @buildnum@
+
+3.4.0:
+o updated for Ant 1.7.
+o finally, Table of Contents List of Tables
+Many of the Antelope tasks are now part of the Ant-Contrib project, http://ant-contrib.sourceforge.net. In this version, 3.4.1, the tasks contained in the Antelope distribution are identical to those in Ant-Contrib other than the package name. The Antelope tasks will continue to be distributed as part of the Antelope distribution, but eventually, the package and code base will reside entirely with Ant-Contrib. Additionally, it is likely that the Ant-Contrib tasks that are not part of Antelope will be included in this distribution as well. The intent is to make Ant-Contrib the central location for additional Ant tasks.
+
+Ant was not designed to be a scripting language. It was meant to replace 'make' and has done an outstanding job in doing so. However, in day to day use in building even small-scale applications, Ant is being used in ways never foreseen by its creators. Complete applications are being build using Ant as the coding language. Build files call other build files, which in turn call other build files. Regardless of the original intent, Ant has become a replacement for batch files, shell scripts, perl scripts, and make files.
+
+Ant is also extensible. The API is nicely defined to allow any number of new tasks to be added, and each new release of Ant includes new and useful tasks. The tasks described here help developers to create more robust build files, and to assist in structuring build files more like a programming or scripting language than is possible with the standard issue tasks.
+
+Several of the tasks described in this manual are based on Java language counterparts:
+
+The Assert task is modeled after the Java
+The If task is modeled after the Java
+The Try task is modeled after the Java
+The Variable task is modeled after Java variable declaration and assignment.
+
+These tasks have become indispensible for me in daily use. I think you will find that your Ant build files are more robust and better structured through the use of these tasks. I've tried to incorporate real-world examples, in fact, many come from the unit tests for the tasks. If you have a source code distribution, you can look at the unit tests for more examples.
+
+ These Ant tasks are licensed under the same Apache license as Ant:
+
+
+
+ If you are running your build files from Antelope, these tasks are already installed and nothing more needs to be done. The following discusses installing the tasks by hand for use outside of Antelope.
+
+ These Ant tasks are packaged as a part of Antelope, which is an application for running Ant build files. They may also be obtained as a separate package. Depending on the distribution you have on hand, copy either antelope.jar or antelope_tasks.jar into your ${ant.home}/lib directory or add it to your classpath. This is the directory where ant.jar and optional.jar are installed for your Ant distribution.
+
+ Once installed, each task that you want to use in a build file must be defined in that build file. Since several of the Antelope tasks are dependent on each other, the preferred way to define them is like this:
+
+ This will load all Antelope tasks without further hassle, and will only load the tasks once. It is not good to load the tasks multiple times, this can cause problems with 'ant' and 'antcall' in particular.
+
+ If you don't want to load all of the tasks, the documentation for each task explains in detail what you will need to add to your build file to use the individual task. For example, the Assert tasks says:
+
+
+
+ Notice that you may name the tasks whatever you want via 'taskdef'. The names listed in the individual task descriptions are those that are set via the preferred method mentioned above.
+
+ As of Antelope version 2.64, the 'AntLib' feature of Ant 1.6 is supported, which provides an alternate way of loading optional tasks. If AntelopeTasks_3.4.1.jar is in the core classpath (in ${ant.home}/lib for example) one can use the namespace short-cut to load them:
+
+ Thanks to Peter Reilly of the Ant development team for this pointer and example.
+
+The Assert task adds an assertion capability to Ant projects. This task works in a manner very similar to the Java
+The Assert task verifies that a given property has a
+given value and throws a BuildException if the property value is not as expected
+or the property does not exist.
+
+Also like Java's
+This task can hold other tasks including Assert.
+
+The Assert task may contain one 'bool' element. The 'bool' element is identical to the ConditionTask, but unlike the ConditionTask, is actually a Task. The 'bool' element can contain all the conditions permitted by the ConditionTask, plus the IsPropertyTrue, IsPropertyFalse,
+StartsWith,
+EndsWith,
+IsGreaterThan,
+IsLessThan,
+DateTimeBefore,
+DateTimeDifference,
+MathEquals conditions.
+See the If task for examples of using these conditionals.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+ Table 4.1. Assert Task Attributes
+
+
+As stated above, the Assert task may contain a nested "bool" task, otherwise,
+the Assert task does not support any nested
+elements apart from Ant tasks. Any valid Ant task may be embedded within the
+assert task.
+
+The "level" attribute is only (so far) useful when Assert is used in conjunction with the Testcase task. Setting this attribute to "warning", "info", or "debug" will force "failonerror" to false.
+
+In the following example, the first
+
+
+The next example shows Assert being used in a unit test for the "limit" task:
+
+
+If the Table of Contents
+The If task provides a greatly improved "if" capability to Ant projects. This task works in a manner very similar to the Java
+This task can hold other tasks including the If task. In particular, it can also have a single "else", which gives Ant a Java-like if/else construct, and a single "bool", which can be used for the "if" boolean expression.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+An If task may contain only one 'bool' and one 'else' and may contain a 'break'. The 'bool' element is identical to the ConditionTask, but unlike the ConditionTask, is actually a Task. The 'bool' element can contain all the conditions permitted by the ConditionTask, plus the IsPropertyTrue, IsPropertyFalse,
+StartsWith,
+EndsWith,
+IsGreaterThan,
+IsLessThan and conditions.
+
+Here is a general outline of the If task:
+
+
+
+ Table 5.1. If Task Attributes
+
+
+The If task can hold any number of Ant tasks. If the property value is correct or the "bool" element evaluates to true, these tasks will be executed.
+
+In addition, the If task supports three special nested elements:
+
+bool This is very similar to the standard Ant Condition task. All conditions supported by the Condition task are supported by the bool element. This is an optional element and if used, is used to decide if the "if" tasks or the "else" tasks should be executed. If the bool element is not used, then the "name" attribute must be used.
+
+else This is very similar to the standard Ant Sequential task. The "else" can hold any number of Ant tasks. These tasks are executed if the "bool" element evaluates to false.
+
+break This is very similar to the Java "break" keyword. This is only useful if the If task is nested in another task that understands "break", such as the Switch task. Like the Java "break", when this element is encountered, no subsequent tasks will be executed and control passes outside the If.
+
+In the following example, the
+
+
+In the next example, the
+
+
+Of course, the same thing could have been done as follows, but the "if" is generally much cleaner.
+
+
+In the next example, the
+
+
+The next example demonstrates nested 'if' tasks. This example will run the unit tests, and if it is Monday, will publish the accumulated test results.
+
+
+
+The next example shows how to use If with Else. Notice that it doesn't matter where the Else is placed inside the If. All tasks in the If that are not in the Else will execute if the property value is correct, otherwise, only those tasks inside the else will execute. The "var" task is discussed here.
+
+
+
+The next example shows the "if" and "assert" tasks working together to validate a property before use, and also shows an example of where the "assert" 'failonerror' attribute might be useful. In this example, if the e-mail address is invalid, the e-mail won't be sent and the build won't fail. The "try" task is discussed here.
+
+
+
+Here is the same thing, but using only If and Else:
+
+
+
+The next example shows how to use the "bool" element:
+
+
+
+The following example shows the "bool" element again:
+
+
+
+The following example is from the unit test for the "Limit" task. It shows the Stopwatch task, the Limit task, and the If task with boolean conditions:
+
+
+
+These conditions are suitable for use in the <bool> element. Unfortunately, they cannot be used in the <condition> task, although all conditions for the <condition> task can be used with the bool and the bool can be used anywhere that <condition> can be used.
+
+Given a property name, tests whether the value for that property equals "true" (or "yes" or "on").
+
+ Table 5.2. IfPropertyTrue Attributes
+
+
+
+Given a property name, tests whether the value for that property equals "false" (or "no" or "off").
+
+ Table 5.3. IfPropertyFalse Attributes
+
+
+
+Given a property name, tests whether the value for that property starts with a specified string.
+
+ Table 5.4. StartsWith Attributes
+
+
+
+Given a property name, tests whether the value for that ends with with a specified string.
+
+ Table 5.5. EndsWith Attributes
+
+
+
+Tests whether the first argument is greater than the second argument. Will
+automatically treat the arguments as numbers if both arguments consists of only the characters 0 through 9 and optionally a decimal point. Otherwise, a String
+comparison is used.
+
+ Table 5.6. IsGreaterThan Attributes
+
+
+
+Tests whether the first argument is less than the second argument. Will
+automatically treat the arguments as numbers if both arguments consists of only the characters 0 through 9 and optionally a decimal point. Otherwise, a String
+comparison is used.
+
+ Table 5.7. IsLessThan Attributes
+
+
+
+Tests whether the first date/time is before the second date/time.
+
+ Table 5.8. DateBefore, TimeBefore
+
+
+
+Tests that the difference between two dates or times is a certain value.
+
+ Table 5.9. DateDifference, TimeDifference
+
+
+
+The "Switch" task works much like the Java "switch" construct. It supports nested "case" elements, which in turn, support nested "break" elements. There is also a "default" case element, so this should be very natural for Java developers to use.
+
+ Table 6.1. Switch Task Attributes
+
+ Table 6.2. "case" and "default" Attributes
+
+
+
+The "Try" task works similarly to the try/catch/finally construct in Java. This task is useful when a particular task might fail, but the build should not fail if it does. An example is the "mail" task will fail if the mail server is not available, but the build should not fail if the mail message cannot be delivered.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+A quick example is probably all that is necessary:
+
+
+Unlike the Java "try", neither the "catch" block nor the "finally" block are required. Also, the order does not matter, the "catch" block may be listed first, followed by the "finally", followed by the tasks that may fail.
+
+ Table 7.1. Try Task Attributes
+
+The next example shows the "break" attribute set to "no". In this case, the second echo task will execute.
+
+
+
+This slightly more practical example uses the Variable task coupled with "try" to run a series of tests. All tests will run even if a preceding test fails. The "catch" block logs a message of each failed test.
+
+
+
+The following example uses a nested Finally to clean up resources:
+
+See the post task for a better way to do a post.
+
+The Unset task provides easier access to one of the most used use cases of Variable, the ability to unset a property. By design, Ant properties are immutable, but sometimes it is handy to set a property to a new value.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+ Table 8.1. Unset Task Attributes
+
+Example:
+
+
+The Variable task provides a mutable property to Ant and works much like variable assignment in Java. This task is similar to the standard Ant Property task, except that THESE PROPERTIES ARE MUTABLE. While this goes against the standard Ant use of properties, occasionally it is useful to be able to change a property value within the build. In general, use of this task is DISCOURAGED, and the standard Ant Property should be used if possible. Having said that, in real life I use this a lot.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+Variables can be set individually or loaded from a standard properties file. A 'feature' of variables is that they can override properties, but properties cannot override variables. So if an already established property exists, its value can be reassigned by use of this task.
+
+ Table 9.1. Variable Task Attributes
+
+In the following example, the property
+
+
+The following shows some more uses of the Variable task. It is especially handy for property appending. Notice a couple of things: the property task can't override a var value, however, if the var value is set to "", then it can as in the case of the format example.
+
+
+
+The next example shows Variable, If, Assert, and Try working together to make sure e-mail is sent from the right address and that if the mail fails to be sent for any reason, the build will not fail.
+
+
+
+The Stopwatch task makes it easy to add performance timing to Ant targets. Stopwatches are named so that multiple watches can run simultaneously.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+ Table 10.1. Stopwatch Task Attributes
+
+The stopwatch is started with the "start" action. When the action is "elapsed" or "total", the running time of the stopwatch is printed out. Both "stop" and "total" stop the stopwatch and reset it to zero. "elapsed" prints out the current running time of the stopwatch without stopping it.
+
+Example:
+
+
+The Limit task is a task container (that is, it holds other tasks) and sets a time limit on how long the nested tasks are allowed to run. This is useful for unit tests that go awry, hung socket connections, or other potentially long running tasks that need to be shut off without stopping the build.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+ Table 11.1. Limit Task Attributes
+
+Examples:
+
+Neither the echo nor the fail will happen in this example. The build will continue once the time has expired.
+
+
+Neither the echo nor the fail will happen in this example. The build will not continue once the time has expired.
+
+
+The FileUtils task provides a number of useful file information functions, such as readability, writability, length, etc. Caution: this task does not follow the standard Ant convention of property immutability.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+ Table 12.1. FileUtil Task Attributes
+
+Operations as nested elements:
+
+listfiles Create a list of files and/or directories.
+ Table 12.2. listfiles
+
+lastmodified Get the "last modified" date/timestamp of a file.
+
+ Table 12.3. lastmodified
+
+
+These operations have no attributes:
+
+canread Is the file readable?
+
+canwrite Is the file writable?
+
+length Finds the length of the file.
+
+filecount Find the number of files in the directory.
+
+isdirectory Is the file a directory?
+
+isfile Is the file a file?
+
+
+
+Only one of the operations can be used at once.
+
+Examples: See the Split for several examples.
+
+The StringUtils task provides a number of useful string manipulation functions, such as converting a string to upper or lower case, trimming white space, finding a substring, etc. Caution: this task does not follow the standard Ant convention of property immutability.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+ Table 13.1. StringUtil Task Attributes
+
+Operations as nested elements:
+
+ Table 13.2. indexof, lastindexof: Find the index of or the last index of a substring.
+
+
+ Table 13.3. substring: Get a substring from the string.
+
+
+ Table 13.4. replace: Replace parts of the string.
+
+ Table 13.5. sort: Sort items in a string.
+This is useful for sorting a comma separated list or a property value that spans several lines.
+
+
+ Table 13.6. messagebox: Put the string in a box for nice display.
+
+These operations have no attributes:
+
+lowercase Converts the string to lowercase.
+
+uppercase Converts the string to uppercase.
+
+length Finds the length of the string.
+
+trim Removes white space from boths ends of the string.
+
+
+
+More than one of the operations can be used at once, that is, you can convert a string to lowercase and trim it at the same time. See below for examples.
+
+Examples:
+
+Convert a string to lower case:
+
+
+Convert a string to upper case:
+
+
+Convert a string to upper case and trim white space:
+
+
+Convert a string to upper case, trim white space, and find a substring:
+
+
+Get the length of a string:
+
+
+Sort a list:
+
+
+Message boxes:
+
+
+The UID task generates a unique ID. This ID may be either a unique string or integer.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+ Table 14.1. UID Task Attributes
+
+Examples:
+
+
+
+The Math task provides support for all the basic mathematical operations
+provided by the java.lang.Math and java.lang.StrictMath classed. It supports int, long, float and double data types. Nesting of operations is supported to allow computation of formulas like (6 + (7.25 * 3.9))/(2 * 3 * 3) or calculating the area of a circle given a radius (I'm sure this comes up often in builds controlled by Ant!).
+
+In addition to the operations provided by the java.lang.Math and java.lang.StrictMath classes, the Math task provides several additional operations: "add", "subtract", "multiply", "divide", and "mod", which duplicate the basic Java mathematical operations "+", "-", "*", "/", and "%", respectively. In fact, either notation can be used, that is, the operation can be set to "add" or "+", depending only on which you feel is more convenient.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+ Table 15.1. Math Task Attributes
+
+The 'result' property is reusable.
+
+ Table 15.2. Op Attributes
+
+The Op element supports nested "Op" elements and nested "Num" elements. A Num represents a number. When an Op is nested in another Op, the nested Op is treated as a Num. The nested elements can be any combination of Op or Num as appropriate for the formula being calculated. Most of the operations provided by java.lang.Math and java.lang.StrictMath operate on one or two numbers. The "+", "-", "*", "/", and "%" operations can task any number of nested numbers.
+
+ Table 15.3. Num Attributes
+
+Some examples:
+
+
+
+This task shows the hostname or IP address of the local machine.
+
+To use this task in your build files, include a task definition like this:
+
+
+ Table 16.1. Hostname Task Attributes
+
+Examples:
+
+
+
+The Post task is a companion to the standard Ant "Get" task. This task does a post and does not necessarily expect anything in return. Almost always, there will be some sort of returned data, this can be logged or written to a file if needed.
+
+To use this task in your build files, include a task definition like this:
+
+
+Basically, an HTTP POST sends name/value pairs to a web server. A very common usage is for html forms for submitting data. A typical use of this task is to send data to a servlet for updating a web page with the status of a build.
+
+This Post task handles cookies and remembers them across calls. This means that you can post to a login form, receive authentication cookies, then subsequent posts will automatically pass the correct cookies. The cookies are stored in memory only, they are not written to disk and will cease to exist upon completion of the build.
+
+The Post task has three ways of specifying the data to be posted. Nested "prop" elements can be used. A "prop" element represents a single name/value pair. The second way is to specify a property file as an attribute to the Post. All properties from the file will be sent as part of the Post data. The third way is to just type in some defined Ant properties. Is it allowed to use all three ways at once, that is, read some properties from a file, specify others via "prop" elements, and just type in some Ant properties.
+
+ Table 17.1. Post Task Attributes
+
+Post supports nested "prop" elements. As an HTTP POST basically sends a list of names and values, the "prop" element represents one name/value pair. A Post may contain any number of "prop" elements.
+
+ Table 17.2. Prop Attributes
+
+The "value" attribute is not strictly required. This provides a short-cut method in cases where the property data is an already-defined Ant property. Suppose the build file has this property defined:
+
+
+
+Then the following are equivalent:
+
+
+
+Defined Ant properties can be entered directly into the post element. Again, suppose the build file has this property defined:
+
+
+
+Then the following are equivalent:
+
+
+
+I googled for the URL in the following example.
+
+
+
+Also see the Grep task for additional examples.
+
+The ssh and scp tasks are no longer included in the main Antelope distribution as they are scheduled to be released as part of Ant 1.6.
+
+AntFetch is identical to the standard 'Ant' task, except that it allows properties from the new project to be set in the original project.
+
+To use this task in your build files, include a task definition like this:
+
+
+Some background may be in order: When the <ant> task is used, in actuality, a new Ant project is created, and depending on the inheritAll property, it is populated with properties from the original project. Then the target in this new project is executed. Any properties set in the new project remain with that project, they do not get "passed back" to the original project. So, for example, if the target in the new project sets a property named "image.directory", there is no reference to that property in the original. Here's an example of what I mean:
+
+Suppose that the "fillImageDirectory" target sets a property named "image.directory" and I call the following:
+
+The output of the echo task will be ${image.directory}, not whatever was set in the "fillImageDirectory" target.
+
+The AntFetch task allows that image.directory property to be set in the original project. The attributes for AntFetch are identical to the 'Ant' task, with one additional, optional attibute. This attribute is named "return" and can be either a single property name or a comma separated list of property names.
+
+Assuming that "fillImageDirectory" actually sets a property named "image.directory", the following example will print out the directory name:
+
+
+And this one will also print out the thumbnail directory:
+
+
+The attributes for AntFetch are identical to the 'ant' task, with one additional, optional attibute. This attribute is named "return" and can be either a single property name or a comma separated list of property names.
+ Table 19.1. AntFetch Attributes
+
+For other attribute and nested element information and more examples, see the documentation for the "ant" task in the Ant documentation.
+
+AntCallBack is identical to the standard 'antcall' task, except that it allows properties set in the called target to be available in the calling target.
+
+To use this task in your build files, include a task definition like this:
+
+
+Some background may be in order: When the <antcall> task is used, in actuality, a new Ant project is created, and depending on the inheritAll property, it is populated with properties from the original project. Then the requested target in this new project is executed. Any properties set in the new project remain with that project, they do not get "passed back" to the original project. So, for example, if the target in the new project sets a property named "image.directory", there is no reference to that property in the original. Here's an example of what I mean:
+
+
+The output from executing "testCallback" looks like this:
+
+Contrast with this output from "antcall":
+
+
+This is an often requested feature for Ant, at least judging from the Ant mailing lists. I assume this is because it allows a more functional programming style than Ant natively supports. The proper Ant way of doing the above is like this:
+
+This is actually looks cleaner in this situation, and is faster, too. There is significant overhead in using both "antcall" and "antcallback" in that they both require a lot of object instantiation and property copying. That said, many people prefer to use "antcall" and "antcallback" as it better fits their logic and style.
+
+The attributes for AntCallBack are identical to the 'antcall' task, with one additional, optional attibute. This attribute is named "return" and can be either a single property name or a comma separated list of property names.
+ Table 20.1. AntCallBack Attributes
+
+For other attribute and nested element information and more examples, see the documentation for the "antcall" task in the Ant documentation.
+
+This is the simplest and possibly the most obvious of the "call" type of tasks. It simply calls a target in the current build file and provides exactly the functionality expected by many users of "antcall".
+
+To use this task in your build files, include a task definition like this:
+
+
+There is only one attribute, that is the name of the target to call.
+
+ Table 21.1. Call Task Attributes
+
+There is none of the weird property manipulation done by "ant", "antcall", "antfetch", or "antcallback", and none of the overhead. When you call a target, any properties set in that target are immediately available in the calling target. A simple example should be all that is necessary:
+
+
+This task uses a regular expression to do pattern matching against a string and store the match in a property. This is useful for extracting a substring, or checking that an html form contains a particular value.
+To use this task in your build files, include a task definition like this:
+
+
+ Table 22.1. Grep Task Attributes
+
+Examples:
+
+
+
+This example uses the 'unset' and 'post' tasks along with 'grep' to list the download url's for Ant:
+
+
+This task splits a property or file into pieces. This is similar to the "split" utility found on most Unix and Linux distributions.
+
+To use this task in your build files, include a task definition like this:
+
+
+
+Once a file has been split into smaller pieces, it can be rejoined with the "concat" task that is part of the standard Ant core tasks.
+
+ Table 23.1. Split Task Attributes
+
+Examples
+
+Split the value of a property into several files:
+
+This will result in 5 files named x.0, x.1, x.2, x.3, and x.4, each containing a single character.
+
+This more involved example shows how to split ant.jar into several files each 100000 bytes in size. The files will be names ant.jar.0, ant.jar.1, ..., ant.jar.10. Then the parts are put back together with concat.
+
+
+The Repeat task performs the same subtasks over and over a certain number of times or until a condition is met. Since most tasks are configured when the build file is first loaded and never again, this task may not do what you want.
+
+To use this task in your build files, include a task definition like this:
+
+
+ Table 24.1. Repeat Task Attributes
+
+Here are a number of examples taken from the unit tests for this task:
+
+
+ Modeled after the TestSuite provided by jUnit, this class is an Ant task that
+ looks through the build file that contains this task, calls a 'setUp' target
+ (if it exists), then executes all nested tasks, and last calls
+ a target named 'tearDown' (if it exists). Both 'setUp' and 'tearDown' are
+ optional targets in the build file. A build file may contain multiple suite tasks, note that each invocation will call 'setUp' and 'tearDown', so you may want to use some conditionals to only have them execute once.
+
+While this task and the associated 'testcase' task work very well, a similar test framework has been created by the Ant development team. You may want to check out that framework as it is likely to be the "standard" Ant test framework. Look for "AntUnit" at http://ant.apache.org.
+
+ Typically, the nested tasks are TestCases, although they can be any task as appropriate to your testing. The nested tasks may also be Suites, so you can group your tests easily. Nested tasks are executed in order.
+
+ Suite may also hold FileSets. Each file in the FileSet will be treated as a file suitable for use by a TestCase and will be executed as such. This makes it easy to run an entire directory of tests without having to specify a TestCase for each one individually.
+
+To use this task in your build files, include a task definition like this:
+
+
+ Table 25.1. Suite Attributes
+
+In the example below, the "suite" tasks is a top-level task, so will execute automatically. This example does not use 'setUp' or 'tearDown' targets.
+
+
+
+ Modeled after the TestCase provided by jUnit, this class is an Ant task that
+ looks through the build file that contains this task, calls a 'setUp' target
+ (if it exists), then all targets whose names start with 'test', and last calls
+ a target named 'tearDown' (if it exists). Both 'setUp' and 'tearDown' are
+ optional targets in the build file.
+
+ Ant stores targets in a hashtable, so there is no guaranteed order in which
+ the 'test*' targets will be called. If order is important, use the 'depends'
+ attribue of a target to enforce order, and do not name dependent targets with
+ a name starting with 'test'.
+
+ Most unit tests will make use of Assert. As the Assert task requires that the property "ant.enable.asserts" be set to true before it will do anything, this task automatically sets this property to true. The Assert task has a "level" attribute. By default, the level is set to "error", so if the Assert fails, the TestCase fails. If the level is set to "warning", the test case will be marked as a warning rather than a failure. If the level is set to "info" or "debug" and the Assert fails, any message associated with the Assert will be written out, but otherwise will be ignored by TestCase.
+
+To use this task in your build files, include a task definition like this:
+
+
+ Table 26.1. TestCase Attributes
+
+TestCase is most often used in conjunction with the Suite task.
+
+
+
+Here is an example build file containing actual tests. The 'setUp' target will execute first, then the two test targets.
+
+
+
+In addition to the tasks described in this manual, Antelope also ships with a special Ant listener than can keep track of the amount of time that each target and task takes to execute. At the end of the build, these times will be sorted from fastest to slowest and displayed following the build output. This can be useful to pinpoint slow and/or inefficient spots in the build process and identify those areas that could benefit from optimization.
+
+The performance listener can be used outside of Antelope by passing a parameter to the command line for Ant:
+
+
+
+Following is an example of the results from using the listener. The result format is projectname.targetname for targets and projectname.targetname.taskname for tasks. All times are shown to the nearest millisecond.
+
+
+The preferred way to send bug reports is to use the
+Issue Tracker at
+
+http://antelope.tigris.org
+.
+ You can also write to me directly at:
+ Dale Anson
+ *
+ * This can happen if the same instance of this task is run twice as
+ * newProject is set to null at the end of execute (to save memory and help
+ * the GC).
+ *
+ * Sets all properties that have been defined as nested property elements.
+ *
+ *
+ * If we cannot clone it, copy the referenced object itself and keep our
+ * fingers crossed.
+ *
+ * This can happen if the same instance of this task is run twice as
+ * newProject is set to null at the end of execute (to save memory and help
+ * the GC).
+ *
+ * Sets all properties that have been defined as nested property elements.
+ *
+ *
+ * If we cannot clone it, copy the referenced object itself and keep our
+ * fingers crossed.
+ *
+ * Also like Java's 'assert' keyword, the Assert task must be 'turned on' using
+ * the property "ant.enable.asserts". If not set, or is set to false, the Assert
+ * task works exactly like the Sequential task.
+ *
+ * Can hold other tasks including Assert. Attributes:
+ *
+ *
+ * The assert task supports a single nested BooleanCondition task, otherwise,
+ * the assert task does not support any nested elements apart from Ant tasks.
+ * Any valid Ant task may be embedded within the assert task.
+ *
+ * @param task Nested task to execute.
+ */
+ public void addTask(Task task) {
+ if (task instanceof BooleanConditionTask) {
+ if (condition_task == null) {
+ condition_task = task;
+ return;
+ }
+ else {
+ throw new BuildException("Only one
+ *
+ *
+ *
+ * @param task Nested task to execute.
+ *
+ *
+ */
+ public void addTask(Task task) {
+ if (task != null)
+ tasks.addElement(task);
+ }
+
+
+ /**
+ * Execute this task and all nested Tasks.
+ *
+ * @exception BuildException Description of Exception
+ */
+ public void execute() throws BuildException {
+ Unset unset = new Unset();
+ StringTokenizer st = new StringTokenizer(values, separator);
+ while (st.hasMoreTokens()) {
+ String value = st.nextToken();
+ value = trim ? value.trim() : value;
+ if (name != null) {
+ unset.setName(name);
+ unset.execute();
+ getProject().setProperty(name, value);
+ }
+ for (Enumeration e = tasks.elements(); e.hasMoreElements(); ) {
+ try {
+ Task task = (Task) e.nextElement();
+ task.perform();
+ }
+ catch (Exception ex) {
+ if (failOnError)
+ throw new BuildException(ex.getMessage());
+ else
+ log(ex.getMessage());
+ }
+ }
+ }
+ }
+
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Grep.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Grep.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Grep.java (revision 15058)
@@ -0,0 +1,224 @@
+package ise.antelope.tasks;
+
+import java.util.*;
+import java.util.regex.*;
+
+
+/**
+ * Borrowed from Antelope, modified to be a general purpose class instead of
+ * an Ant task.
+ *
+ * @version $Revision: 1.1 $
+ */
+public class Grep {
+
+ private String findIn = null;
+ private String regex = null;
+ private int group = 0;
+ private boolean dotall = false;
+ private boolean caseInsensitive = false;
+ private boolean multiLine = false;
+ private boolean unicodeCase = false;
+ private boolean canonEq = false;
+ private boolean comments = false;
+ private boolean unixLines = false;
+ private boolean allMatches = false;
+ private String separator = System.getProperty("line.separator");
+
+ private String grep_match = null;
+ private int count = 0;
+
+ private List matches = new ArrayList();
+
+ /**
+ * Where to look.
+ *
+ * @param string The new in value
+ */
+ public void setIn(String string) {
+ findIn = string;
+ }
+
+ /**
+ * What to look for.
+ *
+ * @param regex The new regex value
+ */
+ public void setRegex(String regex) {
+ this.regex = regex;
+ }
+
+ /**
+ * Set a specific group from the regex.
+ *
+ * @param g The new group value
+ */
+ public void setGroup(int g) {
+ group = g;
+ }
+
+ /**
+ * Sets the dotall attribute for the regex.
+ *
+ * @param b The new dotall value
+ */
+ public void setDotall(boolean b) {
+ dotall = b;
+ }
+
+ /**
+ * Sets the caseinsensitive attribute for the regex.
+ *
+ * @param b The new caseinsensitive value
+ */
+ public void setCaseinsensitive(boolean b) {
+ caseInsensitive = b;
+ }
+
+ /**
+ * Sets the multiline attribute for the regex.
+ *
+ * @param b The new multiline value
+ */
+ public void setMultiline(boolean b) {
+ multiLine = b;
+ }
+
+ /**
+ * Sets the unicodecase attribute for the regex.
+ *
+ * @param b The new unicodecase value
+ */
+ public void setUnicodecase(boolean b) {
+ unicodeCase = b;
+ }
+
+ /**
+ * Sets the canoneq attribute for the regex.
+ *
+ * @param b The new canoneq value
+ */
+ public void setCanoneq(boolean b) {
+ canonEq = b;
+ }
+
+ /**
+ * Sets the comments attribute for the regex.
+ *
+ * @param b The new comments value
+ */
+ public void setComments(boolean b) {
+ comments = b;
+ }
+
+ public void setUnixlines(boolean b) {
+ unixLines = b;
+ }
+
+ /**
+ * If true, concatentates all matches into a single result, if false, only
+ * the first match is returned in the result.
+ *
+ * @param b default is false, only show the first match.
+ */
+ public void setAllmatches(boolean b) {
+ allMatches = b;
+ }
+
+ /**
+ * @return the count of the matches found by the regular expression in
+ * the string
+ */
+ public int getCount() {
+ return matches.size();
+ }
+
+ /**
+ * @return the match found by the regular expression in the string. If
+ * 'all matches' was set to true, then each match will be contained in
+ * this string, separated by the separator specified in
+ *
+ * I updated this task in Apr 2005 to be able to show all hostnames and IP's for
+ * the local machine, which is sometimes handy for machines with dual cards,
+ * like maybe an ethernet card and a wireless card.
+ *
+ * Dale Anson, May 2001
+ *
+ * @version $Revision: 1.2 $
+ */
+public class HostnameTask extends Task {
+
+ private String property = "hostname";
+ private boolean useIp = false;
+ private String host = null;
+ private String nIC = null;
+ private boolean failOnError = false;
+ private boolean showAll = false;
+ private boolean canonical = true;
+ private int outputType = 0;
+ public static final int HOST = 0;
+ public static final int IP = 1;
+ public static final int CANON = 2;
+
+ /**
+ * @param p The name of the property to hold the hostname or IP address.
+ */
+ public void setProperty(String p) {
+ property = p;
+ }
+
+ /**
+ * Should this task get the IP address of the local host instead of the
+ * hostname? Default is no, get the hostname, not the IP address.
+ *
+ * @param b The new ip value
+ */
+ public void setShowip(boolean b) {
+ useIp = b;
+ outputType = IP;
+ }
+
+ /**
+ * Should the build fail if this task fails? Default is no.
+ *
+ * @param b The new failonerror value
+ */
+ public void setFailonerror(boolean b) {
+ failOnError = b;
+ }
+
+ /**
+ * Set a specific network interface to get info for.
+ *
+ * @param n The new nic value
+ */
+ public void setNic(String n) {
+ nIC = n;
+ }
+
+ /**
+ * Show all network interfaces, hostnames and IPs for the local host.
+ * Default is false. If used, output will be something like:
+ *
+ *
+ *
+ * Can hold other tasks including IfTask, in particular, an ElseTask and a
+ * Break.
+ *
+ * @author Dale Anson, danson@germane-software.com
+ * @since Ant 1.5
+ */
+public class IfTask extends Task implements TaskContainer, Breakable {
+
+ // attribute storage
+ private boolean exists = true;
+ private String value = null;
+ private String name = null;
+
+ private Task else_task = null;
+ private Task condition_task = null;
+
+ // vector to hold any nested tasks
+ private Vector tasks = new Vector();
+
+ // break condition
+ private boolean doBreak = false;
+
+
+ /** Automatically define dependent tasks. */
+ public void init() {
+ // may need to do this differently for Ant 1.6, need to check when 1.6
+ // is final
+ getProject().addTaskDefinition( "else", ElseTask.class );
+ getProject().addTaskDefinition( "bool", BooleanConditionTask.class );
+ getProject().addTaskDefinition( "break", Break.class );
+ }
+
+
+ /**
+ * Set the name of the property to test. Required unless nested condition is
+ * used.
+ *
+ * @param name the name of the property to test.
+ */
+ public void setName( String name ) {
+ this.name = name;
+ }
+
+
+ /**
+ * Set the expected value of the property. Implies 'exists'.
+ *
+ * @param task Nested task to execute.
+ */
+ public void addTask( Task task ) {
+ if ( task instanceof ElseTask ) {
+ if ( else_task == null ) {
+ else_task = task;
+ return ;
+ }
+ else {
+ throw new BuildException( "Only one Developed for use with Antelope, migrated to ant-contrib Oct 2003.
+ *
+ * @author Dale Anson
+ * @author Robert D. Rice
+ * @version $Revision: 1.4 $
+ * @since Ant 1.5
+ */
+public class Limit extends Task implements TaskContainer {
+
+
+ // storage for nested tasks
+ private Vector tasks = new Vector();
+
+
+ // time units, default value is 3 minutes.
+ private long maxwait = 180;
+ protected TimeUnit unit = TimeUnit.SECOND_UNIT;
+
+ // property to set if time limit is reached
+ private String timeoutProperty = null;
+ private String timeoutValue = "true";
+
+
+ // storage for task currently executing
+ private Task currentTask = null;
+
+
+ // used to control thread stoppage
+ private Thread taskRunner = null;
+
+
+ // should the build fail if the time limit has expired? Default is no.
+ private boolean failOnError = false;
+
+
+ private Exception exception = null;
+
+
+
+
+ /**
+ * Add a task to wait on.
+ *
+ * @param task A task to execute
+ * @exception BuildException won't happen
+ */
+ public void addTask( Task task ) throws BuildException {
+ tasks.addElement( task );
+ }
+
+
+
+
+ /**
+ * How long to wait for all nested tasks to complete, in units.
+ * Default is to wait 3 minutes.
+ *
+ * @param wait time to wait, set to 0 to wait forever.
+ */
+ public void setMaxwait( int wait ) {
+ maxwait = wait;
+ }
+
+ /**
+ * Sets the unit for the max wait. Default is minutes.
+
+ * @param unit valid values are "millisecond", "second", "minute", "hour", "day", and "week".
+
+ */
+ public void setUnit( String unit ) {
+ if ( unit == null )
+ return ;
+ if ( unit.equals( TimeUnit.SECOND ) ) {
+ setMaxWaitUnit( TimeUnit.SECOND_UNIT );
+ return ;
+ }
+ if ( unit.equals( TimeUnit.MILLISECOND ) ) {
+ setMaxWaitUnit( TimeUnit.MILLISECOND_UNIT );
+ return ;
+ }
+ if ( unit.equals( TimeUnit.MINUTE ) ) {
+ setMaxWaitUnit( TimeUnit.MINUTE_UNIT );
+ return ;
+ }
+ if ( unit.equals( TimeUnit.HOUR ) ) {
+ setMaxWaitUnit( TimeUnit.HOUR_UNIT );
+ return ;
+ }
+ if ( unit.equals( TimeUnit.DAY ) ) {
+ setMaxWaitUnit( TimeUnit.DAY_UNIT );
+ return ;
+ }
+ if ( unit.equals( TimeUnit.WEEK ) ) {
+ setMaxWaitUnit( TimeUnit.WEEK_UNIT );
+ return ;
+ }
+
+ }
+
+ /**
+ * Set a millisecond wait value.
+ * @param value the number of milliseconds to wait.
+ */
+ public void setMilliseconds( int value ) {
+ setMaxwait( value );
+ setMaxWaitUnit( TimeUnit.MILLISECOND_UNIT );
+ }
+
+ /**
+ * Set a second wait value.
+ * @param value the number of seconds to wait.
+ */
+ public void setSeconds( int value ) {
+ setMaxwait( value );
+ setMaxWaitUnit( TimeUnit.SECOND_UNIT );
+ }
+
+ /**
+ * Set a minute wait value.
+ * @param value the number of milliseconds to wait.
+ */
+ public void setMinutes( int value ) {
+ setMaxwait( value );
+ setMaxWaitUnit( TimeUnit.MINUTE_UNIT );
+ }
+
+ /**
+ * Set an hours wait value.
+ * @param value the number of hours to wait.
+ */
+ public void setHours( int value ) {
+ setMaxwait( value );
+ setMaxWaitUnit( TimeUnit.HOUR_UNIT );
+ }
+
+ /**
+ * Set a day wait value.
+ * @param value the number of days to wait.
+ */
+ public void setDays( int value ) {
+ setMaxwait( value );
+ setMaxWaitUnit( TimeUnit.DAY_UNIT );
+ }
+
+ /**
+ * Set a week wait value.
+ * @param value the number of weeks to wait.
+ */
+ public void setWeeks( int value ) {
+ setMaxwait( value );
+ setMaxWaitUnit( TimeUnit.WEEK_UNIT );
+ }
+
+ /**
+ * Set the max wait time unit, default is minutes.
+ */
+ public void setMaxWaitUnit( TimeUnit unit ) {
+ this.unit = unit;
+ }
+
+
+ /**
+ * Determines whether the build should fail if the time limit has
+ * expired on this task.
+ * Default is no.
+ *
+ * @param fail if true, fail the build if the time limit has been reached.
+ */
+ public void setFailonerror( boolean fail ) {
+ failOnError = fail;
+ }
+
+
+ /**
+ * Name the property to set after a timeout.
+ *
+ * @param p of property to set if the time limit has been reached.
+ */
+ public void setProperty( String p ) {
+ timeoutProperty = p;
+ }
+
+
+ /**
+ * The value for the property to set after a timeout, defaults to true.
+ *
+ * @param v for the property to set if the time limit has been reached.
+ */
+ public void setValue( String v ) {
+ timeoutValue = v;
+ }
+
+
+ /**
+ * Execute all nested tasks, but stopping execution of nested tasks after
+ * maxwait or when all tasks are done, whichever is first.
+ *
+ * @exception BuildException Description of the Exception
+ */
+ public void execute() throws BuildException {
+ try {
+ // start executing nested tasks
+ final Thread runner =
+ new Thread() {
+ public void run() {
+ Enumeration e = tasks.elements();
+ while ( e.hasMoreElements() ) {
+ if ( taskRunner != this ) {
+ break;
+ }
+ currentTask = ( Task ) e.nextElement();
+ try {
+ currentTask.perform();
+ }
+ catch ( Exception ex ) {
+ if ( failOnError ) {
+ exception = ex;
+ return ;
+ }
+ else {
+ exception = ex;
+ }
+ }
+ }
+ }
+ };
+ taskRunner = runner;
+ runner.start();
+ runner.join( unit.toMillis( maxwait ) );
+
+
+ // stop executing the nested tasks
+ if ( runner.isAlive() ) {
+ taskRunner = null;
+ runner.interrupt();
+ int index = tasks.indexOf( currentTask );
+ StringBuffer not_ran = new StringBuffer();
+ for ( int i = index + 1; i < tasks.size(); i++ ) {
+ not_ran.append( '<' ).append( ( ( Task ) tasks.get( i ) ).getTaskName() ).append( '>' );
+ if ( i < tasks.size() - 1 ) {
+ not_ran.append( ", " );
+ }
+ }
+
+
+ // maybe set timeout property
+ if ( timeoutProperty != null ) {
+ getProject().setNewProperty( timeoutProperty, timeoutValue );
+ }
+
+
+ // create output message
+ StringBuffer msg = new StringBuffer();
+ msg.append( "Interrupted task <" )
+ .append( currentTask.getTaskName() )
+ .append( ">. Waited " )
+ .append( ( maxwait ) ).append( " " ).append( unit.getValue() )
+ .append( ", but this task did not complete." )
+ .append( ( not_ran.length() > 0 ?
+ " The following tasks did not execute: " + not_ran.toString() + "." :
+ "" ) );
+
+
+ // deal with it
+ if ( failOnError ) {
+ throw new BuildException( msg.toString() );
+ }
+ else {
+ log( msg.toString() );
+ }
+ }
+ else if ( failOnError && exception != null ) {
+ throw new BuildException( exception );
+ }
+ }
+ catch ( Exception e ) {
+ throw new BuildException( e );
+ }
+ }
+
+
+}
+
+
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Math.java_
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Math.java_ (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Math.java_ (revision 15058)
@@ -0,0 +1,667 @@
+/*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Ant", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+*
+ *
+ * The default wait period is 3 minutes (180 seconds).
+ *
+ * @param wait time to wait in seconds, set to 0 to wait forever.
+ */
+ public void setMaxwait( int wait ) {
+ maxwait = wait * 1000;
+ }
+
+
+ /**
+ * Should the build fail if the post fails?
+ *
+ * @param fail true = fail the build, default is false
+ */
+ public void setFailonerror( boolean fail ) {
+ failOnError = fail;
+ }
+
+ /**
+ * Adds a name/value pair to post. Optional.
+ *
+ * @param p A property pair to send as part of the post.
+ * @exception BuildException When name and/or value are missing.
+ */
+ public void addConfiguredProp( Prop p ) throws BuildException {
+ String name = p.getName();
+ if ( name == null ) {
+ throw new BuildException( "name is null", getLocation() );
+ }
+ String value = p.getValue();
+ if ( value == null ) {
+ value = getProject().getProperty( name );
+ }
+ if ( value == null ) {
+ throw new BuildException( "value is null", getLocation() );
+ }
+ props.put( name, value );
+ }
+
+
+ /**
+ * Adds a feature to the Text attribute of the PostTask object
+ *
+ * @param text The feature to be added to the Text attribute
+ */
+ public void addText( String text ) {
+ textProps = text;
+ }
+
+
+ /**
+ * Do the post.
+ *
+ * @exception BuildException On any error.
+ */
+ public void execute() throws BuildException {
+ if ( to == null ) {
+ throw new BuildException( "'to' attribute is required", getLocation() );
+ }
+ final String content = getContent();
+ try {
+ if ( verbose )
+ log( "Opening connection for post to " + to.toString() + "..." );
+
+ // do the POST
+ Thread runner =
+ new Thread() {
+ public void run() {
+ DataOutputStream out = null;
+ try {
+ // set the url connection properties
+ connection = to.openConnection();
+ connection.setDoInput( true );
+ connection.setDoOutput( true );
+ connection.setUseCaches( false );
+ connection.setRequestProperty(
+ "Content-Type",
+ "application/x-www-form-urlencoded" );
+
+ // check if there are cookies to be included
+ for ( Iterator it = cookieStorage.keySet().iterator(); it.hasNext(); ) {
+ StringBuffer sb = new StringBuffer();
+ Object name = it.next();
+ if ( name != null ) {
+ String key = name.toString();
+ Cookie cookie = ( Cookie ) cookieStorage.get( name );
+ if ( to.getPath().startsWith( cookie.getPath() ) ) {
+ connection.addRequestProperty( "Cookie", cookie.toString() );
+ if (verbose)
+ log("Added cookie: " + cookie.toString());
+ }
+ }
+ }
+
+ // do the post
+ if ( verbose ) {
+ log( "Connected, sending data..." );
+ }
+ out = new DataOutputStream( connection.getOutputStream() );
+ if ( verbose ) {
+ log( content );
+ }
+ out.writeBytes( content );
+ out.flush();
+ if ( verbose ) {
+ log( "Data sent." );
+ }
+ }
+ catch ( Exception e ) {
+ if ( failOnError ) {
+ throw new BuildException( e, getLocation() );
+ }
+ }
+ finally {
+ try {
+ out.close();
+ }
+ catch ( Exception e ) {
+ // ignored
+ }
+ }
+ }
+ }
+ ;
+ runner.start();
+ runner.join( maxwait );
+ if ( runner.isAlive() ) {
+ runner.interrupt();
+ if ( failOnError ) {
+ throw new BuildException( "maxwait exceeded, unable to send data", getLocation() );
+ }
+ return ;
+ }
+
+ // read the response, if any, optionally writing it to a file
+ if ( wantResponse ) {
+ if ( verbose ) {
+ log( "Waiting for response..." );
+ }
+ runner =
+ new Thread() {
+ public void run() {
+ PrintWriter fw = null;
+ StringWriter sw = null;
+ PrintWriter pw = null;
+ FileOutputStream dw = null;
+ BufferedInputStream in = null;
+ byte[] buffer = new byte[8192];
+ File downloadFile = null;
+ try {
+ if ( connection instanceof HttpURLConnection ) {
+ // read and store cookies
+ Map map = ( ( HttpURLConnection ) connection ).getHeaderFields();
+ for ( Iterator it = map.keySet().iterator(); it.hasNext(); ) {
+ String name = ( String ) it.next();
+ if ( name != null && name.equals( "Set-Cookie" ) ) {
+ List cookies = ( List ) map.get( name );
+ for ( Iterator c = cookies.iterator(); c.hasNext(); ) {
+ String raw = ( String ) c.next();
+ Cookie cookie = new Cookie( raw );
+ cookieStorage.put( cookie.getId(), cookie );
+ }
+ }
+ }
+
+ // maybe log response headers
+ if ( verbose ) {
+ log( String.valueOf( ( ( HttpURLConnection ) connection ).getResponseCode() ) );
+ log( ( ( HttpURLConnection ) connection ).getResponseMessage() );
+ map = ( ( HttpURLConnection ) connection ).getHeaderFields();
+ StringBuffer sb = new StringBuffer();
+ for ( Iterator it = map.keySet().iterator(); it.hasNext(); ) {
+ String name = ( String ) it.next();
+ sb.append( name ).append( "=" );
+ List values = ( List ) map.get( name );
+ if ( values != null ) {
+ if ( values.size() == 1 )
+ sb.append( values.get( 0 ) );
+ else if ( values.size() > 1 ) {
+ sb.append( "[" );
+ for ( Iterator v = values.iterator(); v.hasNext(); ) {
+ sb.append( v.next() ).append( "," );
+ }
+ sb.append( "]" );
+ }
+ }
+ sb.append( "\n" );
+ log( sb.toString() );
+ }
+ }
+
+ // might have a download
+ map = ( ( HttpURLConnection ) connection ).getHeaderFields();
+ List values = (List)map.get("Content-Type");
+ String content_type = null;
+ if (values != null)
+ content_type = (String)values.get(0);
+ if (content_type != null && content_type.equals("application/download")) {
+ if (outdir == null) {
+ outdir = new File(getProject().getProperty("basedir"));
+ }
+ String cd = (String)(((List)map.get("Content-Disposition")).get(0));
+ int index = cd.indexOf("filename=");
+ if (index >= 0) {
+ String filename = cd.substring(index + "filename=".length());
+ filename = filename.replaceAll("\"", "");
+ downloadFile = new File(outdir, filename);
+ }
+ }
+ }
+ in = new BufferedInputStream( connection.getInputStream() );
+ if ( log != null ) {
+ // user wants output stored to a file
+ fw = new PrintWriter( new FileWriter( log, append ) );
+ }
+ if ( property != null ) {
+ // user wants output stored in a property
+ sw = new StringWriter();
+ pw = new PrintWriter( sw );
+ }
+ if (downloadFile != null) {
+ dw = new FileOutputStream( downloadFile );
+ }
+ int byte_count = in.read(buffer, 0, buffer.length);
+ while ( byte_count > -1 ) {
+ String line = new String( buffer, 0, byte_count );
+ if ( currentRunner != this ) {
+ break;
+ }
+ if ( verbose ) {
+ log( line );
+ }
+ if ( fw != null ) {
+ // write response to a file
+ fw.print( line );
+ }
+ if ( pw != null ) {
+ // write response to a property
+ pw.print( line );
+ }
+ if (dw != null) {
+ dw.write( buffer, 0, byte_count );
+ }
+ byte_count = in.read(buffer, 0, buffer.length);
+ }
+ }
+ catch ( Exception e ) {
+ e.printStackTrace();
+ if ( failOnError ) {
+ throw new BuildException( e, getLocation() );
+ }
+ }
+ finally {
+ try {
+ in.close();
+ }
+ catch ( Exception e ) {
+ // ignored
+ }
+ try {
+ if ( fw != null ) {
+ fw.flush();
+ fw.close();
+ }
+ }
+ catch ( Exception e ) {
+ // ignored
+ }
+ }
+ if ( property != null && sw != null ) {
+ // save property
+ getProject().setProperty( property, sw.toString() );
+ }
+ }
+ };
+ currentRunner = runner;
+ runner.start();
+ runner.join( maxwait );
+ if ( runner.isAlive() ) {
+ currentRunner = null;
+ runner.interrupt();
+ if ( failOnError ) {
+ throw new BuildException( "maxwait exceeded, unable to receive data", getLocation() );
+ }
+ }
+ }
+ if ( verbose )
+ log( "Post complete." );
+ }
+ catch ( Exception e ) {
+ if ( failOnError ) {
+ throw new BuildException( e );
+ }
+ }
+ }
+
+
+ /**
+ * Borrowed from Property -- load variables from a file
+ *
+ * @param file file to load
+ * @exception BuildException Description of the Exception
+ */
+ private void loadFile( File file ) throws BuildException {
+ Properties fileprops = new Properties();
+ try {
+ if ( file.exists() ) {
+ FileInputStream fis = new FileInputStream( file );
+ try {
+ fileprops.load( fis );
+ }
+ finally {
+ if ( fis != null ) {
+ fis.close();
+ }
+ }
+ addProperties( fileprops );
+ }
+ else {
+ log( "Unable to find property file: " + file.getAbsolutePath(),
+ Project.MSG_VERBOSE );
+ }
+ log( "Post complete." );
+ }
+ catch ( Exception e ) {
+ if ( failOnError ) {
+ throw new BuildException( e );
+ }
+ }
+ }
+
+
+ /**
+ * Builds and formats the message to send to the server. Message is UTF-8
+ * encoded unless encoding has been explicitly set.
+ *
+ * @return the message to send to the server.
+ */
+ private String getContent() {
+ if ( propsFile != null ) {
+ loadFile( propsFile );
+ }
+
+ if ( textProps != null ) {
+ loadTextProps( textProps );
+ }
+
+ StringBuffer content = new StringBuffer();
+ try {
+ Enumeration en = props.keys();
+ while ( en.hasMoreElements() ) {
+ String name = ( String ) en.nextElement();
+ String value = ( String ) props.get( name );
+ content.append( URLEncoder.encode( name, encoding ) );
+ content.append( "=" );
+ content.append( URLEncoder.encode( value, encoding ) );
+ if ( en.hasMoreElements() ) {
+ content.append( "&" );
+ }
+ }
+ }
+ catch ( IOException ex ) {
+ if ( failOnError ) {
+ throw new BuildException( ex, getLocation() );
+ }
+ }
+ return content.toString();
+ }
+
+
+ /**
+ * Description of the Method
+ *
+ * @param tp
+ */
+ private void loadTextProps( String tp ) {
+ Properties p = new Properties();
+ Project project = getProject();
+ StringTokenizer st = new StringTokenizer( tp, "$" );
+ while ( st.hasMoreTokens() ) {
+ String token = st.nextToken();
+ int start = token.indexOf( "{" );
+ int end = token.indexOf( "}" );
+ if ( start > -1 && end > -1 && end > start ) {
+ String name = token.substring( start + 1, end - start );
+ String value = project.getProperty( name );
+ if ( value != null )
+ p.setProperty( name, value );
+ }
+ }
+ addProperties( p );
+ }
+
+
+ /**
+ * Borrowed from Property -- iterate through a set of properties, resolve
+ * them, then assign them
+ *
+ * @param fileprops The feature to be added to the Properties attribute
+ */
+ private void addProperties( Properties fileprops ) {
+ resolveAllProperties( fileprops );
+ Enumeration e = fileprops.keys();
+ while ( e.hasMoreElements() ) {
+ String name = ( String ) e.nextElement();
+ String value = fileprops.getProperty( name );
+ props.put( name, value );
+ }
+ }
+
+
+ /**
+ * Borrowed from Property -- resolve properties inside a properties
+ * hashtable
+ *
+ * @param fileprops Description of the Parameter
+ * @exception BuildException Description of the Exception
+ */
+ private void resolveAllProperties( Properties fileprops ) throws BuildException {
+ for ( Enumeration e = fileprops.keys(); e.hasMoreElements(); ) {
+ String name = ( String ) e.nextElement();
+ String value = fileprops.getProperty( name );
+
+ boolean resolved = false;
+ while ( !resolved ) {
+ Vector fragments = new Vector();
+ Vector propertyRefs = new Vector();
+ /// this is the Ant 1.5 way of doing it. The Ant 1.6 PropertyHelper
+ /// should be used -- eventually.
+ ProjectHelper.parsePropertyString( value, fragments,
+ propertyRefs );
+
+ resolved = true;
+ if ( propertyRefs.size() != 0 ) {
+ StringBuffer sb = new StringBuffer();
+ Enumeration i = fragments.elements();
+ Enumeration j = propertyRefs.elements();
+ while ( i.hasMoreElements() ) {
+ String fragment = ( String ) i.nextElement();
+ if ( fragment == null ) {
+ String propertyName = ( String ) j.nextElement();
+ if ( propertyName.equals( name ) ) {
+ throw new BuildException( "Property " + name
+ + " was circularly "
+ + "defined." );
+ }
+ fragment = getProject().getProperty( propertyName );
+ if ( fragment == null ) {
+ if ( fileprops.containsKey( propertyName ) ) {
+ fragment = fileprops.getProperty( propertyName );
+ resolved = false;
+ }
+ else {
+ fragment = "${" + propertyName + "}";
+ }
+ }
+ }
+ sb.append( fragment );
+ }
+ value = sb.toString();
+ fileprops.put( name, value );
+ }
+ }
+ }
+ }
+
+ /**
+ * Represents a cookie. See RFC 2109 and 2965.
+ */
+ public class Cookie {
+ private String name;
+ private String value;
+ private String domain;
+ private String path = "/";
+ private String id;
+
+ /**
+ * @param raw the raw string abstracted from the header of an http response
+ * for a single cookie.
+ */
+ public Cookie( String raw ) {
+ String[] args = raw.split( "[;]" );
+ for ( int i = 0; i < args.length; i++ ) {
+ String part = args[ i ];
+ int eq_index = part.indexOf("=");
+ if (eq_index == -1)
+ continue;
+ String first_part = part.substring(0, eq_index).trim();
+ String second_part = part.substring(eq_index + 1);
+ if ( i == 0 ) {
+ name = first_part;
+ value = second_part;
+ }
+ else if ( first_part.equalsIgnoreCase( "Path" ) )
+ path = second_part;
+ else if ( first_part.equalsIgnoreCase( "Domain" ) )
+ domain = second_part;
+ }
+ if (name == null)
+ throw new IllegalArgumentException("Raw cookie does not contain a cookie name.");
+ if (path == null)
+ path = "/";
+ setId(path, name);
+ }
+
+ /**
+ * @param name name of the cookie
+ * @param value the value of the cookie
+ */
+ public Cookie( String name, String value ) {
+ if (name == null)
+ throw new IllegalArgumentException("Cookie name may not be null.");
+
+ this.name = name;
+ this.value = value;
+ setId(name);
+ }
+
+ /**
+ * @return the id of the cookie, used internally by Post to store the cookie
+ * in a hashtable.
+ */
+ public String getId() {
+ if (id == null)
+ setId(path, name);
+ return id.toString();
+ }
+
+ private void setId(String name) {
+ setId(path, name);
+ }
+
+ private void setId(String path, String name) {
+ if (name == null)
+ name = "";
+ id = path + name;
+ }
+
+ /**
+ * @return the name of the cookie
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return the value of the cookie
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * @param domain the domain of the cookie
+ */
+ public void setDomain( String domain ) {
+ this.domain = domain;
+ }
+
+ /**
+ * @return the domain of the cookie
+ */
+ public String getDomain() {
+ return domain;
+ }
+
+ /**
+ * @param path the path of the cookie
+ */
+ public void setPath( String path ) {
+ this.path = path;
+ }
+
+ /**
+ * @return the path of the cookie
+ */
+ public String getPath() {
+ return path;
+ }
+
+ /**
+ * @return a Cookie formatted as a Cookie Version 1 string. The returned
+ * string is suitable for including with an http request.
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append( name ).append( "=" ).append( value ).append( ";" );
+ if ( domain != null )
+ sb.append( "Domain=" ).append( domain ).append( ";" );
+ if ( path != null )
+ sb.append( "Path=" ).append( path ).append( ";" );
+ sb.append( "Version=\"1\";" );
+ return sb.toString();
+ }
+ }
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/ReadLog.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/ReadLog.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/ReadLog.java (revision 15058)
@@ -0,0 +1,124 @@
+package ise.antelope.tasks;
+
+import java.net.URL;
+import java.text.*;
+import java.util.*;
+import java.util.regex.*;
+
+import org.apache.tools.ant.BuildException;
+
+import org.apache.tools.ant.Task;
+
+/**
+ * Not an antelope task, this is for Cobalt, but put it in the same package
+ * for easier use.
+ *
+ * @version $Revision: 1.1 $
+ */
+public class ReadLog extends Task {
+
+ private URL logURL = null;
+ private String property = null;
+ private int minutes = 2;
+
+ public void setUrl(URL url) {
+ logURL = url;
+ }
+
+ /**
+ * Where to put the log contents.
+ *
+ * @param name The new property value
+ */
+ public void setProperty(String name) {
+ property = name;
+ }
+
+ /**
+ * Set the number of minutes to read, so, for example, 2 would read the most
+ * recent 2 minutes from the log.
+ *
+ * @param m the number of minutes. Use -1 to read the complete log.
+ * Default setting is to read 2 minutes.
+ */
+ public void setMinutes(int m) {
+ minutes = m;
+ }
+
+
+ public void execute() {
+ // check attributes
+ if (property == null)
+ throw new BuildException("Property is null.");
+ if (logURL == null)
+ throw new BuildException("URL is null.");
+ if (minutes < -1)
+ minutes = -1;
+
+ try {
+ // fetch the log
+ PostTask post = new PostTask();
+ post.setProject(getProject());
+ post.setTo(logURL);
+ Date now = new Date();
+ String temp_property = property + now.getTime();
+ post.setProperty(temp_property);
+ post.setVerbose(false);
+ post.execute();
+ String log = getProject().getProperty(temp_property);
+
+ if (minutes == -1) {
+ // save the complete log
+ getProject().setProperty(property, log);
+ }
+ else {
+ // calculate how much of log to save into property
+ long end_time = now.getTime() - (minutes * 1000 * 60);
+
+ // split up the log to parse the dates
+ String[] msgs = log.split("
+ *
+ * @param task Nested task to execute.
+ */
+ public void addTask( Task task ) {
+ if ( tasks == null )
+ tasks = new Vector();
+ tasks.addElement( task );
+ }
+
+ /**
+ * Add a fileset to the suite. For each file in the fileset, a testcase
+ * will be created.
+ */
+ public void addFileset( FileSet fs ) {
+ if ( tasks == null )
+ tasks = new Vector();
+ tasks.addElement( fs );
+ }
+
+ /**
+ * Set a name for the suite, optional attribute.
+ * @param s the name for the suite.
+ */
+ public void setName( String s ) {
+ name = s;
+ }
+
+ /**
+ * @return the name of the suite, may be null.
+ */
+ public String getName() {
+ return name;
+ }
+
+ public void setFailonerror(boolean f) {
+ failonerror = f;
+ }
+
+ public boolean getFailonerror() {
+ return failonerror;
+ }
+
+ /**
+ * Set to true if the test should be allowed to run.
+ * @param b if true, execute the test. This is handy for enabling or disabling
+ * groups of tests by setting a single property. Optional, default
+ * is true, the suite should run.
+ */
+ public void setEnabled( boolean b ) {
+ enabled = b;
+ }
+
+ /**
+ * Should asserts be enabled? Asserts are enabled by default.
+ * @param b if false, disable asserts
+ */
+ public void setAssertsenabled( boolean b ) {
+ assertEnabled = b;
+ }
+
+ /**
+ * Should the results be shown?
+ * @param b show the results if true
+ */
+ public void setShowsummary( boolean b ) {
+ showSummary = b;
+ }
+
+ public int getTestCaseCount() {
+ return totalTestCount;
+ }
+
+ public int getRanCount() {
+ return totalRanCount;
+ }
+
+ public int getPassedCount() {
+ return totalPassedCount;
+ }
+
+ public int getFailedCount() {
+ return totalFailedCount;
+ }
+
+ /**
+ * @return an Enumeration of the failures. Individual elements are Strings
+ * containing the name of the failed target and the reason why it
+ * failed.
+ */
+ public Enumeration getFailures() {
+ return failures.elements();
+ }
+
+ public int getWarningCount() {
+ return totalWarningCount;
+ }
+
+ /** Run tests. */
+ public void execute() {
+ if ( !enabled )
+ return ;
+
+ String ae = assertEnabled ? "true" : "false";
+ if ( assertEnabled )
+ getProject().setProperty( "ant.enable.asserts", ae );
+
+ try {
+ // get the setUp and tearDown targets
+ Target setUp = null;
+ Target tearDown = null;
+ Hashtable targets = getProject().getTargets();
+ Enumeration en = targets.keys();
+ while ( en.hasMoreElements() ) {
+ String target_name = ( String ) en.nextElement();
+ if ( target_name.equals( "setUp" ) )
+ setUp = ( Target ) targets.get( target_name );
+ else if ( target_name.equals( "tearDown" ) )
+ tearDown = ( Target ) targets.get( target_name );
+ }
+
+ // run the setUp target
+ if ( setUp != null )
+ setUp.execute();
+
+ // create testcases out of any filesets, maintaining order with
+ // testcases already added.
+ Vector testcases = new Vector();
+ if ( tasks != null && tasks.size() > 0 ) {
+ for ( Enumeration e = tasks.elements(); e.hasMoreElements(); ) {
+ Object o = e.nextElement();
+ if ( o instanceof FileSet ) {
+ loadTestFiles( ( FileSet ) o, testcases );
+ }
+ else {
+ testcases.addElement( o );
+ }
+ }
+
+ // actually execute the testcases
+ for ( Enumeration e = testcases.elements(); e.hasMoreElements(); ) {
+ Task task = ( Task ) e.nextElement();
+ task.perform();
+ }
+ }
+
+ // run the tearDown target
+ if ( tearDown != null )
+ tearDown.execute();
+
+ // tabulate the results. The individual testcases contain their
+ // own stats, so it is just a matter of reading them and accumulating
+ // the totals.
+ for ( Enumeration e = testcases.elements(); e.hasMoreElements(); ) {
+ Task task = ( Task ) e.nextElement();
+ if ( task instanceof TestStatisticAccumulator ) {
+ TestStatisticAccumulator acc = ( TestStatisticAccumulator ) task;
+ totalTestCount += acc.getTestCaseCount();
+ totalRanCount += acc.getRanCount();
+ totalPassedCount += acc.getPassedCount();
+ totalFailedCount += acc.getFailedCount();
+ totalWarningCount += acc.getWarningCount();
+ for (Enumeration fen = acc.getFailures(); fen.hasMoreElements(); ) {
+ failures.add(fen.nextElement());
+ }
+ }
+ }
+ if ( showSummary ) {
+ log( getSummary() );
+ }
+
+ if (failonerror && totalFailedCount > 0)
+ throw new BuildException("+++++ FAILED +++++\n" + getSummary());
+ }
+ catch ( Exception ex ) {
+ ex.printStackTrace();
+ throw new BuildException( ex.getMessage() );
+ }
+ }
+
+ public String getSummary() {
+ String title = (name == null ? "Suite" : name ) + " Totals";
+ StringBuffer msg = new StringBuffer();
+ String ls = System.getProperty( "line.separator" );
+
+ // log the failures
+ if (failures.size() > 0) {
+ String error_title = "Errors";
+ StringBuffer error_msg = new StringBuffer();
+ Enumeration en = failures.elements();
+ while (en.hasMoreElements()) {
+ error_msg.append((String) en.nextElement()).append(ls);
+ }
+ int box_width = MessageBox.getMaxWidth();
+ MessageBox.setMaxWidth(box_width - 8);
+ msg.append(MessageBox.box(error_title, error_msg));
+ MessageBox.setMaxWidth(box_width);
+ msg.append(ls);
+ }
+
+ msg.append( "Total Ran: " ).append( totalRanCount ).append( " out of " ).append( totalTestCount ).append( " tests." ).append( ls );
+ msg.append( "Total Passed: " ).append( totalPassedCount ).append( ls );
+ msg.append( "Total Warnings: " ).append( totalWarningCount ).append( ls );
+ msg.append( "Total Failed: " ).append( totalFailedCount ).append( ls );
+ return MessageBox.box(title, msg);
+ }
+
+ /**
+ * Create TestCases from the files specified in a FileSet.
+ * @param fs the fileset to use for testcases
+ * @param destination where to store the newly created TestCases.
+ */
+ protected void loadTestFiles( FileSet fs, Vector destination ) {
+ File d = fs.getDir( getProject() );
+ DirectoryScanner ds = fs.getDirectoryScanner( getProject() );
+ String[] files = ds.getIncludedFiles();
+ String[] dirs = ds.getIncludedDirectories();
+ if ( files.length > 0 ) {
+ for ( int j = 0; j < files.length; j++ ) {
+ File f = new File( d, files[ j ] );
+ TestCase tc = createTestCase( f );
+ destination.addElement( tc );
+ }
+ }
+
+ if ( dirs.length > 0 ) {
+ for ( int j = dirs.length - 1; j >= 0; j-- ) {
+ File dir = new File( d, dirs[ j ] );
+ String[] dirFiles = dir.list();
+ if ( dirFiles != null && dirFiles.length > 0 ) {
+ for ( int i = 0; i < dirFiles.length; i++ ) {
+ File f = new File( dir, dirFiles[ i ] );
+ TestCase tc = createTestCase( f );
+ destination.addElement( tc );
+ }
+ }
+ }
+ }
+ }
+
+ private TestCase createTestCase( File f ) {
+ TestCase tc = new TestCase();
+ tc.init();
+ tc.setFile( f );
+ tc.setProject( getProject() );
+ return tc;
+ }
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/SuiteOriginal.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/SuiteOriginal.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/SuiteOriginal.java (revision 15058)
@@ -0,0 +1,157 @@
+package ise.antelope.tasks;
+
+import java.util.*;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+
+/**
+ * Modeled after the TestSuite provided by jUnit, this class is an Ant task that
+ * looks through the build file that contains this task, calls a 'setUp' target
+ * (if it exists), then all targets whose names start with 'test', and last calls
+ * a target named 'tearDown' (if it exists). Both 'setUp' and 'tearDown' are
+ * optional targets in the build file.
+ * Ant stores targets in a hashtable, so there is no guaranteed order in which
+ * the 'test*' classes will be called. If order is important, use the 'depends'
+ * attribue of a target to enforce order, and do not name dependent targets with
+ * a name starting with 'test'.
+ * Test targets may also be imported with the import task. Imported files should
+ * not have a "suite" task in the implicit target as such a task would rerun
+ * all test targets in all files.
+ *
+ * @author Dale Anson
+ */
+public class SuiteOriginal extends Task {
+
+ private Target setUp = null;
+ private Target tearDown = null;
+ private Vector testTargets = new Vector();
+ private Vector failures = new Vector();
+ private boolean showSummary = true;
+ private boolean showOutput = true;
+
+ private int tests_passed = 0;
+ private int tests_failed = 0;
+
+ public int getTestCaseCount() {
+ return testTargets.size();
+ }
+
+ public int getRanCount() {
+ return tests_passed + tests_failed;
+ }
+
+ public int getFailedCount() {
+ return tests_failed;
+ }
+
+ public int getPassedCount() {
+ return tests_passed;
+ }
+
+ public Enumeration getFailures() {
+ return failures.elements();
+ }
+
+ public void setShowoutput( boolean b ) {
+ showOutput = b;
+ }
+
+ public void setShowsummary(boolean b ) {
+ showSummary = b;
+ }
+
+ /** Run tests. */
+ public void execute() {
+
+ // get the setUp, tearDown, and test targets
+ Hashtable targets = getProject().getTargets();
+ Enumeration en = targets.keys();
+ while ( en.hasMoreElements() ) {
+ String target = ( String ) en.nextElement();
+ if ( target.equals( "setUp" ) )
+ setUp = ( Target ) targets.get( target );
+ else if ( target.equals( "tearDown" ) )
+ tearDown = ( Target ) targets.get( target );
+ else if ( target.startsWith( "test" ) )
+ testTargets.addElement( targets.get( target ) );
+ // also check for imported targets. Imported targets are named like
+ // projectname.targetname, so check for whatever follows the last dot.
+ // This is somewhat naive, as there is no restriction using dots in
+ // target names, so a target named "build.testimonials" would be treated
+ // as a test target.
+ else if ( target.lastIndexOf( "." ) > 0 && target.substring( target.lastIndexOf( "." ) + 1 ).startsWith( "test" ) ) {
+ testTargets.addElement( targets.get( target ) );
+ }
+ }
+
+ // run the setUp target
+ if ( setUp != null )
+ setUp.execute();
+ en = testTargets.elements();
+
+ // run the test targets
+ StringBuffer messages = new StringBuffer();
+ while ( en.hasMoreElements() ) {
+ Target target = ( Target ) en.nextElement();
+ try {
+ executeDependencies( target );
+ target.performTasks();
+ if (showOutput)
+ log( target.getName() + " passed." );
+ ++tests_passed;
+ }
+ catch ( Exception e ) {
+ ++tests_failed;
+ if (showOutput)
+ log( target.getName() + " failed: " + e.getMessage() );
+ failures.addElement( target.getName() + " failed: " + e.getMessage() );
+ }
+ }
+
+ // run the tearDown target
+ if ( tearDown != null )
+ tearDown.execute();
+
+ // print any error messages
+ if ( showSummary ) {
+ // log the failures
+ if ( failures.size() > 0 ) {
+ log( "" );
+ log( "---- Errors ---------------------------------" );
+ en = failures.elements();
+ while(en.hasMoreElements()) {
+ String msg = (String)en.nextElement();
+ log(msg);
+ }
+ }
+
+ // log the test count info
+ log( "" );
+ log( "---- Results --------------------------------" );
+ log( "Ran " + getRanCount() + " out of " + getTestCaseCount() + " tests." );
+ log( "Passed: " + getPassedCount() );
+ log( "Failed: " + getFailedCount() );
+ }
+ }
+
+ /**
+ * Execute a target's dependencies followed by the target itself.
+ * @param target the target to execute
+ */
+ private void executeDependencies( Target target ) {
+ if ( target == null )
+ return ;
+ Enumeration en = target.getDependencies();
+ if ( en == null )
+ return ;
+ while ( en.hasMoreElements() ) {
+ String name = ( String ) en.nextElement();
+ Target t = ( Target ) getProject().getTargets().get( name );
+ executeDependencies( t );
+ t.performTasks();
+ }
+ }
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/SwitchTask.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/SwitchTask.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/SwitchTask.java (revision 15058)
@@ -0,0 +1,139 @@
+/*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Ant", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+*
+ *
+ * Ant stores targets in a hashtable, so there is no guaranteed order in which
+ * the 'test*' classes will be called. If order is important, use the 'depends'
+ * attribue of a target to enforce order, and do not name dependent targets with
+ * a name starting with 'test'.
+ *
+ * Test targets may also be imported with the import task. Imported files should
+ * not have a "suite" task in the implicit target as such a task would rerun all
+ * test targets in all files.
+ *
+ * @author Dale Anson
+ * @version $Revision: 1.3 $
+ */
+public class TestCase extends Task implements TestStatisticAccumulator {
+
+ private boolean enabled = true;
+ private boolean assertEnabled = true;
+ private Target setUp = null;
+ private Target tearDown = null;
+ private Vector testTargets = new Vector();
+ private Vector failures = new Vector();
+ private boolean failOnError = false;
+ private boolean showSummary = true;
+ private boolean showOutput = true;
+ private File testFile = null;
+ private String test_name = "";
+
+ private int tests_passed = 0;
+ private int tests_failed = 0;
+ private int tests_warning = 0;
+
+ /** task initilization */
+ public void init() {
+ super.init();
+ setTaskName("testcase");
+ }
+
+ /**
+ * @return the count of test targets.
+ */
+ public int getTestCaseCount() {
+ return testTargets.size();
+ }
+
+ /**
+ * @return the number of tests targets actually executed.
+ */
+ public int getRanCount() {
+ return tests_passed + tests_warning + tests_failed;
+ }
+
+ /**
+ * @return the number of tests that failed.
+ */
+ public int getFailedCount() {
+ return tests_failed;
+ }
+
+ public int getWarningCount() {
+ return tests_warning;
+ }
+
+ /**
+ * @return the number of tests that passed.
+ */
+ public int getPassedCount() {
+ return tests_passed;
+ }
+
+ /**
+ * @return an Enumeration of the failures. Individual elements are Strings
+ * containing the name of the failed target and the reason why it
+ * failed.
+ */
+ public Enumeration getFailures() {
+ return failures.elements();
+ }
+
+ /**
+ * @param b if true, show the output of the tests as they run. Optional,
+ * default is true, do show output.
+ */
+ public void setShowoutput(boolean b) {
+ showOutput = b;
+ }
+
+ /**
+ * @param b if true, show the summary output (number of tests, passed,
+ * failed) after the completion of all tests. Optional, default is
+ * true, do show summary.
+ */
+ public void setShowsummary(boolean b) {
+ showSummary = b;
+ }
+
+ /**
+ * @param f the file containing the tests to execute. Required. The file
+ * itself is a standard Ant build file, but will be treated differently
+ * than if Ant itself ran it. If there is a target named "setUp", that
+ * target will be executed first, then all targets with names starting
+ * with "test" (not in any particular order), then if there is a target
+ * named "tearDown", that target will be executed last. All other
+ * targets are ignored.
+ */
+ public void setFile(File f) {
+ testFile = f;
+ }
+
+ /**
+ * Should Asserts be enabled? Many (most?) tests will use the Assert task,
+ * which requires a property to be set to actually enable the asserts. By
+ * default, Asserts are enabled for testcases.
+ *
+ * @param b if false, do not enable asserts. Note that this sets an Ant
+ * property, and due to property immutability, this attribute may have
+ * no effect if it has been set already. Generally, asserts are enabled
+ * or disabled for an entire build.
+ */
+ public void setAssertsenabled(boolean b) {
+ assertEnabled = b;
+ }
+
+ /**
+ * Should the build fail if the test fails? By default, a failed test does
+ * not cause the build to fail, so all tests may have the opportunity to
+ * run.
+ *
+ * @param b set to true to cause the build to fail if the test fails
+ */
+ public void setFailonerror(boolean b) {
+ failOnError = b;
+ }
+
+ /**
+ * @return the name of the test as set by
+ * This used to be a nice little task that took advantage of what is probably
+ * a flaw in the Ant Project API -- setting a "user" property programatically
+ * causes the project to overwrite a previously set property. Now this task
+ * has become more violent and employs a technique known as "object rape" to
+ * directly access the Project's private property hashtable.
+ * Developed for use with Antelope, migrated to ant-contrib Oct 2003.
+ *
+ * @author Dale Anson, danson@germane-software.com
+ * @since Ant 1.5
+ * @version $Revision: 1.3 $
+ */
+public class Variable extends Task {
+
+ // attribute storage
+ private String value = "";
+ private String name = null;
+ private File file = null;
+ private boolean remove = false;
+
+
+ /**
+ * Set the name of the property. Required unless 'file' is used.
+ *
+ * @param name the name of the property.
+ */
+ public void setName( String name ) {
+ this.name = name;
+ }
+
+
+ /**
+ * Set the value of the property. Optional, defaults to "".
+ *
+ * @param value the value of the property.
+ */
+ public void setValue( String value ) {
+ this.value = value;
+ }
+
+
+ /**
+ * Set the name of a file to read properties from. Optional.
+ *
+ * @param file the file to read properties from.
+ */
+ public void setFile( File file ) {
+ this.file = file;
+ }
+
+ /**
+ * Determines whether the property should be removed from the project.
+ * Default is false. Once removed, conditions that check for property
+ * existence will find this property does not exist.
+ *
+ * @param b set to true to remove the property from the project.
+ */
+ public void setUnset( boolean b ) {
+ remove = b;
+ }
+
+
+ /**
+ * Execute this task.
+ *
+ * @exception BuildException Description of the Exception
+ */
+ public void execute() throws BuildException {
+ if ( remove ) {
+ if ( name == null || name.equals( "" ) ) {
+ throw new BuildException( "The 'name' attribute is required with 'unset'." );
+ }
+ removeProperty( name );
+ return ;
+ }
+ if ( file == null ) {
+ // check for the required name attribute
+ if ( name == null || name.equals( "" ) ) {
+ throw new BuildException( "The 'name' attribute is required." );
+ }
+
+ // check for the required value attribute
+ if ( value == null ) {
+ value = "";
+ }
+
+ // adjust the property value if necessary -- is this necessary?
+ // Doesn't Ant do this automatically?
+ value = getProject().replaceProperties( value );
+
+ // set the property
+ forceProperty( name, value );
+ }
+ else {
+ if ( !file.exists() ) {
+ throw new BuildException( file.getAbsolutePath() + " does not exists." );
+ }
+ loadFile( file );
+ }
+ }
+
+ /**
+ * Remove a property from the project's property table and the userProperty table.
+ * Note that Ant 1.6 uses a helper for this.
+ */
+ private void removeProperty( String name ) {
+ Hashtable properties = null;
+ // Ant 1.5 stores properties in Project
+ try {
+ properties = ( Hashtable ) getValue( getProject(), "properties" );
+ if ( properties != null ) {
+ properties.remove( name );
+ }
+ }
+ catch ( Exception e ) {
+ // ignore, could be Ant 1.6
+ }
+ try {
+ properties = ( Hashtable ) getValue( getProject(), "userProperties" );
+ if ( properties != null ) {
+ properties.remove( name );
+ }
+ }
+ catch ( Exception e ) {
+ // ignore, could be Ant 1.6
+ }
+
+ // Ant 1.6 uses a PropertyHelper, can check for it by checking for a
+ // reference to "ant.PropertyHelper"
+ try {
+ Object property_helper = getProject().getReference( "ant.PropertyHelper" );
+ if ( property_helper != null ) {
+ try {
+ properties = ( Hashtable ) getValue( property_helper, "properties" );
+ if ( properties != null ) {
+ properties.remove( name );
+ }
+ }
+ catch ( Exception e ) {
+ // ignore
+ }
+ try {
+ properties = ( Hashtable ) getValue( property_helper, "userProperties" );
+ if ( properties != null ) {
+ properties.remove( name );
+ }
+ }
+ catch ( Exception e ) {
+ // ignore
+ }
+ }
+ }
+ catch ( Exception e ) {
+ // ignore, could be Ant 1.5
+ }
+ }
+
+ private void forceProperty( String name, String value ) {
+ try {
+ Hashtable properties = ( Hashtable ) getValue( getProject(), "properties" );
+ if ( properties == null ) {
+ getProject().setUserProperty( name, value );
+ }
+ else {
+ properties.put( name, value );
+ }
+ }
+ catch ( Exception e ) {
+ getProject().setUserProperty( name, value );
+ }
+ }
+
+
+ /**
+ * Object rape: fondle the private parts of an object without it's
+ * permission.
+ *
+ * @param thisClass The class to rape.
+ * @param fieldName The field to fondle
+ * @return The field value
+ * @exception NoSuchFieldException Darn, nothing to fondle.
+ */
+ private Field getField( Class thisClass, String fieldName ) throws NoSuchFieldException {
+ if ( thisClass == null ) {
+ throw new NoSuchFieldException( "Invalid field : " + fieldName );
+ }
+ try {
+ return thisClass.getDeclaredField( fieldName );
+ }
+ catch ( NoSuchFieldException e ) {
+ return getField( thisClass.getSuperclass(), fieldName );
+ }
+ }
+
+
+ /**
+ * Object rape: fondle the private parts of an object without it's
+ * permission.
+ *
+ * @param instance the object instance
+ * @param fieldName the name of the field
+ * @return an object representing the value of the
+ * field
+ * @exception IllegalAccessException foiled by the security manager
+ * @exception NoSuchFieldException Darn, nothing to fondle
+ */
+ private Object getValue( Object instance, String fieldName )
+ throws IllegalAccessException, NoSuchFieldException {
+ Field field = getField( instance.getClass(), fieldName );
+ field.setAccessible( true );
+ return field.get( instance );
+ }
+
+
+ /**
+ * load variables from a file
+ *
+ * @param file file to load
+ * @exception BuildException Description of the Exception
+ */
+ private void loadFile( File file ) throws BuildException {
+ Properties props = new Properties();
+ try {
+ if ( file.exists() ) {
+ FileInputStream fis = new FileInputStream( file );
+ try {
+ props.load( fis );
+ }
+ finally {
+ if ( fis != null ) {
+ fis.close();
+ }
+ }
+ addProperties( props );
+ }
+ else {
+ log( "Unable to find property file: " + file.getAbsolutePath(),
+ Project.MSG_VERBOSE );
+ }
+ }
+ catch ( IOException ex ) {
+ throw new BuildException( ex, location );
+ }
+ }
+
+
+ /**
+ * iterate through a set of properties, resolve them, then assign them
+ *
+ * @param props The feature to be added to the Properties attribute
+ */
+ protected void addProperties( Properties props ) {
+ resolveAllProperties( props );
+ Enumeration e = props.keys();
+ while ( e.hasMoreElements() ) {
+ String name = ( String ) e.nextElement();
+ String value = props.getProperty( name );
+ forceProperty( name, value );
+ }
+ }
+
+
+ /**
+ * resolve properties inside a properties hashtable
+ *
+ * @param props properties object to resolve
+ * @exception BuildException Description of the Exception
+ */
+ private void resolveAllProperties( Properties props ) throws BuildException {
+ for ( Enumeration e = props.keys(); e.hasMoreElements(); ) {
+ String name = ( String ) e.nextElement();
+ String value = props.getProperty( name );
+
+ boolean resolved = false;
+ while ( !resolved ) {
+ Vector fragments = new Vector();
+ Vector propertyRefs = new Vector();
+ ProjectHelper.parsePropertyString( value, fragments,
+ propertyRefs );
+
+ resolved = true;
+ if ( propertyRefs.size() != 0 ) {
+ StringBuffer sb = new StringBuffer();
+ Enumeration i = fragments.elements();
+ Enumeration j = propertyRefs.elements();
+ while ( i.hasMoreElements() ) {
+ String fragment = ( String ) i.nextElement();
+ if ( fragment == null ) {
+ String propertyName = ( String ) j.nextElement();
+ if ( propertyName.equals( name ) ) {
+ throw new BuildException( "Property " + name
+ + " was circularly "
+ + "defined." );
+ }
+ fragment = getProject().getProperty( propertyName );
+ if ( fragment == null ) {
+ if ( props.containsKey( propertyName ) ) {
+ fragment = props.getProperty( propertyName );
+ resolved = false;
+ }
+ else {
+ fragment = "${" + propertyName + "}";
+ }
+ }
+ }
+ sb.append( fragment );
+ }
+ value = sb.toString();
+ props.put( name, value );
+ }
+ }
+ }
+ }
+
+}
+
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/XmlPropertyTask.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/XmlPropertyTask.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/XmlPropertyTask.java (revision 15058)
@@ -0,0 +1,728 @@
+/*
+* Copyright 2002-2004 The Apache Software Foundation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+package ise.antelope.tasks;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Hashtable;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.XMLCatalog;
+import org.apache.tools.ant.util.FileUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import org.xml.sax.EntityResolver;
+
+/**
+ * danson: modified from original to allow setting xml as a string rather than
+ * a file.
+ *
+ * Loads property values from a valid XML file, generating the
+ * property names from the file's element and attribute names.
+ *
+ * Example: this generates the following properties: The collapseAttributes property of this task can be set
+ * to true (the default is false) which will instead result in the
+ * following properties (note the difference in names of properties
+ * corresponding to XML attributes): Optionally, to more closely mirror the abilities of the Property
+ * task, a selected set of attributes can be treated specially. To
+ * enable this behavior, the "semanticAttributes" property of this task
+ * must be set to true (it defaults to false). If this attribute is
+ * specified, the following attributes take on special meaning
+ * (setting this to true implicitly sets collapseAttributes to true as
+ * well): For example, with keepRoot = false, the following properties file: is equivalent to the following entries in a build file: This task requires the following attributes: This task supports the following attributes: If we are using semantic attributes, then first
+ * dependent properties are resolved (i.e., ${foo} is resolved
+ * based on the foo property value), and then an appropriate data
+ * type is used. In particular, location-based properties are
+ * resolved to absolute file names. Also for refid values, look
+ * up the referenced object from the project. Iterates over all conditions and returns false as soon as one
+ * evaluates to false. Iterates over all conditions and returns true as soon as one
+ * evaluates to true.
+ * Change Log:
+ *
+ * I am placing this code in the Public Domain. Do with it as you will.
+ * This software comes with no guarantees or warranties but with
+ * plenty of well-wishing instead!
+ * Please visit http://iharder.net/base64
+ * periodically to check for updates or to contribute improvements.
+ *
+ * Valid options:
+ * Example:
+ * Example:
+ * Valid options:
+ * Example:
+ * Example:
+ * Valid options:
+ * Example:
+ * Example:
+ * Valid options:
+ * Example:
+ * Valid options:
+ * Example: Copyright 2003, Dale Anson, all rights reserved
+ * @author Dale Anson, danson@germane-software.com
+ */
+public class Math {
+
+ private boolean strict = false;
+
+ public static Class BIGDECIMAL_TYPE;
+ public static Class BIGINT_TYPE;
+ static {
+ try {
+ BIGDECIMAL_TYPE = Class.forName( "java.math.BigDecimal" );
+ }
+ catch ( ClassNotFoundException e ) {
+ BIGDECIMAL_TYPE = null;
+ }
+ try {
+ BIGINT_TYPE = Class.forName( "java.math.BigInteger" );
+ }
+ catch ( Exception e ) {
+ BIGINT_TYPE = null;
+ }
+ }
+
+ public Math() {}
+
+ public Math( boolean strict ) {
+ this.strict = strict;
+ }
+
+ public void setStrict( boolean strict ) {
+ this.strict = strict;
+ }
+
+ public boolean isStrict() {
+ return strict;
+ }
+
+ public static BigDecimal add( BigDecimal a, BigDecimal b ) {
+ return a.add( b );
+ }
+
+ public static BigInteger add( BigInteger a, BigInteger b ) {
+ return a.add( b );
+ }
+
+ public static BigInteger and( BigInteger a, BigInteger b ) {
+ return a.and( b );
+ }
+
+ public static int and( int a, int b ) {
+ return a & b;
+ }
+
+ public static BigInteger or( BigInteger a, BigInteger b ) {
+ return a.or( b );
+ }
+
+ public static int or( int a, int b ) {
+ return a | b;
+ }
+
+ public static BigInteger not( BigInteger a ) {
+ return a.not();
+ }
+
+ public static int not( int a ) {
+ return ~a;
+ }
+
+ public static BigInteger xor( BigInteger a, BigInteger b ) {
+ return a.xor( b );
+ }
+
+ public static int xor( int a, int b ) {
+ return a ^ b;
+ }
+
+ public static double add( double a, double b ) {
+ return a + b;
+ }
+ public static float add( float a, float b ) {
+ return a + b;
+ }
+ public static long add( long a, long b ) {
+ return a + b;
+ }
+ public static int add( int a, int b ) {
+ return a + b;
+ }
+ public static BigInteger add( BigInteger[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ BigInteger b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b = b.add( a[ i ] );
+ return b;
+ }
+ public static double add( double[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ double b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b += a[ i ];
+ return b;
+ }
+ public static float add( float[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ float b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b += a[ i ];
+ return b;
+ }
+ public static long add( long[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ long b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b += a[ i ];
+ return b;
+ }
+ public static int add( int[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ int b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b += a[ i ];
+ return b;
+ }
+
+ public static BigDecimal subtract( BigDecimal a, BigDecimal b ) {
+ return a.subtract( b );
+ }
+
+ public static BigInteger subtract( BigInteger a, BigInteger b ) {
+ return a.subtract( b );
+ }
+
+ public static double subtract( double a, double b ) {
+ return a - b;
+ }
+ public static float subtract( float a, float b ) {
+ return a - b;
+ }
+ public static long subtract( long a, long b ) {
+ return a - b;
+ }
+ public static int subtract( int a, int b ) {
+ return a - b;
+ }
+ public static BigDecimal subtract( BigDecimal[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ BigDecimal b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b = b.subtract( a[ i ] );
+ return b;
+ }
+ public static BigInteger subtract( BigInteger[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ BigInteger b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b = b.subtract( a[ i ] );
+ return b;
+ }
+ public static double subtract( double[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ double b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b -= a[ i ];
+ return b;
+ }
+ public static float subtract( float[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ float b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b -= a[ i ];
+ return b;
+ }
+ public static long subtract( long[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ long b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b -= a[ i ];
+ return b;
+ }
+ public static int subtract( int[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ int b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b -= a[ i ];
+ return b;
+ }
+
+ public static BigDecimal multiply( BigDecimal a, BigDecimal b ) {
+ return a.multiply( b );
+ }
+
+ public static BigInteger multiply( BigInteger a, BigInteger b ) {
+ return a.multiply( b );
+ }
+
+ public static double multiply( double a, double b ) {
+ return a * b;
+ }
+ public static float multiply( float a, float b ) {
+ return a * b;
+ }
+ public static long multiply( long a, long b ) {
+ return a * b;
+ }
+ public static int multiply( int a, int b ) {
+ return a * b;
+ }
+ public static BigDecimal multiply( BigDecimal[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ BigDecimal b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b = b.multiply( a[ i ] );
+ return b;
+ }
+ public static BigInteger multiply( BigInteger[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ BigInteger b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b = b.multiply( a[ i ] );
+ return b;
+ }
+ public static double multiply( double[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ double b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b *= a[ i ];
+ return b;
+ }
+ public static float multiply( float[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ float b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b *= a[ i ];
+ return b;
+ }
+ public static long multiply( long[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ long b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b *= a[ i ];
+ return b;
+ }
+ public static int multiply( int[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ int b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b *= a[ i ];
+ return b;
+ }
+
+ public static BigDecimal divide( BigDecimal a, BigDecimal b ) {
+ try {
+ return a.divide( b, BigDecimal.ROUND_HALF_EVEN );
+ }
+ catch ( Throwable e ) {
+ return a.divide( b, BigDecimal.ROUND_HALF_EVEN );
+ }
+ }
+
+ public static BigInteger divide( BigInteger a, BigInteger b ) {
+ return a.divide( b );
+ }
+
+ public static double divide( double a, double b ) {
+ if (b == 0)
+ throw new ArithmeticException("/ by zero");
+ return a / b;
+ }
+ public static float divide( float a, float b ) {
+ if (b == 0)
+ throw new ArithmeticException("/ by zero");
+ return a / b;
+ }
+ public static long divide( long a, long b ) {
+ if (b == 0)
+ throw new ArithmeticException("/ by zero");
+ return a / b;
+ }
+ public static int divide( int a, int b ) {
+ if (b == 0)
+ throw new ArithmeticException("/ by zero");
+ return a / b;
+ }
+ public static BigDecimal divide( BigDecimal[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ BigDecimal b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b = b.divide( a[ i ], BigDecimal.ROUND_HALF_EVEN );
+ return b;
+ }
+ public static BigInteger divide( BigInteger[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ BigInteger b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b = b.divide( a[ i ] );
+ return b;
+ }
+ public static double divide( double[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ double b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ ) {
+ if (a[i] == 0)
+ throw new ArithmeticException("/ by zero");
+ b /= a[ i ];
+ }
+ return b;
+ }
+ public static float divide( float[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ float b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ ) {
+ if (a[i] == 0)
+ throw new ArithmeticException("/ by zero");
+ b /= a[ i ];
+ }
+ return b;
+ }
+ public static long divide( long[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ long b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ ) {
+ if (a[i] == 0)
+ throw new ArithmeticException("/ by zero");
+ b /= a[ i ];
+ }
+ return b;
+ }
+ public static int divide( int[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ int b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ ) {
+ if (a[i] == 0)
+ throw new ArithmeticException("/ by zero");
+ b /= a[ i ];
+ }
+ return b;
+ }
+
+ public static BigInteger mod( BigInteger a, BigInteger b ) {
+ return a.mod( b );
+ }
+
+ public static double mod( double a, double b ) {
+ return a % b;
+ }
+ public static float mod( float a, float b ) {
+ return a % b;
+ }
+ public static long mod( long a, long b ) {
+ return a % b;
+ }
+ public static int mod( int a, int b ) {
+ return a % b;
+ }
+ public static BigInteger mod( BigInteger[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ BigInteger b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b = b.mod( a[ i ] );
+ return b;
+ }
+ public static double mod( double[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ double b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b %= a[ i ];
+ return b;
+ }
+ public static float mod( float[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ float b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b %= a[ i ];
+ return b;
+ }
+ public static long mod( long[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ long b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b %= a[ i ];
+ return b;
+ }
+ public static int mod( int[] a ) {
+ if ( a.length == 0 )
+ throw new IllegalArgumentException();
+ if ( a.length == 1 )
+ return a[ 0 ];
+ int b = a[ 0 ];
+ for ( int i = 1; i < a.length; i++ )
+ b %= a[ i ];
+ return b;
+ }
+
+ // comparisons
+ public static boolean greaterThan(int x, int y) {
+ return x > y;
+ }
+ public static boolean greaterThan(long x, long y) {
+ return x > y;
+ }
+ public static boolean greaterThan(double x, double y) {
+ return x > y;
+ }
+ public static boolean greaterThan(BigInteger x, BigInteger y) {
+ return x.compareTo(y) > 0;
+ }
+ public static boolean greaterThan(BigDecimal x, BigDecimal y) {
+ return x.compareTo(y) > 0;
+ }
+ public static boolean lessThan(int x, int y) {
+ return x < y;
+ }
+ public static boolean lessThan(long x, long y) {
+ return x < y;
+ }
+ public static boolean lessThan(double x, double y) {
+ return x < y;
+ }
+ public static boolean lessThan(BigInteger x, BigInteger y) {
+ return x.compareTo(y) < 0;
+ }
+ public static boolean lessThan(BigDecimal x, BigDecimal y) {
+ return x.compareTo(y) < 0;
+ }
+ public static boolean equal(int x, int y) {
+ return x == y;
+ }
+ public static boolean equal(long x, long y) {
+ return x == y;
+ }
+ public static boolean equal(double x, double y) {
+ return x == y;
+ }
+ public static boolean equal(BigInteger x, BigInteger y) {
+ return x.compareTo(y) == 0;
+ }
+ public static boolean equal(BigDecimal x, BigDecimal y) {
+ return x.compareTo(y) == 0;
+ }
+ public static boolean notEqual(int x, int y) {
+ return x != y;
+ }
+ public static boolean notEqual(long x, long y) {
+ return x != y;
+ }
+ public static boolean notEqual(double x, double y) {
+ return x != y;
+ }
+ public static boolean notEqual(BigInteger x, BigInteger y) {
+ return x.compareTo(y) != 0;
+ }
+ public static boolean notEqual(BigDecimal x, BigDecimal y) {
+ return x.compareTo(y) != 0;
+ }
+
+ public static BigInteger factorial( BigInteger x ) {
+ if ( x.compareTo( new BigInteger( "0" ) ) < 0 )
+ throw new IllegalArgumentException( "number must be greater than 0" );
+ BigInteger y = x;
+ for ( x = x.subtract( new BigInteger( "1" ) ); x.toString().compareTo( "1" ) > 0; x = x.subtract( new BigInteger( "1" ) ) ) {
+ y = y.multiply( x );
+ }
+ return y;
+ }
+
+ public static int factorial( double x ) {
+ return factorial( ( int ) x );
+ }
+
+ public static int factorial( float x ) {
+ return factorial( ( int ) x );
+ }
+
+ public static int factorial( int x ) {
+ if ( x < 0 )
+ throw new IllegalArgumentException( "number must be greater than 0" );
+ int y = x;
+ for ( x -= 1; x > 1; x-- )
+ y *= x;
+ return y;
+ }
+
+ public static BigDecimal min( BigDecimal a, BigDecimal b ) {
+ return a.min( b );
+ }
+
+ public static BigInteger min( BigInteger a, BigInteger b ) {
+ return a.min( b );
+ }
+
+ public static BigDecimal max( BigDecimal a, BigDecimal b ) {
+ return a.max( b );
+ }
+
+ public static BigInteger max( BigInteger a, BigInteger b ) {
+ return a.max( b );
+ }
+
+ /**
+ * y raised to the x power
+ */
+ public static BigInteger pow( BigInteger y, BigInteger x ) {
+ int exp = x.intValue();
+ if ( exp < 1 )
+ throw new IllegalArgumentException( "Exponent must be greater than 0" );
+ return y.pow( x.intValue() );
+ }
+
+ /**
+ * y raised to the x power
+ */
+ public static BigDecimal pow( BigDecimal y, BigDecimal x ) {
+ if ( x.compareTo( new BigDecimal( "1" ) ) <= 0 ) {
+ throw new ArithmeticException( "Powers of BigDecimals must be integers greater than 1" );
+ }
+ String exp = x.toString();
+ if ( exp.indexOf( "." ) > 0 )
+ exp = exp.substring( 0, exp.indexOf( "." ) );
+ BigInteger e = new BigInteger( exp );
+ BigDecimal z = new BigDecimal( y.toString() );
+ for ( ;e.compareTo( BigInteger.ONE ) > 0; e = e.subtract( BigInteger.ONE ) ) {
+ y = y.multiply( z );
+ }
+ return y;
+ }
+
+ /**
+ * Do a mathematical calculation. The allowed operations are all
+ * operations supported by java.lang.Math and this class. Assumes data
+ * type is "double".
+ * @param op the name of a mathematical operation to perform
+ * @param operands the operands for the operation, these strings must parse to numbers.
+ */
+ public Number calculate( String op, String[] operands ) {
+ return calculate( op, "double", operands );
+ }
+
+ /**
+ * Do a mathematical calculation. The allowed operations are all
+ * operations supported by java.lang.Math.
+ * @param op the name of a mathematical operation to perform
+ * @param type the data type of the operands
+ * @param operands the operands for the operation
+ * @return the result of the calculation. For boolean operations, returns
+ * 1 for true, 0 for false;
+ */
+ public Number calculate( String op, String type, String[] operands ) {
+ try {
+ if ( operands.length >= 2 && ( op.equals( "add" ) ||
+ op.equals( "subtract" ) ||
+ op.equals( "multiply" ) ||
+ op.equals( "divide" ) ||
+ op.equals( "mod" ) ) ) {
+ return calculateArray( op, type, operands );
+ }
+
+ if ( operands.length > 2 )
+ throw new IllegalArgumentException( "too many operands" );
+
+ Class c;
+ Method m;
+ if ( strict )
+ c = Class.forName( "java.lang.StrictMath" );
+ else
+ c = Class.forName( "java.lang.Math" );
+
+ // check if op is 'random'. Random is a special case in that it is
+ // the only method in Math that takes no parameters.
+ if ( op.equals( "random" ) ) {
+ m = c.getDeclaredMethod( op, new Class[] {} );
+ Object result = m.invoke( c, null );
+ return ( Number ) result;
+ }
+
+ // find candidate methods for the requested operation
+ Vector candidates = new Vector();
+ Method[] methods = c.getDeclaredMethods();
+ for ( int i = 0; i < methods.length; i++ ) {
+ String name = methods[ i ].getName();
+ if ( name.equals( op ) ) {
+ candidates.addElement( new Candidate( c, methods[ i ] ) );
+ }
+ }
+
+ // also look for candidate methods in this class
+ c = this.getClass();
+ methods = c.getDeclaredMethods();
+ for ( int i = 0; i < methods.length; i++ ) {
+ String name = methods[ i ].getName();
+ if ( name.equals( op ) ) {
+ candidates.addElement( new Candidate( c, methods[ i ] ) );
+ }
+ }
+
+ if ( candidates.size() == 0 )
+ throw new RuntimeException( "Unknown operation: " + op );
+
+ // get the desired data type for the operation, default is
+ // Double.TYPE if no other match is found
+ Class wantTypeClass = getDataType( type );
+
+ // get the parameter count for the candidate methods -- in Math,
+ // all like named methods have the same number of parameters, just
+ // the data types are different. (Fix for bug # 724812 -- the above
+ // statement is true of java.lang.Math, but not of this class.)
+ //int paramCount = ( ( Method ) candidates.elementAt( 0 ) ).getParameterTypes().length;
+ int paramCount = -1;
+ try {
+ for ( int i = 0; i <= candidates.size(); i++ ) {
+ Candidate candidate = ( Candidate ) candidates.elementAt( i );
+ Method method = candidate.getCandidateMethod();
+ paramCount = method.getParameterTypes().length;
+ if ( paramCount == operands.length )
+ break;
+ }
+ }
+ catch ( Exception e ) {
+ throw new RuntimeException( "Wrong number of arguments, have " +
+ operands.length + ", but can't find corresponding method." );
+ }
+
+ // make sure there are enough arguments to pass to the method
+ // see bug fix above, this is no longer necessary
+ //if ( operands.length != paramCount )
+ // throw new RuntimeException( "Wrong number of arguments, have " +
+ // operands.length + ", expected " + paramCount );
+
+ // determine the actual type class for the method to invoke.
+ // Some methods have only one implementation so determine the
+ // typeClass from the method itself, not the desired.
+ Class typeClass = null;
+ if ( candidates.size() == 1 ) {
+ Candidate candidate = ( Candidate ) candidates.elementAt( 0 );
+ c = candidate.getCandidateClass();
+ m = candidate.getCandidateMethod();
+ typeClass = m.getParameterTypes() [ 0 ];
+ }
+ else {
+ // check each candidate to find one with the desired type
+ Enumeration en = candidates.elements();
+ while ( en.hasMoreElements() ) {
+ Candidate candidate = ( Candidate ) en.nextElement();
+ c = candidate.getCandidateClass();
+ m = candidate.getCandidateMethod();
+ if ( m.getParameterTypes() [ 0 ].equals( wantTypeClass ) ) {
+ typeClass = wantTypeClass;
+ break;
+ }
+ }
+ if ( typeClass == null )
+ throw new RuntimeException( "Can't find a method with parameters of type " + type );
+ }
+
+ // get the method to invoke
+ Class[] paramTypes = new Class[ paramCount ];
+ for ( int i = 0; i < paramCount; i++ ) {
+ paramTypes[ i ] = typeClass;
+ }
+ m = c.getDeclaredMethod( op, paramTypes );
+ //System.out.println( "Math.calculate, invoking: " + m.toString() );
+
+ // load the parameters and invoke the method
+ Object[] params = getParams( typeClass, operands );
+
+ try {
+ //System.out.println( "Math.calculateArray, invoking: " + m.toString() );
+ Object result = m.invoke( c, params );
+ if (result instanceof Boolean) {
+ result = new Integer(((Boolean)result).booleanValue() ? 1 : 0);
+ }
+ return ( Number ) result;
+ }
+ catch ( InvocationTargetException ite ) {
+ Throwable t = ite.getCause();
+ if ( t != null && t instanceof ArithmeticException ) {
+ throw ( ArithmeticException ) t;
+ }
+ else {
+ throw ite;
+ }
+ }
+ }
+ catch ( Exception e ) {
+ if ( e instanceof RuntimeException )
+ throw ( RuntimeException ) e;
+ }
+ return null;
+ }
+
+ /**
+ * Performs a calculation on an array of numbers. The mathematical methods
+ * in this class will accept an array of numbers, so
+ * Copyright 2003, Dale Anson, all rights reserved
+ * @author Dale Anson, danson@germane-software.com
+ */
+public class Num {
+
+ // the value of this number
+ private String value = null;
+
+ private String datatype = null;
+
+ public Num() {
+ }
+
+ public Num( String value ) {
+ setValue( value );
+ }
+
+ /**
+ * Set the value for this number. This string must parse to the set
+ * datatype, for example, setting value to "7.992" and datatype to INT
+ * will cause a number format exception to be thrown. Supports two special
+ * numbers, "E" and "PI".
+ * @param value the value for this number
+ */
+ public void setValue( String value ) {
+ if ( value.equals( "E" ) )
+ value = String.valueOf( java.lang.Math.E );
+ else if ( value.equals( "PI" ) )
+ value = String.valueOf( java.lang.Math.PI );
+ this.value = value;
+ }
+
+ /**
+ * @return the value for this number as a Number. Cast as appropriate to
+ * Integer, Long, Float, or Double.
+ */
+ public Number getValue() {
+ try {
+ if ( datatype == null )
+ datatype = "double";
+ if ( datatype.equals( "int" ) )
+ return new Integer( value );
+ if ( datatype.equals( "long" ) )
+ return new Long( value );
+ if ( datatype.equals( "float" ) )
+ return new Float( value );
+ if ( datatype.equals( "double" ) )
+ return new Double( value );
+ if ( datatype.equals( "bigint" ) )
+ return new java.math.BigInteger( value );
+ if ( datatype.equals( "bigdecimal" ) )
+ return new java.math.BigDecimal( value );
+ throw new RuntimeException( "Invalid datatype." );
+ }
+ catch ( NumberFormatException nfe ) {
+ return new Double( value );
+ }
+ }
+
+ /**
+ * Sets the datatype of this number. Allowed values are
+ * "int", "long", "float", or "double".
+ */
+ public void setDatatype( String p ) {
+ datatype = p;
+ }
+
+ /**
+ * @return the datatype as one of the defined types.
+ */
+ public String getDatatype() {
+ if ( datatype == null )
+ datatype = "double";
+ return datatype;
+ }
+
+ public String toString() {
+ if (value == null)
+ return null;
+ return getValue().toString();
+ }
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/math/Op.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/math/Op.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/math/Op.java (revision 15058)
@@ -0,0 +1,154 @@
+package ise.antelope.tasks.util.math;
+
+import java.util.Vector;
+import java.util.Enumeration;
+
+/**
+ * Represents a mathematical operation.
+ * Copyright 2003, Dale Anson, all rights reserved
+ * @author Dale Anson, danson@germane-software.com
+ */
+public class Op {
+ // datatype for the result of this operation
+ private String datatype = null;
+
+ // storage for the numbers to execute the operation on
+ Vector nums = new Vector();
+
+ // storage for nested Ops
+ Vector ops = new Vector();
+
+ // storage for operation
+ String operation = null;
+
+ // should the StrictMath library be used?
+ private boolean _strict = false;
+
+ public Op() {
+
+ }
+
+ public Op(String op) {
+ setOp(op);
+ }
+
+ public Op(String op, String type) {
+ setOp(op);
+ setDatatype(type);
+ }
+
+ /**
+ * Set the operation.
+ */
+ public void setOp( String op ) {
+ if (op.equals("+"))
+ operation = "add";
+ else if (op.equals("-"))
+ operation = "subtract";
+ else if (op.equals("*") || op.equals("x"))
+ operation = "multiply";
+ else if (op.equals("/") || op.equals( "÷" ) )
+ operation = "divide";
+ else if (op.equals("%") || op.equals("\\"))
+ operation = "mod";
+ else
+ operation = op;
+ }
+
+ /**
+ * Add a number to this operation. An operation can hold any number of
+ * numbers to support formulas like 5 + 4 + 3 + 2 + 1.
+ * @param num a number to use in this operation
+ */
+ public void addConfiguredNum( Num num ) {
+ nums.addElement( num );
+ //System.out.println("Op.addNum " + num);
+
+ }
+
+ /**
+ * Sets the datatype of this calculation. Allowed values are
+ * "int", "long", "float", or "double".
+ */
+ public void setDatatype( String p ) {
+ if ( p.equals( "int" ) ||
+ p.equals( "long" ) ||
+ p.equals( "float" ) ||
+ p.equals( "double" ) ||
+ p.equals( "bigint") ||
+ p.equals( "bigdecimal"))
+ datatype = p;
+ else
+ throw new IllegalArgumentException( "Invalid datatype: " + p +
+ ". Must be one of int, long, float, double, bigint, or bigdouble." );
+ }
+
+ /**
+ * Add a nested operation.
+ * @param op the operation to add.
+ */
+ public void addConfiguredOp( Op op ) {
+ if ( datatype != null )
+ op.setDatatype( datatype );
+ //ops.addElement( op );
+ //System.out.println("Op.addConfiguredOp");
+ addConfiguredNum(op.calculate());
+ }
+
+ /**
+ * Use the StrictMath library.
+ */
+ public void setStrict( boolean b ) {
+ _strict = b;
+ }
+
+ /**
+ * Perform this operation.
+ * @return the value resulting from the calculation as a Num.
+ */
+ public Num calculate() {
+ if ( operation == null )
+ throw new RuntimeException( "Operation not specified." );
+
+ // calculate nested Ops
+ /*
+ Enumeration en = ops.elements();
+ while ( en.hasMoreElements() ) {
+ Op op = ( Op ) en.nextElement();
+ if ( datatype != null )
+ op.setDatatype( datatype );
+ nums.addElement( op.calculate() );
+ }
+ */
+
+ // make an array of operands
+ //System.out.println("operation is " + operation + " on these numbers:");
+ String[] operands = new String[ nums.size() ];
+ Enumeration en = nums.elements();
+ int i = 0;
+ while ( en.hasMoreElements() ) {
+ Num num = (Num)en.nextElement();
+ if (datatype != null)
+ num.setDatatype(datatype);
+ //System.out.println(num.toString());
+ operands[ i++ ] = num.toString();
+ }
+
+ Math math = new Math(_strict);
+
+ Number number = null;
+ try {
+ number = math.calculate( operation, datatype, operands );
+ }
+ catch(ArithmeticException e) {
+ throw e;
+ }
+ if (number == null)
+ throw new ArithmeticException("math error");
+ Num num = new Num();
+ num.setValue(number.toString());
+ num.setDatatype(datatype);
+ return num;
+
+ }
+}
Index: /release-kits/shared/ant-tasks/tasks/orans/RegexSearchReplace.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/orans/RegexSearchReplace.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/orans/RegexSearchReplace.java (revision 15058)
@@ -0,0 +1,116 @@
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import java.util.*;
+import java.io.*;
+import java.util.regex.*;
+
+
+public class RegexSearchReplace extends Task {
+ private File file = null;
+ private String pattern = null;
+ private String replacement = null;
+
+
+ /**
+ * for testing
+ */
+ public static void main( String[] args ) {
+ RegexSearchReplace rsr = new RegexSearchReplace();
+ rsr.setFile(new File (args[0]));
+ rsr.setPattern(args[1]);
+ rsr.setReplacement(args[2]);
+
+ rsr.execute();
+
+ }
+
+ public void execute() {
+
+ if ( file == null ) {
+ throw new BuildException( "Error - No file specified !!" );
+ }
+
+ if ( pattern == null ) {
+ throw new BuildException( "Error - No pattern specified !!" );
+ }
+
+ if (replacement == null) {
+ replacement = "";
+ }
+
+
+ //create the output stream
+ BufferedWriter out = null;
+ File temp = null;
+ try {
+ // Create temp file.
+ temp = File.createTempFile("rsr", ".tmp");
+
+ // Delete temp file when program exits.
+ temp.deleteOnExit();
+
+ // Write to temp file
+ out = new BufferedWriter(new FileWriter(temp));
+
+ } catch (IOException e) {}
+
+
+ //create the input stream
+ BufferedReader in = null;
+ try {
+ in = new BufferedReader(new FileReader( file ));
+ } catch ( Exception e ) {}
+
+ //pass the file through, searching and replacing
+ String line;
+ try {
+ while ( (line = in.readLine()) != null ) {
+ line = line.replaceAll( pattern, replacement);
+ out.write(line);
+ out.newLine();
+ }
+ //close them both up
+ in.close();
+ out.close();
+
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ }
+
+
+
+ //copy the new file (temp) over the original
+ try {
+ InputStream i = new FileInputStream(temp);
+ OutputStream o = new FileOutputStream(file);
+
+ // Transfer bytes from in to out
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = i.read(buf)) > 0) {
+ o.write(buf, 0, len);
+ }
+
+ //close them up
+ i.close();
+ o.close();
+ } catch ( Exception e ) {}
+
+ }
+
+
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
+
+ public void setReplacement(String replacement) {
+ this.replacement = replacement;
+ }
+
+
+}
Index: /release-kits/shared/ant-tasks/tasks/orans/SetLogLevel.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/orans/SetLogLevel.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/orans/SetLogLevel.java (revision 15058)
@@ -0,0 +1,49 @@
+import java.util.*;
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import org.apache.tools.ant.taskdefs.Echo.EchoLevel;
+
+public class SetLogLevel extends Task
+{
+ private int logLevel = -1;
+
+ public void execute()
+ {
+ if (logLevel == -1)
+ {
+ throw new BuildException("Error - No Loglevel specified !!");
+ }
+ Vector listeners = this.getProject().getBuildListeners();
+ for (Iterator i = listeners.iterator(); i.hasNext();)
+ {
+ BuildListener listener = (BuildListener) i.next();
+ if (listener instanceof BuildLogger)
+ {
+ BuildLogger logger = (BuildLogger) listener;
+ logger.setMessageOutputLevel(logLevel);
+ }
+ }
+ }
+
+ /**
+ *
+ * @see org.apache.tools.ant.taskdefs.Echo$EchoLevel
+ *
+ */
+
+ public void setLevel(EchoLevel echoLevel) {
+ String option = echoLevel.getValue();
+ if (option.equals("error")) {
+ logLevel = Project.MSG_ERR;
+ } else if (option.equals("warning")) {
+ logLevel = Project.MSG_WARN;
+ } else if (option.equals("info")) {
+ logLevel = Project.MSG_INFO;
+ } else if (option.equals("verbose")) {
+ logLevel = Project.MSG_VERBOSE;
+ } else {
+ // must be "debug"
+ logLevel = Project.MSG_DEBUG;
+ }
+ }
+}
Index: /release-kits/shared/ant-tasks/tasks/orans/TreeCallTarget.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/orans/TreeCallTarget.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/orans/TreeCallTarget.java (revision 15058)
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2000-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import org.apache.tools.ant.taskdefs.*;
+import java.io.IOException;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.PropertySet;
+
+/**
+ * Call another target in the same project.
+ *
+ * This only works as expected if neither property1 nor foo are
+ * defined in the project itself.
+ *
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task name="antcall" category="control"
+ */
+public class TreeCallTarget extends Task {
+
+ private Ant callee;
+ // must match the default value of Ant#inheritAll
+ private boolean inheritAll = true;
+ // must match the default value of Ant#inheritRefs
+ private boolean inheritRefs = false;
+
+ private boolean targetSet = false;
+ private String theTarget = null;
+ private String address = null;
+
+ /**
+ * If true, pass all properties to the new Ant project.
+ * Defaults to true.
+ * @param inherit This only works as expected if neither property1 nor foo are
+ * defined in the project itself.
+ *
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task name="antcall" category="control"
+ */
+public class AddressedCallTarget extends Task {
+
+ private Ant callee;
+ // must match the default value of Ant#inheritAll
+ private boolean inheritAll = true;
+ // must match the default value of Ant#inheritRefs
+ private boolean inheritRefs = false;
+
+ //the address of the target
+ private String address = "";
+
+ private boolean targetSet = false;
+
+ /**
+ * If true, pass all properties to the new Ant project.
+ * Defaults to true.
+ * @param inherit This task provides an interface to Subversion
+revision control system that is a compelling replacement for CVS in the open source community.
+ You can add files and directories to svn repository with nested
+ Parameters specified as nested elements :
+ Get the content of a file on repository. Check out a working copy from a repository. Parameters specified as nested elements :
+
+ Send changes from your working copy to the repository. Parameters specified as nested elements :
+ Duplicate something in working copy or repository, remembering
+history. Create a new, empty repository at path. Example: If run on a working copy target, the item is scheduled for
+deletion upon the next commit. Files, and directories that have
+not been committed, are immediately removed from the working copy.
+ Parameters specified as nested elements :
+ Display the differences between two paths (oldPath and newPath) or
+two urls (oldUrl and newUrl).
+ Example : diff between BASE and current working version
+assert
keyword.
+if/else
construct.
+try/catch
construct.
+
+
+The Apache Software License, Version 1.1
+
+Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. The end-user documentation included with the redistribution, if
+ any, must include the following acknowlegement:
+ "This product includes software developed by the
+ Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowlegement may appear in the software itself,
+ if and wherever such third-party acknowlegements normally appear.
+
+4. The names "The Jakarta Project", "Ant", and "Apache Software
+ Foundation" must not be used to endorse or promote products derived
+ from this software without prior written permission. For written
+ permission, please contact apache@apache.org.
+
+5. Products derived from this software may not be called "Apache"
+ nor may "Apache" appear in their names without prior written
+ permission of the Apache Group.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+====================================================================
+
+This software consists of voluntary contributions made by many
+individuals on behalf of the Apache Software Foundation. For more
+information on the Apache Software Foundation, please see
+<http://www.apache.org/>.
+
+
+
+ <taskdef resource="ise.antelope.tasks.antelope.taskdefs
+ classpath="path/to/AntelopeTasks_3.4.1.jar"/>
+
+
+ To use this task in your build files, include a task definition like this:
+
+ <taskdef name="assert" classname="ise.antelope.tasks.Assert"/>
+ <property name="ant.enable.asserts" value="true"/>
+
+
+
+ <project xmlns:antelope="antlib:ise.antelope.tasks">
+ <antelope:try messageproperty="failed">
+ <fail>This should fail</fail>
+ <echo>This will not be reached</echo>
+ <antelope:catch>
+ <echo>failed is ${failed}</echo>
+ </antelope:catch>
+ </antelope:try>
+ </project>
+
+
assert
keyword, and provides a limited "design by contract" facility to Ant. This is very useful for testing build scripts prior to putting them into production.
+assert
keyword, the Assert task must be 'turned on' using the property ant.enable.asserts
. If not set, or is set to false
, the Assert task works exactly like the Sequential task. If the Variable task is used to define this property, then it can be turned on and off as needed throughout a build.
+
+
+ <taskdef name="assert" classname="ise.antelope.tasks.Assert"/>
+ <property name="ant.enable.asserts" value="true"/>
+
+
Attribute Description Default Required name The name of the property to test for. none Yes exists Test for existence or non-existence of the property. True No value The value to test for, implies 'exists=true'. If the value in the project is different than this value, a BuildException will be thrown and the build will stop. none No execute Should the tasks contained in this task be executed? It may be useful to set this to false when testing build files. True No failonerror Should the build halt if the assertion fails? Setting this to false is contrary to the intented use of assertions, but may be useful in certain situations. True No message A message to include with the output in the event of this assert failing. none No level A "level" for the assert, similar to debug levels. Valid values are 'error', 'warning', 'info', 'debug'. error No assert
task checks that the wait
property exists and does not execute the echo
and sleep
tasks. The second assert
task checks that the wait
property exists, has a value of 2, and executes the echo
task.
+
+
+ <property name="wait" value="2"/>
+ <assert name="wait" execute="false">
+ <echo>
+ Waiting ${wait} seconds...
+ Click the red button to stop waiting.
+ </echo>
+ <sleep seconds="${wait}"/>
+ </assert>
+ <assert name="wait" value="2" execute="true">
+ <echo>done waiting!</echo>
+ </assert>
+
+
+
+ <property name="ant.enable.asserts" value="true"/>
+ <target name="test2">
+ <!-- should not stop 'sleep' task, should print out '_passed_' -->
+ <stopwatch name="timer"/>
+ <limit maxwait="5">
+ <sleep seconds="1"/>
+ <echo>_passed_</echo>
+ </limit>
+ <stopwatch name="timer" action="total"/>
+ <assert message="Too much time.">
+ <bool>
+ <islessthan arg1="${timer}" arg2="2"/>
+ </bool>
+ </assert>
+ </target>
+
+
ant.enable.asserts
property is set to false, then in the above example, the echo
, sleep
, and echo
tasks will all execute.
+if
keyword. This is useful for performing certain tasks only if a property has a specific value or certain conditions are met.
+
+
+ <taskdef name="if" classname="ise.antelope.tasks.IfTask"/>
+
+
+
+<if>
+ <bool>
+ <some condition(s)/>
+ </bool>
+
+ some tasks...
+
+ <!-- a break is allowed
+ <break/>
+ -->
+
+ <else>
+ some other tasks...
+
+ <!-- a break is allowed
+ <break/>
+ -->
+ </else>
+</if>
+
+
Attribute Description Default Required name The name of the property to test for. none Yes, unless nested bool is used. exists Test for existence or non-existence of the property. True No value The value to test for, implies 'exists=true'. If the value for the property in the project is the same as this value, embedded tasks will be executed. none No antcall
task will execute only if the project has a property named test
with a value of true
.
+
+
+ <if name="test" value="true">
+ <antcall target="doUnitTests"/>
+ </if>
+
+
antcall
task will execute only if the project has a property named test
. In this example, it does not matter what value is assigned to the test
property.
+
+
+ <if name="test">
+ <antcall target="doUnitTests"/>
+ </if>
+
+
+
+ <antcall target="doUnitTests"/>
+ <target name="doUnitTests" if="test">
+ ...
+ </target>
+
+
antcall
task will execute only if the project does not have a property named test
. This is the opposite situation of the previous example.
+
+
+ <if name="test" exists="false">
+ <antcall target="doUnitTests"/>
+ </if>
+
+
+
+ <tstamp>
+ <format property="day" pattern="E" />
+ </tstamp>
+ <if name="test" value="true">
+ <antcall target="doUnitTests"/>
+ <if name="day" value="Mon">
+ <antcall target="publishTestResults"/>
+ </if>
+ </if>
+
+
+
+ <var name="foo" value="bar"/>
+ <if name="foo" value="bar">
+ <echo>this will happen</echo>
+ <else>
+ <echo>this won't happen</echo>
+ </else>
+ <echo>this will happen also</echo>
+ </if>
+
+ <if name="foo" value="snarf">
+ <echo>this won't happen</echo>
+ <else>
+ <echo>this 'else' will happen</echo>
+ <echo>and so will this</echo>
+ </else>
+ <echo>this won't happen either</echo>
+ </if>
+
+
+
+ <if name="email_from" value="buildteam@mycompany.com">
+ <property name="valid_email" value="true"/>
+ </if>
+ <if name="email_from" value="buildsite@mycompany.com">
+ <property name="valid_email" value="true"/>
+ </if>
+ <assert name="valid_email" value="true" failonerror="false">
+ <try>
+ <mail from="${email_from}" tolist="${email_to}"
+ message="New release available"/>
+ </try>
+ </assert>
+
+
+
+ <try>
+ <if name="email_from" value="buildteam@mycompany.com">
+ <mail from="${email_from}" tolist="${email_to}"
+ message="New release available"/>
+ <else>
+ <if name="email_from" value="buildsite@mycompany.com">
+ <mail from="${email_from}" tolist="${email_to}"
+ message="New release available"/>
+ </if>
+ </else>
+ </if>
+ </try>
+
+
+
+ <if>
+ <!-- "if" evaluates this element -->
+ <bool>
+ <and>
+ <available file="build.xml"/>
+ <available file="run.xml"/>
+ </and>
+ </bool>
+
+ <!-- if true, then tasks listed here will execute -->
+ <echo>build.xml and run.xml are available</echo>
+
+ <!-- if false, then tasks inside the "else" will execute -->
+ <else>
+ <echo>didn't find one or both of build.xml and run.xml</echo>
+ </else>
+ </if>
+
+
+
+ <if>
+ <bool>
+ <equals arg1="${download.dir}" arg2="test.dir"/>
+ </bool>
+
+ <fail message="Download and test directories cannot be
+ the same! You need to reset to use the production
+ property set."/>
+
+ <else>
+ <copy file="installer.zip" todir="${download.dir}"/>
+ </else>
+ </if>
+
+
+
+ <target name="test2">
+ <!-- should not stop 'sleep' task, should print out '_passed_' -->
+ <stopwatch name="timer"/>
+ <limit maxwait="5">
+ <sleep seconds="1"/>
+ <echo>_passed_</echo>
+ </limit>
+ <stopwatch name="timer" action="total"/>
+ <if>
+ <bool>
+ <isgreaterthan arg1="${timer}" arg2="2"/>
+ </bool>
+ <fail message="Too much time"/>
+ </if>
+ </target>
+
+
IfPropertyTrue
Attribute Description Required property The name of a property to test the value of. Yes
+
+<ispropertytrue property="myprop"/>
+<ispropertytrue property="${someprop}"/>
+
+
IfPropertyFalse
Attribute Description Required property The name of a property to test the value of. Yes
+
+<ispropertyfalse property="myprop"/>
+<ispropertyfalse property="${someprop}"/>
+
+
StartsWith
Attribute Description Required string The string to test. Yes with Check if 'string' starts with this value. Yes
+
+<startswith string="abcdefg" with="abc"/>
+<startswith string="${myprop}" with="foo"/>
+
+
EndsWith
Attribute Description Required string The string to test. Yes with Check if 'string' ends with this value. Yes
+
+<endswith string="abcdefg" with="efg"/>
+<endswith string="${myprop}" with="bar"/>
+
+
IsGreaterThan
Attribute Description Required arg1 The first argument. Yes arg2 The second argument. Yes
+
+<!-- evaluates to true -->
+<isgreaterthan arg1="6.02" arg2="4"/>
+
+<!-- evaluates to false -->
+<isgreaterthan arg1="bar" arg2="foo"/>
+
+
IsLessThan
Attribute Description Required arg1 The first argument. Yes arg2 The second argument. Yes
+
+<!-- evaluates to false -->
+<islessthan arg1="6.02" arg2="4"/>
+
+<!-- evaluates to true -->
+<islessthan arg1="bar" arg2="foo"/>
+
+
DateBefore, TimeBefore
Attribute Description Required datetime1 The first date/time. Yes datetime2 The second date/time. Yes format The format of the date/time stamps. Yes lenient Whether the datetime parser should use lenient parsing, defaults to true. No
+
+ <target name="test1">
+ <a:assert>
+ <bool>
+ <not>
+ <datebefore datetime1="2005-09-09 14:58:36" datetime2="2005-07-11 14:58:36" format="yyyy-MM-dd HH:mm:ss"/>
+ </not>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test2">
+ <a:assert>
+ <bool>
+ <not>
+ <timebefore datetime1="22:58:36" datetime2="10:58:36" format="HH:mm:ss"/>
+ </not>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test3">
+ <a:assert>
+ <bool>
+ <timebefore datetime1="2005" datetime2="2030" format="yyyy"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test4">
+ <a:assert>
+ <bool>
+ <timebefore datetime1="01:00:00" datetime2="03:00:00" format="hh:mm:ss"/>
+ </bool>
+ </a:assert>
+ </target>
+
+
DateDifference, TimeDifference
Attribute Description Required datetime1 The first date/time. Yes datetime2 The second date/time. Yes format The format of the date/time stamps. Yes lenient Whether the datetime parser should use lenient parsing, defaults to true. No value The expected difference between the 2 datetimes. No, default is 0 unit Sets the unit for the difference between the 2 datetimes. For example,
+if value is 12 and unit is "hours", then this
+condition checks that the difference between the 2 datetimes is 12 hours.
+Valid values are "millisecond", "second", "minute", "hour", "day", "week", "month", "year". Yes
+
+ <target name="test1">
+ <a:assert message="Difference between dates is not 60 days.">
+ <bool>
+ <datedifference datetime1="2005-09-09 14:58:36" datetime2="2005-07-11 14:58:36" format="yyyy-MM-dd HH:mm:ss" value="60" unit="day"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test2">
+ <a:assert message="Difference between hours is not 12.">
+ <bool>
+ <timedifference datetime1="22:58:36" datetime2="10:58:36" format="HH:mm:ss" value="12" unit="hour"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test3">
+ <a:assert message="Difference between years is not 25.">
+ <bool>
+ <timedifference datetime1="2005" datetime2="2030" format="yyyy" value="25" unit="year"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test4">
+ <a:assert message="Difference between minutes is not 120.">
+ <bool>
+ <timedifference datetime1="01:00:00" datetime2="03:00:00" format="hh:mm:ss" value="120" unit="minute"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test5">
+ <a:assert message="Difference between seconds is not 7200.">
+ <bool>
+ <timedifference datetime1="01:00:00" datetime2="03:00:00" format="hh:mm:ss" value="7200" unit="second"/>
+ </bool>
+ </a:assert>
+ </target>
+
+
Attribute Description Default Required name The name of a property whose value will be used for the switch. None Yes Attribute Description Default Required value The value of of the property used for the switch. If this value equals the property value, then all tasks in this 'case' will be executed. None Yes
+
+<property name="foo" value="bar"/>
+<switch name="foo">
+ <case value="baz">
+ <echo>Executing case baz</echo>
+ <break/>
+ </case>
+ <case value="bar">
+ <echo>Executing case bar</echo>
+ <if name="foo" value="bar">
+ <echo>breaking from the if</echo>
+ <break/>
+ </if>
+ <echo>Falling through to case "bat"</echo>
+ </case>
+ <case value="bat">
+ <echo>Executing case bat</echo>
+ <break/>
+ </case>
+ <default>
+ <echo>Executing default case</echo>
+ <break/>
+ </default>
+</switch>
+
+
+
+<taskdef name="try" classname="ise.antelope.tasks.TryTask"/>
+
+
+
+ <tempfile property="temp.file" destdir="${java.io.tmpdir}"
+ prefix="delete" suffix=".tmp"/>
+ <try>
+ <!-- use 'get' task to post to the unit test status servlet. It
+ would be better to use a post for this, but this shows a good
+ use of 'finally'. -->
+ <get
+ src="http://mycompany.com/servlet/junit?testnum=${test.num}&status="${status}"
+ dest="${temp.file}"/>
+
+ <catch>
+ <echo>Unit test servlet update failed.</echo>
+ </catch>
+
+ <finally>
+ <delete file="${temp.file}"/>
+ </finally>
+ </try>
+
+
Attribute Description Default Required break If true and a nested task fails, no other nested tasks will execute. If false, all nested tasks will execute regardless of whether a previous task failed. Note that for each failed task, the 'catch' block (if defined) will execute. true No printstacktrace If true, the exception stack trace from a failed task will be logged. false No stacktraceproperty Specify a property to store the stack trace of any exception. None No printmessage If true, the exception message from a failed task will be logged. If printstacktrace is set to true, this attribute is ignored as the exception message is printed as part of the stack trace. true No messageproperty Specify a property to store the message line of any exception. None No
+
+ <target name="test" description="This exercises the Try task.">
+ <try break="no">
+ <echo>I am trying...</echo>
+ <fail message=" and I failed..."/>
+ <echo> but I did not die!</echo> <!-- this WILL print -->
+ </try>
+ </target>
+
+
+
+ <target name="runTests" messageproperty="msg">
+ <try catch="testFailed" break="no">
+ <var name="testname" value="fileUtilTests"/>
+ <antcall target="runFileUtilTests"/>
+ <var name="testname" value="imageUtilTests"/>
+ <antcall target="runImageUtilTests"/>
+ <var name="testname" value="imageConversionTests"/>
+ <antcall target="runImageConversionTests"/>
+
+ <catch>
+ <!-- log a test failure -->
+ <echo file="test.log" append="yes">
+ Test suite ${testname} failed: ${msg}
+ </echo>
+ </catch>
+ </try>
+ </target>
+ </target>
+
+
+
+ <tempfile property="temp.file" destdir="${java.io.tmpdir}"
+ prefix="delete" suffix=".tmp"/>
+ <try>
+ <!-- use 'get' task to post to the unit test status servlet. It
+ would be better use use a post for this, but this shows a good
+ use of 'finally'. -->
+ <get
+ src="http://mycompany.com/servlet/junit?testnum=${test.num}&status="${status}"
+ dest="${temp.file}"/>
+
+ <catch>
+ <echo>Unit test servlet update failed.</echo>
+ </catch>
+
+ <finally>
+ <delete file="${temp.file}"/>
+ </finally>
+ </try>
+
+
+
+ <taskdef name="unset" classname="ise.antelope.tasks.Unset"/>
+
+
Attribute Description Default Required name The name of the property to unset. None Yes, unless 'file' is used. file The name of a property file. All properties references in the file will be unset. This means you can load a bunch of properties from a file, then unset them all with a single line. None Yes, unless 'name' is used.
+
+<project name="unset_example" basedir=".">
+ <taskdef resource="ise/antelope/tasks/antlib.xml"/>
+ <property name="x" value="6"/>
+ <echo>original value = ${x}</echo>
+ <unset name="x"/>
+ <echo>unset: ${x}</echo>
+ <property name="x" value="hello"/>
+ <echo>new value = ${x}</echo>
+</project>
+
+$ ant -f unset_example.xml
+Buildfile: unset_example.xml
+ [echo] original value = 6
+ [echo] unset: ${x}
+ [echo] new value = hello
+
+BUILD SUCCESSFUL
+Total time: 0 seconds
+
+
+
+ <taskdef name="var" classname="ise.antelope.tasks.Variable"/>
+
+
Attribute Description Default Required name The name of the property to set. None Yes, unless 'file' is used. value The value of the property. "" No file The name of a standard properties file to load variables from. None No x
is first set to "6", then evaluated by the if
, and reassigned the value "12". The echo
task will print out 12.
+
+
+ <var name="x" value="6"/>
+ <if name="x" value="6">
+ <var name="x" value="12"/>
+ </if>
+ <echo>${x}</echo> <!-- will print 12 -->
+
+
+
+ <var name="x" value="6"/>
+ <echo>x = ${x}</echo> <!-- print: 6 -->
+
+ <var name="x" value="12"/>
+ <echo>x = ${x}</echo> <!-- print: 12 -->
+
+ <var name="x" value="6 + ${x}"/>
+ <echo>x = ${x}</echo> <!-- print: 6 + 12 -->
+
+ <var name="str" value="I "/>
+ <var name="str" value="${str} am "/>
+ <var name="str" value="${str} a "/>
+ <var name="str" value="${str} string."/>
+ <echo>${str}</echo> <!-- print: I am a string. -->
+
+ <var name="x" value="6"/>
+ <echo>x = ${x}</echo> <!-- print: 6 -->
+
+ <property name="x" value="12"/>
+ <echo>x = ${x}</echo> <!-- print: 6 (property can't override) -->
+
+ <var name="x" value="blue"/>
+ <tstamp>
+ <format property="x" pattern="EEEE"/>
+ </tstamp>
+ <echo>Today is ${x}.</echo> <!-- print: Today is blue. -->
+
+ <var name="x" value=""/>
+ <tstamp>
+ <format property="x" pattern="EEEE"/>
+ </tstamp>
+ <echo>Today is ${x}.</echo> <!-- print: Today is Friday. -->
+
+
+
+
+ <var name="valid_email" value="false"/>
+ <if name="email_from" value="buildteam@mycompany.com">
+ <var name="valid_email" value="true"/>
+ </if>
+ <if name="email_from" value="buildsite@mycompany.com">
+ <var name="valid_email" value="true"/>
+ </if>
+ <assert name="valid_email" value="true" failonerror="false">
+ <try>
+ <mail from="${email_from}" tolist="${email_to}"
+ message="New release available"/>
+ </try>
+ </assert>
+
+
+
+ <taskdef name="stopwatch" classname="ise.antelope.tasks.StopWatchTask"/>
+
+
Attribute Description Default Required name The name for the stopwatch. The elapsed time or total time will be stored as an Ant property with this name. None Yes action Valid values are "start", "stop", "elapsed", and "total". "start" No
+
+<stopwatch name="timer1"/>
+<!-- do some tasks here... -->
+<stopwatch name="timer1" action="elapsed"/> <!-- print the elapsed time -->
+<!-- do some more tasks here... -->
+<stopwatch name="timer1" action="total"/> <!-- print out the total time -->
+
+
+
+ <taskdef name="limit" classname="ise.antelope.tasks.Limit"/>
+
+
Attribute Description Default Required maxwait How long to wait for nested tasks to finish, this is in seconds. 180 seconds (3 minutes) No failonerror Should the build fail if the time limit has been exceeded? false No
+
+<limit maxwait="3">
+ <sleep seconds="10"/>
+ <echo>This won't happen...</echo>
+ <fail>This won't happen either...</fail>
+</limit>
+
+
+
+<limit maxwait="3" failonerror="true">
+ <sleep seconds="10"/>
+ <echo>This won't happen...</echo>
+ <fail>This won't happen either...</fail>
+</limit>
+
+
+
+ <taskdef name="fileutil" classname="ise.antelope.tasks.FileUtilTask"/>
+
+
Attribute Description Default Required file The file or directory in question. None No, but does nothing without a file. property Where to store the answer. Caution: this task will overwrite any existing property with this name. None No Attribute Description Default Required what What to list, valid values are "files", "dirs", or "all". files No separator The separator to use between individual items in the list of files. , (comma) No includepath If true, include the path with the names in the list. If false, include only the names. true No Attribute Description Default Required format A format for the last modified timestamp. Must comply with the standards listed in java.text.SimpleDateFormat. No
+
+ <taskdef name="stringutil" classname="ise.antelope.tasks.StringUtilTask"/>
+
+
Attribute Description Default Required string The string to manipulate. None No property Where to store the manipulated string. Caution: this task will overwrite any existing property with this name. None No Attribute Description Default Required string The string to find the index of. None No fromindex Where to start looking. 0 No Attribute Description Default Required beginindex Start of substring. 0 No endindex End of substring. End of string. No Attribute Description Default Required regex Pattern to replace. None No replacement What to replace with. None No Attribute Description Default Required separator The character separating individual items in the string. Any of tab, new line, carriage return, line feed, or space. No Attribute Description Default Required title Title for the message box. None No width
+Maximum width in characters for the message box. Lines
+will be wrapped to fit inside the box. The box will not
+stretch to this width if the message is less than
+width - 4 characters wide.
+ 60 No
+
+ <target name="test1">
+ <property name="prop1" value="ABCDE"/>
+ <echo>prop1 before = ${prop1}</echo>
+ <a:stringutil string="${prop1}" property="prop1">
+ <a:lowercase/>
+ </a:stringutil>
+ <echo>prop1 after = ${prop1}</echo>
+ <a:assert message="prop1, expected abcde, got ${prop1}">
+ <bool>
+ <equals arg1="abcde" arg2="${prop1}"/>
+ </bool>
+ </a:assert>
+ </target>
+
+
+
+ <target name="test2">
+ <property name="prop2" value="abcdefgh"/>
+ <echo>prop2 before = ${prop2}</echo>
+ <a:stringutil string="${prop2}" property="prop2">
+ <a:uppercase/>
+ </a:stringutil>
+ <echo>prop2 after = ${prop2}</echo>
+ <a:assert message="prop2, expected ABCDEFGH, got ${prop2}">
+ <bool>
+ <equals arg1="ABCDEFGH" arg2="${prop2}"/>
+ </bool>
+ </a:assert>
+ </target>
+
+
+
+ <target name="test3">
+ <property name="prop3" value=" abcdefgh "/>
+ <echo>prop3 before = ${prop3}</echo>
+ <a:stringutil string="${prop3}" property="prop3">
+ <a:uppercase/>
+ <a:trim/>
+ </a:stringutil>
+ <echo>prop3 after = ${prop3}</echo>
+ <a:assert message="prop3, expected ABCDEFGH, got ${prop3}">
+ <bool>
+ <equals arg1="ABCDEFGH" arg2="${prop3}"/>
+ </bool>
+ </a:assert>
+ </target>
+
+
+
+ <target name="test4">
+ <property name="prop4" value=" abcdefgh "/>
+ <echo>prop4 before = ${prop4}</echo>
+ <a:stringutil string="${prop4}" property="prop4">
+ <a:uppercase/>
+ <a:trim/>
+ <a:substring beginindex="3"/>
+ </a:stringutil>
+ <echo>prop4 after = ${prop4}</echo>
+ <a:assert message="prop4, expected DEFGH, got ${prop4}">
+ <bool>
+ <equals arg1="DEFGH" arg2="${prop4}"/>
+ </bool>
+ </a:assert>
+ </target>
+
+
+
+ <target name="test7">
+ <property name="prop7" value="abcdefgh"/>
+ <echo>prop7 before = ${prop7}</echo>
+ <a:stringutil string="${prop7}" property="prop7">
+ <a:length/>
+ </a:stringutil>
+ <echo>prop7 length = ${prop7}</echo>
+ <a:assert message="prop7, expected 8, got ${prop7}">
+ <bool>
+ <mathequals arg1="8" arg2="${prop7}"/>
+ </bool>
+ </a:assert>
+ </target>
+
+
+
+ <target name="test12">
+ <property name="prop12" value="a,b,c,d,e,f,g,h,a,b,c,d,e,f,g,h"/>
+ <echo>prop12 before = ${prop12}</echo>
+ <a:stringutil string="${prop12}" property="prop12">
+ <a:sort separator=","/>
+ </a:stringutil>
+ <echo>prop12 sorted = ${prop12}</echo>
+ <a:assert message="prop12, expected 'a,a,b,b,c,c,d,d,e,e,f,f,g,g,h,h', got ${prop12}">
+ <bool>
+ <equals arg1="a,a,b,b,c,c,d,d,e,e,f,f,g,g,h,h" arg2="${prop12}"/>
+ </bool>
+ </a:assert>
+ </target>
+
+
+
+ <target name="test13">
+ <property name="prop13" value="Character boundary analysis allows users to interact with characters as they expect to, for example, when moving the cursor around through a text string. Character boundary analysis provides correct navigation of through character strings, regardless of how the character is stored. For example, an accented character might be stored as a base character and a diacritical mark. What users consider to be a character can differ between languages."/>
+ <echo>prop13 before = ${prop13}</echo>
+ <a:stringutil string="${prop13}" property="prop13">
+ <a:messagebox/>
+ </a:stringutil>
+ <echo>prop13 in messagebox:${line.separator}${prop13}</echo>
+
+ <property name="prop13a" value="Character boundary analysis allows users to interact with characters as they expect to, for example, when moving the cursor around through a text string. Character boundary analysis provides correct navigation of through character strings, regardless of how the character is stored. For example, an accented character might be stored as a base character and a diacritical mark. What users consider to be a character can differ between languages."/>
+ <a:stringutil string="${prop13a}" property="prop13a">
+ <a:messagebox title="About Character Boundaries"/>
+ </a:stringutil>
+ <echo>prop13a in messagebox with title:${line.separator}${prop13a}</echo>
+
+ </target>
+
+test13:
+ [echo] prop13 before = Character boundary analysis allows users to interact with characters as they expect to, for
+example, when moving the cursor around through a text string. Character boundary analysis provides correct navigation of
+ through character strings, regardless of how the character is stored. For example, an accented character might be store
+d as a base character and a diacritical mark. What users consider to be a character can differ between languages.
+ [echo] prop13 in messagebox:
+ [echo]
+ [echo] +----------------------------------------------------------------------+
+ [echo] | Character boundary analysis allows users to interact with characters |
+ [echo] | as they expect to, for example, when moving the cursor around |
+ [echo] | through a text string. Character boundary analysis provides correct |
+ [echo] | navigation of through character strings, regardless of how the |
+ [echo] | character is stored. For example, an accented character might |
+ [echo] | be stored as a base character and a diacritical mark. What users |
+ [echo] | consider to be a character can differ between languages. |
+ [echo] +----------------------------------------------------------------------+
+ [echo] prop13a in messagebox with title:
+ [echo]
+ [echo] +----------------------------------------------------------------------+
+ [echo] | About Character Boundaries |
+ [echo] +----------------------------------------------------------------------+
+ [echo] | Character boundary analysis allows users to interact with characters |
+ [echo] | as they expect to, for example, when moving the cursor around |
+ [echo] | through a text string. Character boundary analysis provides correct |
+ [echo] | navigation of through character strings, regardless of how the |
+ [echo] | character is stored. For example, an accented character might |
+ [echo] | be stored as a base character and a diacritical mark. What users |
+ [echo] | consider to be a character can differ between languages. |
+ [echo] +----------------------------------------------------------------------+
+[antlib:ise.antelope.tasks:testcase] test13 passed.
+
+
+
+ <taskdef name="uid" classname="ise.antelope.tasks.UIDTask"/>
+
+
Attribute Description Default Required name Name of a property to store the unique ID. None Yes int If true, generate a unique integer. false No
+
+<uid name="uid_1"/>
+<echo>uid_1 = ${uid_1}</echo>
+<uid name="uid_2" int="yes"/>
+<echo>uid_2 = ${uid_2}</echo>
+
+
+ [echo] uid_1 = -4a1a8b86:10728498757:-7fff
+ [echo] uid_2 = 2
+
+
+
+ <taskdef name="math" classname="ise.antelope.tasks.MathTask"/>
+
+
Attribute Description Default Required result The name of the property to hold the result of the operation. None Yes datatype Sets the datatype of the calculation. Allowed values are
+"int", "long", "float", or "double". Optional, if
+used, will be applied to all numbers in this math operation. double No strict If true, use the methods in the java.lang.StrictMath class. false No operation If used, any nested Ops will be ignored. This is for convenience for simple calculations. None No operand1 A number to use with the operation specified in the 'operation' attribute. None Depends on the specific operation. operand2 A number to use with the operation specified in the 'operation' attribute. None Depends on the specific operation. Attribute Description Default Required op Set the name of this operation. Allowed values are
+one of the method names from java.lang.Math or java.lang.StrictMath, or one of "add", "subtract", "multiply", "divide", or "mod" (or "+", "-", "*", "/", or "%", respectively) None Yes datatype Sets the datatype of this calculation. Allowed values are
+"int", "long", "float", or "double". Optional, default
+is "double". If the parent Math task has a datatype set, this value will be ignored and the datatype specifed in the task will be used. "int" No Attribute Description Default Required value Set the value for this number. Must be able to parse to the datatype set by the parent element or the default datatype set by the task. Two special numbers, pi and e, can be represented by PI and E respectively. ("PI" is the ratio of the diameter of a circle to its radius, "E" is Euler's e, the base for natural logrithms.) None Yes datatype Sets the datatype of this number. Allowed values are
+"int", "long", "float", or "double". Optional, default
+is "double". If the parent Math task has a datatype set, this value will be ignored and the datatype specifed in the task will be used. double No
+
+ <var name="op1" value="12"/>
+ <var name="op2" value="6"/>
+ <var name="op" value="+"/>
+
+ <!-- demo plus -->
+ <math result="result" operand1="${op1}" operation="${op}" operand2="${op2}" datatype="int"/>
+ <echo>${op1} ${op} ${op2} = ${result}</echo>
+ <assert name="result" value="18"/>
+
+ <!-- demo reusing result -->
+ <math result="result" operand1="${result}" operation="${op}" operand2="${op2}" datatype="int"/>
+ <echo>${op1} ${op} ${op2} = ${result}</echo>
+ <assert name="result" value="24"/>
+
+ <!-- demo minus -->
+ <var name="op" value="-"/>
+ <math result="result" operand1="${op1}" operation="${op}" operand2="${op2}" datatype="int"/>
+ <echo>${op1} ${op} ${op2} = ${result}</echo>
+ <assert name="result" value="6"/>
+
+ <!-- demo multiply -->
+ <var name="op" value="*"/>
+ <math result="result" operand1="${op1}" operation="${op}" operand2="${op2}" datatype="int"/>
+ <echo>${op1} ${op} ${op2} = ${result}</echo>
+ <assert name="result" value="72"/>
+
+ <!-- demo divide -->
+ <var name="op" value="/"/>
+ <math result="result" operand1="${op1}" operation="${op}" operand2="${op2}" datatype="int"/>
+ <echo>${op1} ${op} ${op2} = ${result}</echo>
+ <assert name="result" value="2"/>
+
+ <!-- demo modulo -->
+ <var name="op" value="%"/>
+ <math result="result" operand1="${op1}" operation="${op}" operand2="${op2}" datatype="int"/>
+ <echo>${op1} ${op} ${op2} = ${result}</echo>
+ <assert name="result" value="0"/>
+
+ <!-- demo calculating the area of a circle -->
+ <!-- first, calculate the radius -->
+ <math result="radius"> <!-- defaults to double datatype -->
+ <op type="*">
+ <num value="1"/>
+ <num value="2"/>
+ <num value="3"/>
+ <num value="4"/>
+ <num value="5"/>
+ </op>
+ </math>
+ <echo> 1 * 2 * 3 * 4 * 5 = ${radius}</echo>
+
+ <!-- now calculate the area -->
+ <math result="area" precision="float">
+ <op type="*">
+ <num value="PI"/>
+ <op type="pow">
+ <num value="${radius}"/>
+ <num value="2"/>
+ </op>
+ </op>
+ </math>
+ <echo>area = PI * radius ^ 2 = ${area}</echo>
+
+ <!-- demo calculating a random number between 0 and 100 -->
+ <math result="result">
+ <op op="rint">
+ <op op="*">
+ <num value="100"/>
+ <op op="random"/>
+ </op>
+ </op>
+ </math>
+ <echo>a random number between 0 and 100: ${result}</echo>
+
+ <!-- demo another multiplication -->
+ <math result="result" operation="multiply" operand1="17" operand2="13"/>
+ <echo>${result}</echo>
+
+
+
+ <taskdef name="hostname" classname="ise.antelope.tasks.HostnameTask"/>
+
+
Attribute Description Default Required property Name of the property to store the hostname or IP hostname No showip If true, get the IP address of the local machine. false No nic The specific name of an interface to get the hostname or IP address of. None No showall Get all names or IP addresses for all network interfaces on the local machine. false No failonerror Should the build fail if this task fails? false No
+
+ <description>
+ Unit tests for hostname task, not really good as hostname is machine
+ dependent, so writing a portable test is hard.
+ </description>
+
+ <target name="test1">
+ <a:unset name="hostname"/>
+ <a:hostname/>
+ <echo>hostname: ${hostname}</echo>
+ <a:assert name="hostname" exists="true" message="test 1 failed."/>
+ </target>
+
+ <target name="test2">
+ <a:unset name="localhost"/>
+ <a:hostname property="localhost"/>
+ <echo>localhost: ${localhost}</echo>
+ <a:assert name="localhost" exists="true" message="test 2 failed."/>
+ </target>
+
+ <target name="test3">
+ <a:unset name="localhost"/>
+ <a:hostname property="localhost" showall="yes"/>
+ <echo>all interfaces: ${localhost}</echo>
+ <a:assert name="localhost" exists="true" message="test 3 failed."/>
+ </target>
+
+ <target name="test4">
+ <a:unset name="localhost"/>
+ <a:hostname property="localhost" showall="yes" showip="yes"/>
+ <echo>all interfaces by IP: ${localhost}</echo>
+ <a:assert name="localhost" exists="true" message="test 4 failed."/>
+ </target>
+
+ <target name="test5">
+ <a:unset name="localhost"/>
+ <a:hostname property="localhost" nic="lo" showip="yes"/>
+ <echo>nic lo: ${localhost}</echo>
+ <a:assert name="localhost" value="lo:127.0.0.1" message="test 5 failed."/>
+ </target>
+
+Output:
+
+test1:
+ [echo] hostname: blackdog
+
+test2:
+ [echo] localhost: blackdog
+
+test3:
+ [echo] all interfaces: lo:127.0.0.1, eth0:, eth1:blackdog.somewhere.com, eth2:blackdog.wireless.somewhere.com
+
+test4:
+ [echo] all interfaces by IP: lo:127.0.0.1, eth0:, eth1:192.168.1.3, eth2:192.168.44.12
+
+test5:
+ [echo] nic lo: lo:127.0.0.1
+
+
+
+ <taskdef name="post" classname="ise.antelope.tasks.PostTask"/>
+
+
Attribute Description Default Required to The URL of the remote server to send the post. None Yes encoding Character encoding for the name/value pairs. UTF-8 No logfile The name of a file to write any response to. Ignored if wantresponse is set to false. None No append Should an existing log file be appended to or overwritten? True, append to an existing file. No file A file to read POST data from. All Ant properties contained in this file will be resolved (that is, ${} syntax will be expanded to their values) prior to sending the file contents. None No maxwait The maximum amount of time in seconds to wait for the data to be sent or for a response from the remote server. Setting this to zero means wait forever. 180 (3 minutes) No wantresponse Whether to wait for a response from the remote server or not. In many cases this can greatly improve the performance of the build script as the server response may be large and useless to the script. Use this with caution - while the response from the server may not be required for the client, the server may require that the client accept the response prior to processing the post data. true No property If set and wantresponse, put the response from the remote server into this property. None No failonerror Whether the build should fail if the post fails. false No Attribute Description Default Required name The name of a property to post. None Yes value The value associated with the name. None No
+
+ <property name="src.dir" value="/home/user/project/src"/>
+
+
+
+ <prop name="src.dir"/>
+ <prop name="src.dir" value="${src.dir}"/>
+ <prop name="src.dir" value="/home/user/project/src"/>
+
+
+
+ <property name="src.dir" value="/home/user/project/src"/>
+
+
+
+ ${src.dir}
+ <prop name="src.dir"/>
+ <prop name="src.dir" value="${src.dir}"/>
+ <prop name="src.dir" value="/home/user/project/src"/>
+
+
+
+ <property name="test.val" value="here's my test value"/>
+ <property name="test.val2" value="second test value"/>
+ <post to="http://wwwj.cs.unc.edu:8888/tang/servlet/tangGetPostServlet"
+ verbose="true">
+ <prop name="prop1" value="val1 ${test.val}"/>
+ <prop name="prop2" value="val1 value 2"/>
+ <prop name="prop3" value="val got some spaces %funky ^$* chars"/>
+ <prop name="prop4" value="& do an ampersand like this &amp; or
+ Ant will whine"/>
+ <prop name="thanks" value="dude, thanks for the echo server!"/>
+ <prop name="test.val"/>
+ ${test.val2}
+ </post>
+
+
+
+ <taskdef name="antfetch" classname="ise.antelope.tasks.AntFetch"/>
+
+
+
+ <ant dir="${image.project} target="fillImageDirectory"/>
+ <echo>${image.directory}</echo>
+
+
+
+ <antfetch dir="${image.project} target="fillImageDirectory" return="image.directory"/>
+ <echo>${image.directory}</echo>
+
+
+
+ <antfetch dir="${image.project} target="fillImageDirectory" return="image.directory, thumbnail.directory"/>
+ <echo>${image.directory}</echo>
+ <echo>${thumbnail.directory}</echo>
+
+
Attribute Description Default Required return A comma separated list of property names. Whitespace is allowed, so either "a,b" or "a, b" are acceptable. None No
+
+ <taskdef name="antcallback" classname="ise.antelope.tasks.AntCallBack"/>
+
+
+
+ <target name="testCallback" description="Test CallBack">
+ <taskdef name="antcallback" classname="ise.antelope.tasks.AntCallBack" classpath="${antelope.home}/build" />
+ <antcallback target="-testcb" return="a, b"/>
+ <echo>a = ${a}</echo>
+ <echo>b = ${b}</echo>
+ </target>
+
+ <target name="-testcb">
+ <property name="a" value="A"/>
+ <property name="b" value="B"/>
+ </target>
+
+
+a = A
+b = B
+
+a = ${a}
+b = ${b}
+
+
+ <target name="testCallback" description="Test CallBack" depends="-testcb">
+ <echo>a = ${a}</echo>
+ <echo>b = ${b}</echo>
+ </target>
+
+ <target name="-testcb">
+ <property name="a" value="A"/>
+ <property name="b" value="B"/>
+ </target>
+
+
Attribute Description Default Required return A comma separated list of property names. Whitespace is allowed, so either "a,b" or "a, b" are acceptable. None No
+
+ <taskdef name="call" classname="ise.antelope.tasks.Call"/>
+
+
Attribute Description Default Required target The name of a target to execute. None Yes
+
+ <target name="test" description="Test Call">
+ <call target="called"/>
+ <echo>a = ${a}</echo>
+ <echo>b = ${b}</echo>
+ </target>
+
+ <target name="called">
+ <property name="a" value="A"/>
+ <property name="b" value="B"/>
+ </target>
+
+
+
+ <taskdef name="grep" classname="ise.antelope.tasks.Find"/>
+
+
Attribute Description Default Required in The string to perform the regular expression matching on None Yes regex The regular expression. See the Java API documentation for java.util.regex.Pattern for the details of the syntax for this expression. None Yes group The regular expression group to return in the property. 0 No property The name of a property in which to put the matched value. None Yes allmatches A regex may find multiple matches in the input string. If this attribute is set to true, then the property set after the grep will contain all matches. The individual matches can be separated by using the 'separator' attribute (see below). The default is 'false', that is, only return the first match. false No separator When 'allmatches' is set to true and there are multiple matches, this value will be used to separate the individual matches. ${line.separator} No caseinsensitive Enables case-insensitive matching. false No comments Permits whitespace and comments in pattern. false No dotall Enables dotall mode. false No multiline Enables multiline mode. false No unicodecase Enables Unicode-aware case folding. false No canoneq Enables canonical equivalence. false No unixlines Enables Unix lines mode. false No
+
+ <target name="test" description="Test grep">
+ <grep in="${response}" regex="(account id=)([0-9]+)" group="2" property="AccountId"/>
+ <echo>Account Id: ${AccountId} received for ${user}</echo>
+ </target>
+
+
+
+
+ <target name="test">
+ <unset name="ant_download_page"/>
+ <post to="http://ant.apache.org/bindownload.cgi"
+ verbose="no"
+ property="ant_download_page"/>
+ <grep in="${ant_download_page}"
+ regex="select name="Preferred.*?</select"
+ dotall="yes"
+ property="options"/>
+
+ <unset name="urls"/>
+ <grep in="${options}"
+ regex="<option.*?>(.*?)</option>"
+ group="1"
+ allmatches="yes"
+ separator="${line.separator}"
+ property="urls"/>
+ <echo>${urls}</echo>
+ </target>
+
+ [echo] http://apache.gr-linux.com
+ [echo] http://www.reverse.net/pub/apache
+ [echo] http://government-grants.org/mirrors/apache.org
+ [echo] http://apache.mirrors.hoobly.com
+ [echo] http://apache.mirrormax.net
+ [echo] http://www.ibiblio.org/pub/mirrors/apache
+ [echo] http://www.mirrormonster.com/apache.org
+ [echo] http://apache.towardex.com
+ [echo] http://www.axint.net/apache
+ [echo] http://apache.tradebit.com/pub
+ [echo] http://www.eng.lsu.edu/mirrors/apache
+ [echo] http://mirrors.isc.org/pub/apache
+ [echo] http://www.theshell.com/pub/apache
+ [echo] http://apache.mirrors.redwire.net
+ [echo] http://apache.cs.utah.edu
+ [echo] http://www.tux.org/pub/net/apache/dist
+ [echo] http://linux.cs.lewisu.edu/apache
+ [echo] http://apache.roweboat.net
+ [echo] http://apache.secsup.org/dist
+ [echo] http://www.signal42.com/mirrors/apache
+ [echo] http://apache.mirror99.com
+ [echo] http://mirrors.xtria.com/apache
+ [echo] http://apache.downlod.in
+ [echo] http://apache.mirrors.pair.com
+ [echo] http://apache.seekmeup.com
+ [echo] http://mirrors.combose.com/apache
+ [echo] http://www.wmwweb.com/apache
+ [echo] http://apache.intissite.com
+ [echo] http://apache.oregonstate.edu
+ [echo] http://apache.bestwebcover.com
+ [echo] http://ftp.wayne.edu/apache
+ [echo] http://mirrors.ccs.neu.edu/Apache/dist
+ [echo] http://www.ip97.com/apache.org
+ [echo] http://apache.mirrors.versehost.com
+ [echo] http://mirrors.playboy.com/apache
+ [echo] ftp://ftp.ccs.neu.edu/net/mirrors/Apache/dist
+ [echo] ftp://apache.mirrors.pair.com
+ [echo] ftp://apache.cs.utah.edu/pub/apache.org
+ [echo] ftp://apache.mirrors.redwire.net/pub/apache
+ [echo] ftp://ftp.oregonstate.edu/pub/apache
+ [echo] ftp://ftp.wayne.edu/apache
+ [echo] ftp://mirror.sg.depaul.edu/pub/apache
+ [echo] ftp://www.ibiblio.org/pub/mirrors/apache
+ [echo] ftp://ftp.tux.org/pub/net/apache/dist
+ [echo] ftp://www.reverse.net/pub/apache
+ [echo] ftp://apache.secsup.org/pub/apache/dist
+ [echo] http://www.eu.apache.org/dist (backup)
+ [echo] http://www.apache.org/dist (backup)
+
+
+
+ <taskdef name="split" classname="ise.antelope.tasks.SplitTask"/>
+
+
Attribute Description Default Required prefix The start of the filename(s) to write the parts to. x No bytes How big, in bytes, to make the individual pieces. In general, use lines for text files, bytes or size for binary files. None No size How big to make the individual pieces. Like the Unix/Linux split utility, this attribute allows modifiers: b for 512, k for 1K, m for 1 Meg, so 100k is the same as passing 102400 in the bytes attribute. In general, use lines for text files, bytes or size for binary files. None No lines How big to make the individual pieces in lines. In general, use lines for text files, bytes or size for binary files. 1000 No property Split the value of the property into several files. None No string Split this string into several files. None No file Split this file into several files. None No outputdir Destination for the output files. None Maybe. If file is given and output dir is not, will write to the same directory as file, otherwise, this is a required attribute. failonerror Should the build stop if this task fails? Yes No
+
+ <target name="test1" depends="clean">
+ <property name="prop1" value="ABCDE"/>
+ <a:split property="prop1" bytes="1" outputdir="${out_dir}"/>
+ <a:fileutil file="${out_dir}" property="file_count">
+ <a:filecount/>
+ </a:fileutil>
+ <a:assert message="Expected 5 files, got ${file_count}">
+ <bool>
+ <a:mathequals arg1="5" arg2="${file_count}"/>
+ </bool>
+ </a:assert>
+ </target>
+
+
+
+ <target name="test2" depends="clean">
+ <!-- make sure ant.jar is available -->
+ <property name="ant.jar" value="${ant.library.dir}/ant.jar"/>
+ <available property="ant.jar.available" file="${ant.jar}"/>
+
+ <a:if name="ant.jar.available" value="true">
+ <!-- ant.jar generally runs around 1MB in size, so split into 100000 byte pieces -->
+ <a:unset name="piece_size"/>
+ <property name="piece_size" value="100000"/>
+ <a:split file="${ant.jar}" bytes="${piece_size}" outputdir="${out_dir}" prefix="ant.jar"/>
+
+ <!-- count the parts -->
+ <a:fileutil file="${out_dir}" property="file_count">
+ <a:filecount/>
+ </a:fileutil>
+
+ <!-- calculate how many parts there should be -->
+ <a:fileutil file="${ant.jar}" property="ant_size">
+ <a:filelength/>
+ </a:fileutil>
+ <a:math result="split_size">
+ <a:op op="ceil">
+ <a:op op="/">
+ <a:num value="${ant_size}"/>
+ <a:num value="${piece_size}"/>
+ </a:op>
+ </a:op>
+ </a:math>
+
+ <!-- make sure there are the right number of parts -->
+ <a:assert message="Expected ${split_size} files, got ${file_count}">
+ <bool>
+ <a:mathequals arg1="${split_size}" arg2="${file_count}"/>
+ </bool>
+ </a:assert>
+
+ <!-- sort the filenames of the parts so concat puts them together in
+ the right order-->
+ <a:fileutil file="${out_dir}" property="file_list">
+ <a:listfiles includepath="no"/>
+ </a:fileutil>
+ <a:stringutil string="${file_list}" property="file_list">
+ <a:sort/>
+ </a:stringutil>
+
+ <!-- put them back together -->
+ <concat destfile="${out_dir}/ant.jar" binary="true">
+ <filelist dir="${out_dir}" files="${file_list}"/>
+ </concat>
+
+ <!-- make sure the new file is the identical to the original -->
+ <a:assert message="concat did not produce identical file">
+ <bool>
+ <filesmatch file1="${ant.jar}" file2="${out_dir}/ant.jar"/>
+ </bool>
+ </a:assert>
+ </a:if>
+ </target>
+
+
+
+ <taskdef name="call" classname="ise.antelope.tasks.Repeat"/>
+
+
Attribute Description Default Required count The number of times to repeat execution of the nested tasks. 1 No interval How long to wait between repetitions. If set to 0, only 1 repetition will be performed, this is to avoid a tight loop. 0 No unit The units for interval, allowed values are "milliseconds", "seconds", "minutes", "days", and "weeks" seconds No property The name of a property to set upon completion. None No value The value to set for the property to be set upon completion. None No
+
+ <target name="test1a">
+ <!-- no count set, verify performs tasks once -->
+ <a:var name="count" value="0"/>
+ <a:repeat>
+ <a:math result="count" operand1="${count}" operand2="1" operation="+"/>
+ </a:repeat>
+ <a:assert>
+ <bool>
+ <mathequals arg1="${count}" arg2="1"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test1b">
+ <!-- count > 1, verify performs tasks correct number of times -->
+ <a:var name="count" value="0"/>
+ <a:repeat count="3" interval="1">
+ <a:math result="count" operand1="${count}" operand2="1" operation="+"/>
+ </a:repeat>
+ <a:assert message="Expected 3, got ${count}">
+ <bool>
+ <mathequals arg1="${count}" arg2="3"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test1c">
+ <!-- count = -1, verify performs tasks indefinitely -->
+ <a:var name="count" value="0"/>
+ <a:limit maxwait="10">
+ <a:repeat count="-1" interval="1">
+ <a:math result="count" operand1="${count}" operand2="1" operation="+"/>
+ </a:repeat>
+ </a:limit>
+ <a:assert>
+ <bool>
+ <and>
+ <a:isgreaterthan arg1="${count}" arg2="8"/>
+ <a:islessthan arg1="${count}" arg2="12"/>
+ </and>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test2a">
+ <!-- no interval set, verify performs tasks 10 seconds apart -->
+ <a:var name="count" value="0"/>
+ <a:stopwatch name="test2a_stopwatch" action="start"/>
+ <a:repeat count="2">
+ <a:math result="count" operand1="${count}" operand2="1" operation="+"/>
+ </a:repeat>
+ <a:stopwatch name="test2a_stopwatch" action="total"/>
+ <a:assert message="Got ${count}, expected 2">
+ <bool>
+ <and>
+ <a:mathequals arg1="${count}" arg2="2"/>
+ <a:islessthan arg1="${test2a_stopwatch}" arg2="11"/>
+ </and>
+ </bool>
+ </a:assert>
+ </target>
+
+
+ <target name="test2b">
+ <!-- interval set to other than 10 seconds, verify tasks performed correct
+ time apart. -->
+ <a:var name="count" value="0"/>
+ <a:stopwatch name="test2b_stopwatch" action="start"/>
+ <a:repeat count="2" interval="5">
+ <a:math result="count" operand1="${count}" operand2="1" operation="+"/>
+ </a:repeat>
+ <a:stopwatch name="test2b_stopwatch" action="total"/>
+ <a:assert>
+ <bool>
+ <and>
+ <a:mathequals arg1="${count}" arg2="2"/>
+ <a:islessthan arg1="${test2b_stopwatch}" arg2="6"/>
+ </and>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test2c">
+ <!-- interval = 0, verify tasks performed just once -->
+ <a:var name="count" value="0"/>
+ <a:stopwatch name="test2c_stopwatch" action="start"/>
+ <a:repeat count="5" interval="0">
+ <a:math result="count" operand1="${count}" operand2="1" operation="+" datatype="int"/>
+ </a:repeat>
+ <a:stopwatch name="test2c_stopwatch" action="total"/>
+ <a:assert>
+ <bool>
+ <and>
+ <a:mathequals arg1="${count}" arg2="1"/>
+ <a:islessthan arg1="${test2c_stopwatch}" arg2="1"/>
+ </and>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test3a">
+ <!-- failOnError not set, verify continues to execute tasks even if one fails -->
+ <a:var name="count" value="0"/>
+ <a:repeat count="3" interval="1">
+ <a:math result="count" operand1="${count}" operand2="1" operation="+"/>
+ <fail/>
+ </a:repeat>
+ <a:assert>
+ <bool>
+ <a:mathequals arg1="${count}" arg2="3"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test3b">
+ <!-- failOnError set to false, same as 3a -->
+ <a:var name="count" value="0"/>
+ <a:repeat count="3" interval="1" failonerror="no">
+ <a:math result="count" operand1="${count}" operand2="1" operation="+"/>
+ <fail/>
+ </a:repeat>
+ <a:assert>
+ <bool>
+ <a:mathequals arg1="${count}" arg2="3"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test3c">
+ <!-- failOnError set to true, verify build fails if subtask fails -->
+ <a:var name="count" value="0"/>
+ <a:try>
+ <a:repeat count="3" interval="1" failonerror="yes">
+ <a:math result="count" operand1="${count}" operand2="1" operation="+"/>
+ <fail/>
+ </a:repeat>
+ </a:try>
+ <a:assert>
+ <bool>
+ <a:mathequals arg1="${count}" arg2="1"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test4a">
+ <!-- property name set, value not set, verify property is set to true when task
+ is complete -->
+ <a:var name="count" value="0"/>
+ <a:repeat count="1" interval="1" property="test4a_property">
+ <a:math result="count" operand1="${count}" operand2="1" operation="+"/>
+ <fail/>
+ </a:repeat>
+ <a:assert>
+ <bool>
+ <istrue value="${test4a_property}"/>
+ </bool>
+ </a:assert>
+ </target>
+
+ <target name="test4b">
+ <!-- property ame set, value set to a specific value, verify property is set to
+ specific value when task is complete -->
+ <a:var name="count" value="0"/>
+ <a:repeat count="1" interval="1" property="test4b_property" value="good">
+ <a:math result="count" operand1="${count}" operand2="1" operation="+"/>
+ <fail/>
+ </a:repeat>
+ <a:assert name="test4b_property" value="good"/>
+ </target>
+
+ <target name="test5">
+ <property name="call_count" value="0"/>
+ <a:limit seconds="5" failonerror="true">
+ <a:repeat count="-1" interval="1">
+ <a:until>
+ <a:contains property="log_contents" substring="All tests passed 4 times." />
+ </a:until>
+
+ <echo>read log</echo>
+ <a:new>
+ <a:call target="readLog"/>
+ </a:new>
+ <echo>${call_count} - ${log_contents}</echo>
+
+ </a:repeat>
+ </a:limit>
+ </target>
+
+ <target name="readLog">
+ <a:unset name="log_contents"/>
+ <a:new>
+ <a:math result="call_count" operand1="${call_count}" operand2="1" operation="+" datatype="int"/>
+ <property name="log_contents" value="All tests passed ${call_count} times."/>
+ </a:new>
+ </target>
+
+
+
+ <taskdef name="suite" classname="ise.antelope.tasks.Suite"/>
+
+
Attribute Description Default Required enabled Determines if this suite should be ran. By using a property for this attribute, it is easy to turn off/on multiple tests. On No assertenabled Generally tests will use the Assert task. This attribute sets whether asserts should be enabled. Yes No showoutput If true, show intermediate test results Yes No showsummary If true, show a summary of test results at the end of the test run. Yes Yes
+
+<project name="mathtest" basedir="." xmlns:a="antlib:ise.antelope.tasks">
+ <description>
+ Build file to run unit tests for the Math task
+ </description>
+
+ <a:suite>
+ <a:testcase file="math_basic_tests.xml"/>
+ <a:testcase file="math_rules_tests.xml"/>
+ <a:testcase file="math_precision_tests.xml"/>
+ </a:suite>
+
+ <!-- alternatively, a fileset could be used:
+ <a:suite>
+ <fileset dir="${basedir}">
+ <include name="math_*.xml"/>
+ </fileset>
+ </a:suite>
+ -->
+</project>
+
+$ ant -f mathtest2.xml
+Buildfile: mathtest2.xml
+ [testcase] +-------------------------------------------+
+ [testcase] + mathtest
+ [testcase] +-------------------------------------------+
+
+test6:
+ [testcase] ERROR: test6 failed: string or property must be set.
+
+test5:
+ [testcase] test5 passed.
+
+test4:
+ [testcase] test4 passed.
+
+test3:
+ [testcase] test3 passed.
+
+test2:
+ [testcase] test2 passed.
+
+test1:
+ [testcase] test1 passed.
+ [testcase] +-------------------------------------------+
+ [testcase] + mathtest
+ [testcase] +-------------------------------------------+
+ [testcase]
+ [testcase] ---- Errors ---------------------------------
+ [testcase] ERROR: test6 failed: string or property must be set.
+ [testcase] ---- Results --------------------------------
+ [testcase] Ran 6 out of 6 tests.
+ [testcase] Passed: 5
+ [testcase] Warning: 0
+ [testcase] Failed: 1
+ [testcase] +-------------------------------------------+
+ [testcase] +-------------------------------------------+
+ [testcase] + math_precision_tests
+ [testcase] +-------------------------------------------+
+
+test11:
+ [echo] Division by zero test
+ [a:try] Task 'a:math' in target 'test11' failed, error message is: java.lang.ArithmeticException
+ [testcase] ERROR: test11 failed: java.lang.ArithmeticException: / by zero
+
+test10:
+ [echo] Circle area test
+ [testcase] ERROR: test10 failed: string or property must be set.
+ [testcase] +-------------------------------------------+
+ [testcase] + math_precision_tests
+ [testcase] +-------------------------------------------+
+ [testcase]
+ [testcase] ---- Errors ---------------------------------
+ [testcase] ERROR: test11 failed: java.lang.ArithmeticException: / by zero
+ [testcase] ERROR: test10 failed: string or property must be set.
+ [testcase] ---- Results --------------------------------
+ [testcase] Ran 2 out of 2 tests.
+ [testcase] Passed: 0
+ [testcase] Warning: 0
+ [testcase] Failed: 2
+ [testcase] +-------------------------------------------+
+ [testcase] +-------------------------------------------+
+ [testcase] + math_rules_tests
+ [testcase] +-------------------------------------------+
+
+test7.2:
+ [testcase] test7.2 passed.
+
+test7.1:
+ [testcase] test7.1 passed.
+
+test7.0:
+ [testcase] test7.0 passed.
+
+test8.3:
+ [testcase] test8.3 passed.
+
+test8.2:
+ [testcase] test8.2 passed.
+
+test9:
+ [testcase] test9 passed.
+
+test8.1:
+ [testcase] test8.1 passed.
+
+test8.0:
+ [testcase] test8.0 passed.
+ [testcase] +-------------------------------------------+
+ [testcase] + math_rules_tests
+ [testcase] +-------------------------------------------+
+ [testcase] ---- Results --------------------------------
+ [testcase] Ran 8 out of 8 tests.
+ [testcase] Passed: 8
+ [testcase] Warning: 0
+ [testcase] Failed: 0
+ [testcase] +-------------------------------------------+
+ [suite] ++-- Totals -------------------------------++
+ [suite] ++ Total Ran 16 out of 16 tests.
+ [suite] ++ Total Passed: 13
+ [suite] ++ Total Warnings: 0
+ [suite] ++ Total Failed: 3
+ [suite] ++-----------------------------------------++
+
+BUILD SUCCESSFUL
+Total time: 1 second
+
+
+
+ <taskdef name="testcase" classname="ise.antelope.tasks.TestCase"/>
+
+
Attribute Description Default Required file The file containing tests. None Yes enabled Determines if this test should be ran. By using a property for this attribute, it is easy to turn off/on multiple tests. On No assertenabled Generally tests will use the Assert task. This attribute sets whether asserts should be enabled. Yes No failonerror If true, cause the build to fail. By default, a failed test does not cause the build to fail, so all tests may have the opportunity to run. No No showoutput If true, show intermediate test results Yes No showsummary If true, show a summary of test results at the end of the test run. Yes Yes
+
+<project name="mathtest" basedir="." default="suite"
+ xmlns:a="antlib:ise.antelope.tasks">
+
+ <description>
+ Build file to run unit tests for the Math task
+ </description>
+
+ <a:suite>
+ <a:testcase file="math_basic_tests.xml"/>
+ <a:testcase file="math_rules_tests.xml"/>
+ <a:testcase file="math_precision_tests.xml"/>
+ </a:suite>
+
+</project>
+
+
+
+<project name="math_precision_tests" basedir="." default="suite"
+ xmlns:a="antlib:ise.antelope.tasks">
+
+ <target name="setUp">
+ <echo>Running math precision tests.</echo>
+ </target>
+
+ <target name="test10">
+ <echo>Circle area test</echo>
+ <a:math result="pi">
+ <a:op op="*">
+ <a:num value="PI"/>
+ <a:op op="pow">
+ <a:num value="1"/>
+ <a:num value="2"/>
+ </a:op>
+ </a:op>
+ </a:math>
+ <a:assert message="failed circle area test">
+ <a:bool>
+ <a:startswith string="${pi}" with="3.141592653589793"/>
+ </a:bool>
+ </a:assert>
+ </target>
+
+ <target name="test11">
+ <echo>Division by zero test</echo>
+ <!-- division by zero -->
+ <a:try>
+ <a:math result="x">
+ <a:op op="/">
+ <a:num value="PI"/>
+ <a:num value="0"/>
+ </a:op>
+ </a:math>
+ <fail>Division by 0 succeeded: ${x}</fail>
+ <catch>
+ <assert/>
+ </catch>
+ </a:try>
+ </target>
+
+</project>
+
+
+
+ ant -listener ise.antelope.common.AntPerformanceListener target
+
+
+
+[danson@blackdog antelope]$ ant -listener ise.antelope.common.AntPerformanceListener dist
+Buildfile: build.xml
+
+init:
+
+clean:
+ [delete] Deleting 170 files from /home/danson/apps/antelope/build
+
+compile:
+ [javac] Compiling 61 source files to /home/danson/apps/antelope/build
+
+all:
+
+-build_number:
+
+prep_files:
+ [delete] Deleting 3 files from /home/danson/apps/antelope/config
+ [copy] Copying 3 files to /home/danson/apps/antelope/config
+
+combined:
+ [echo] basedir = /home/danson/apps/antelope
+ [jar] Building jar: /home/danson/apps/antelope/Antelope_1.208.jar
+
+dist:
+ [delete] Deleting 4 files from /home/danson/apps/antelope/dist
+ [zip] Building zip: /home/danson/apps/antelope/dist/Antelope_1.208.zip
+ [echo] Created zip file.
+
+-zip_docs:
+ [zip] Building zip: /home/danson/apps/antelope/dist/Antelope_docs_1.208.zip
+ [echo] Zipped docs to Antelope_docs_1.208.zip.
+
+-zip_tasks:
+ [jar] Building jar: /tmp/Antelope_tasks_1.208.jar
+ [zip] Building zip: /home/danson/apps/antelope/dist/Antelope_tasks_1.208.zip
+ [delete] Deleting: /tmp/Antelope_tasks_1.208.jar
+ [echo] Zipped tasks to Antelope_tasks_1.208.zip.
+ [copy] Copying 1 file to /home/danson/apps/antelope/dist
+
+BUILD SUCCESSFUL
+Total time: 8 seconds
+
+-------------- Target Results -----------------------
+Antelope.all: 0.000 sec
+Antelope.init: 0.011 sec
+Antelope.-build_number: 0.014 sec
+Antelope.clean: 0.233 sec
+Antelope.-zip_tasks: 0.297 sec
+Antelope.prep_files: 0.311 sec
+Antelope.-zip_docs: 0.546 sec
+Antelope.combined: 1.290 sec
+Antelope.compile: 1.724 sec
+Antelope.dist: 2.162 sec
+
+-------------- Task Results -----------------------
+Antelope.init.mkdir: 0.000 sec
+Antelope.init.mkdir: 0.001 sec
+Antelope.dist.echo: 0.002 sec
+Antelope.prep_files.delete: 0.004 sec
+Antelope.combined.echo: 0.005 sec
+Antelope.dist.delete: 0.006 sec
+Antelope.-zip_tasks.echo: 0.007 sec
+Antelope.dist.copy: 0.011 sec
+Antelope.-build_number.buildnumber: 0.014 sec
+Antelope.compile.copy: 0.016 sec
+Antelope.prep_files.copy: 0.020 sec
+Antelope.prep_files.replace: 0.071 sec
+Antelope.-zip_tasks.zip: 0.122 sec
+Antelope.-zip_tasks.jar: 0.161 sec
+Antelope.prep_files.replace: 0.216 sec
+Antelope.clean.delete: 0.233 sec
+Antelope.dist.antcall: 0.421 sec
+Antelope.-zip_docs.zip: 0.540 sec
+Antelope.dist.antcall: 0.685 sec
+Antelope.dist.zip: 1.036 sec
+Antelope.combined.jar: 1.284 sec
+Antelope.compile.javac: 1.708 sec
+
+-------------- Totals -----------------------
+Start time: Thu, 5 Dec 2002 17:18:30
+Stop time: Thu, 5 Dec 2002 17:18:39
+Total time: 8.476 sec
+
+
<danson@germane-software.com>
+
+ * <target name="foo" depends="init">
+ * <ant antfile="build.xml" target="bar" >
+ * <property name="property1" value="aaaaa" />
+ * <property name="foo" value="baz" />
+ * </ant> </target> <target name="bar"
+ * depends="init"> <echo message="prop is ${property1}
+ * ${foo}" /> </target>
+ *
+ * @author costin@dnt.ro
+ * @author Dale Anson, danson@germane-software.com
+ * @since Ant 1.1
+ * @ant.task category="control"
+ */
+public class AntCallBack 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;
+
+ /** should we inherit references from the parent ? */
+ private boolean inheritRefs = false;
+
+ /** the properties to pass to the new project */
+ private Vector properties = new Vector();
+
+ /** the references to pass to the new project */
+ private Vector references = new Vector();
+
+ /** the temporary project created to run the build file */
+ private Project newProject;
+
+ /** The stream to which output is to be written. */
+ private PrintStream out = null;
+
+ /** the name of the property to fetch from the new project */
+ private String returnName = null;
+
+
+ /**
+ * If true, pass all properties to the new Ant project. Defaults to true.
+ *
+ * @param value The new inheritAll value
+ */
+ public void setInheritAll( boolean value ) {
+ inheritAll = value;
+ }
+
+
+ /**
+ * If true, pass all references to the new Ant project. Defaults to false.
+ *
+ * @param value The new inheritRefs value
+ */
+ public void setInheritRefs( boolean value ) {
+ inheritRefs = value;
+ }
+
+
+ /** Creates a Project instance for the project to call. */
+ public void init() {
+ newProject = new Project();
+ newProject.setJavaVersionProperty();
+ newProject.addTaskDefinition( "property",
+ (Class)getProject().getTaskDefinitions().get( "property" ) );
+ }
+
+
+ /**
+ * Called in execute or createProperty if newProject is null.
+ * <target name="foo" depends="init">
+ * <ant antfile="build.xml" target="bar" >
+ * <property name="property1" value="aaaaa" />
+ * <property name="foo" value="baz" />
+ * </ant> </target> <target name="bar"
+ * depends="init"> <echo message="prop is ${property1}
+ * ${foo}" /> </target>
+ *
+ * @author costin@dnt.ro
+ * @author Dale Anson, danson@germane-software.com
+ * @since Ant 1.1
+ * @ant.task category="control"
+ */
+public class AntFetch 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;
+
+ /** should we inherit references from the parent ? */
+ private boolean inheritRefs = false;
+
+ /** the properties to pass to the new project */
+ private Vector properties = new Vector();
+
+ /** the references to pass to the new project */
+ private Vector references = new Vector();
+
+ /** the temporary project created to run the build file */
+ private Project newProject;
+
+ /** The stream to which output is to be written. */
+ private PrintStream out = null;
+
+ /** the name of the property to fetch from the new project */
+ private String returnName = null;
+
+
+ /**
+ * If true, pass all properties to the new Ant project. Defaults to true.
+ *
+ * @param value The new inheritAll value
+ */
+ public void setInheritAll( boolean value ) {
+ inheritAll = value;
+ }
+
+
+ /**
+ * If true, pass all references to the new Ant project. Defaults to false.
+ *
+ * @param value The new inheritRefs value
+ */
+ public void setInheritRefs( boolean value ) {
+ inheritRefs = value;
+ }
+
+
+ /** Creates a Project instance for the project to call. */
+ public void init() {
+ newProject = new Project();
+ newProject.setJavaVersionProperty();
+ newProject.addTaskDefinition( "property",
+ (Class)getProject().getTaskDefinitions()
+ .get( "property" ) );
+ }
+
+
+ /**
+ * Called in execute or createProperty if newProject is null.
+ *
+ *
+ */
+ public void init() {
+ Project p = getProject();
+ p.addTaskDefinition( "antcallback", AntCallBack.class);
+ p.addTaskDefinition( "antfetch", AntFetch.class );
+ p.addTaskDefinition( "assert", Assert.class );
+ p.addTaskDefinition( "bool", BooleanConditionTask.class );
+ p.addTaskDefinition( "break", Break.class );
+ p.addTaskDefinition( "case", Case.class );
+ p.addTaskDefinition( "catch", CatchTask.class );
+ p.addTaskDefinition( "default", DefaultCase.class );
+ p.addTaskDefinition( "else", ElseTask.class );
+ p.addTaskDefinition( "finally", FinallyTask.class );
+ p.addTaskDefinition( "if", IfTask.class );
+ p.addTaskDefinition( "limit", Limit.class);
+ p.addTaskDefinition( "math", MathTask.class );
+ p.addTaskDefinition( "post", PostTask.class );
+ p.addTaskDefinition( "stopwatch", StopWatchTask.class );
+ p.addTaskDefinition( "switch", SwitchTask.class );
+ p.addTaskDefinition( "try", TryTask.class );
+ p.addTaskDefinition( "var", Variable.class );
+ }
+
+ /**
+ * Does nothing.
+ */
+ public void execute() {
+ // no-op, only care about the init.
+ }
+}
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Assert.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Assert.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Assert.java (revision 15058)
@@ -0,0 +1,521 @@
+/*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Ant", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+*
+ *
setAllmatches
, this string will be
+ * placed between each match in the final result.
+ *
+ * @param s the separator, default is "".
+ */
+ public void setSeparator(String s) {
+ separator = s;
+ }
+
+ /** Do the grep */
+ public void execute() {
+ // check attributes
+ if (findIn == null)
+ throw new BuildException("'in' is required");
+ if (regex == null)
+ throw new BuildException("'regex' is required");
+ if (property == null)
+ throw new BuildException("'property' is required");
+
+ // set flags for pattern
+ int flags = 0;
+ if (dotall)
+ flags += Pattern.DOTALL;
+ if (caseInsensitive)
+ flags += Pattern.CASE_INSENSITIVE;
+ if (multiLine)
+ flags += Pattern.MULTILINE;
+ if (unicodeCase)
+ flags += Pattern.UNICODE_CASE;
+ if (canonEq)
+ flags += Pattern.CANON_EQ;
+ if (comments)
+ flags += Pattern.COMMENTS;
+ if (unixLines)
+ flags += Pattern.UNIX_LINES;
+
+ try {
+ Pattern p = Pattern.compile(regex, flags);
+ Matcher m = p.matcher(findIn);
+ StringBuffer result = new StringBuffer();
+ int count = 0;
+ if (allMatches) {
+ while (m.find()) {
+ String match = m.group(group);
+ if (match != null) {
+ result.append(match).append(separator);
+ ++ count;
+ }
+ }
+ }
+ else if (m.find()) {
+ String match = m.group(group);
+ if (match != null)
+ result.append(match);
+ }
+
+ if (result.length() > 0) {
+ getProject().setUserProperty(property, result.toString());
+ if (allMatches)
+ getProject().setUserProperty(property + "_count", String.valueOf(count));
+ }
+ else
+ log("No match.");
+ }
+ catch (Exception e) {
+ throw new BuildException(e.getMessage());
+ }
+ }
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/ForTask.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/ForTask.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/ForTask.java (revision 15058)
@@ -0,0 +1,306 @@
+/*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Ant", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+* setSeparator
+ */
+ public String getMatch() {
+ return grep_match;
+ }
+
+ /**
+ * @return an Iterator over all matches found by the regular expression.
+ */
+ public Iterator getMatches() {
+ return matches.iterator();
+ }
+
+ /**
+ * @return if there are multiple matches, return the i
th match.
+ */
+ public String getMatch(int i) {
+ return (i < 0 || i >= matches.size()) ? null : (String)matches.get(i);
+ }
+
+ /**
+ * Used in conjunction with setAllmatches
, this string will be
+ * placed between each match in the final result.
+ *
+ * @param s the separator, default is "".
+ */
+ public void setSeparator(String s) {
+ separator = s;
+ }
+
+ /** Do the grep */
+ public String grep() {
+ // check attributes
+ if (findIn == null)
+ throw new IllegalArgumentException("'in' is required");
+ if (regex == null)
+ throw new IllegalArgumentException("'regex' is required");
+
+ // set flags for pattern
+ int flags = 0;
+ if (dotall)
+ flags += Pattern.DOTALL;
+ if (caseInsensitive)
+ flags += Pattern.CASE_INSENSITIVE;
+ if (multiLine)
+ flags += Pattern.MULTILINE;
+ if (unicodeCase)
+ flags += Pattern.UNICODE_CASE;
+ if (canonEq)
+ flags += Pattern.CANON_EQ;
+ if (comments)
+ flags += Pattern.COMMENTS;
+ if (unixLines)
+ flags += Pattern.UNIX_LINES;
+
+ try {
+ Pattern p = Pattern.compile(regex, flags);
+ Matcher m = p.matcher(findIn);
+ StringBuffer result = new StringBuffer();
+ matches = new ArrayList();
+ if (allMatches) {
+ while (m.find()) {
+ String match = m.group(group);
+ if (match != null) {
+ result.append(match).append(separator);
+ matches.add(match);
+ }
+ }
+ }
+ else if (m.find()) {
+ String match = m.group(group);
+ if (match != null) {
+ result.append(match);
+ matches.add(match);
+ }
+ }
+
+ grep_match = result.length() > 0 ? result.toString() : null;
+ return grep_match;
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/HostnameTask.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/HostnameTask.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/HostnameTask.java (revision 15058)
@@ -0,0 +1,159 @@
+package ise.antelope.tasks;
+
+import java.io.IOException;
+import java.net.*;
+import java.util.Enumeration;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * A task to put hostname or IP in a property. The default property is
+ * 'hostname'.
+ * lo:127.0.0.1, eth0:mycomputer.somewhere.com, eth1:wireless.somwhere.com
+ *
+ * @param b if true, show all hostnames and IPs
+ */
+ public void setShowall(boolean b) {
+ showAll = b;
+ }
+
+ public void setShowcanonical(boolean b) {
+ canonical = b;
+ outputType = CANON;
+ }
+
+ /** Description of the Method */
+ public void execute() {
+ try {
+ if (showAll) {
+ StringBuffer hostnames = new StringBuffer();
+ Enumeration nics = NetworkInterface.getNetworkInterfaces();
+ while (nics.hasMoreElements()) {
+ NetworkInterface nic = (NetworkInterface) nics.nextElement();
+ hostnames.append(nic.getName() + ":");
+ Enumeration addrs = nic.getInetAddresses();
+ while (addrs.hasMoreElements()) {
+ InetAddress addr = (InetAddress) addrs.nextElement();
+ String hostname = getAddress(addr);
+ if (hostname != null && hostname.trim().length() > 0)
+ hostnames.append(hostname);
+ if (addrs.hasMoreElements())
+ hostnames.append(", ");
+ }
+ if (nics.hasMoreElements())
+ hostnames.append(", ");
+ }
+ getProject().setProperty(property, hostnames.toString());
+ }
+ else if (nIC != null) {
+ StringBuffer hostnames = new StringBuffer();
+ Enumeration nics = NetworkInterface.getNetworkInterfaces();
+ while (nics.hasMoreElements()) {
+ NetworkInterface nic = (NetworkInterface) nics.nextElement();
+ if (nIC.equals(nic.getName())) {
+ hostnames.append(nic.getName() + ":");
+ Enumeration addrs = nic.getInetAddresses();
+ while (addrs.hasMoreElements()) {
+ InetAddress addr = (InetAddress) addrs.nextElement();
+ String hostname = getAddress(addr);
+ if (hostname != null && hostname.trim().length() > 0)
+ hostnames.append(hostname);
+ if (addrs.hasMoreElements())
+ hostnames.append(", ");
+ }
+ }
+ }
+ getProject().setProperty(property, hostnames.toString());
+ }
+ else {
+ InetAddress addr = InetAddress.getLocalHost();
+ String hostname = getAddress(addr);
+ getProject().setProperty(property, hostname);
+ }
+ }
+ catch (IOException e) {
+ if (failOnError)
+ throw new BuildException(e.getMessage());
+ else
+ log(e.getMessage());
+ }
+ }
+
+ private String getAddress(InetAddress addr) {
+ String hostname = "";
+ switch (outputType) {
+ case IP:
+ hostname = addr.getHostAddress();
+ break;
+ case CANON:
+ hostname = addr.getCanonicalHostName();
+ break;
+ default:
+ hostname = addr.getHostName();
+ }
+ return hostname;
+ }
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/IfTask.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/IfTask.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/IfTask.java (revision 15058)
@@ -0,0 +1,316 @@
+/*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Ant", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+* execute
+ * method throws BuildException if the actual value is not the same as this value.
+ * Optional.
+ *
+ * @param value the expected value of the property.
+ */
+ public void setValue( String value ) {
+ this.value = value;
+ }
+
+
+ /**
+ * Set the 'exists' attribute. If true, throws BuildException if the property
+ * does not exist. Optional, default is true.
+ *
+ * @param exists Ant boolean, whether the value must exist.
+ */
+ public void setExists( String exists ) {
+ this.exists = getProject().toBoolean( exists );
+ }
+
+
+ /**
+ * Required by Breakable.
+ *
+ * @param b The new break value
+ */
+ public void setBreak( boolean b ) {
+ doBreak = b;
+ }
+
+
+ /**
+ * Required by Breakable.
+ *
+ * @param b The feature to be added to the Break attribute
+ */
+ public void addBreak( Break b ) {
+ // does nothing for Ant 1.5, next line is for Ant 1.6
+ addTask( b );
+ }
+
+ public void addElse( ElseTask elseTask ) {
+ addTask( elseTask );
+ }
+
+ public void addBool( BooleanConditionTask boolTask ) {
+ addTask( boolTask );
+ }
+
+ /**
+ * Required by Breakable.
+ *
+ * @return Description of the Return Value
+ */
+ public boolean doBreak() {
+ return doBreak;
+ }
+
+
+ /**
+ * Override {@link org.apache.tools.ant.Task#maybeConfigure maybeConfigure}
+ * in a way that leaves the nested tasks unconfigured until they get
+ * executed.
+ *
+ * @exception BuildException Description of the Exception
+ * @since Ant 1.5
+ */
+ public void maybeConfigure() throws BuildException {
+ if ( isInvalid() ) {
+ super.maybeConfigure();
+ }
+ else {
+ getRuntimeConfigurableWrapper().maybeConfigure( getProject(), false );
+ }
+ }
+
+
+ /**
+ * Add a nested task to execute. add(new int[]{1, 2, 3})
+ * is equivalent to
+ * add(add(1, 2), 3)
+ * which is equivalent to 1 + 2 + 3.
+ * @param op the operation to perform
+ * @type the data type of the operands. All operands will be cast to the same
+ * data type
+ * @param operands these strings must parse to numbers.
+ */
+ private Number calculateArray( String op, String type, String[] operands ) {
+ try {
+ Class c = this.getClass();
+
+ // find candidate methods for the requested operation
+ Vector candidates = new Vector();
+ Method[] methods = c.getDeclaredMethods();
+ for ( int i = 0; i < methods.length; i++ ) {
+ String name = methods[ i ].getName();
+ if ( name.equals( op ) ) {
+ if ( methods[ i ].getParameterTypes().length == 1 ) {
+ if ( methods[ i ].getParameterTypes() [ 0 ].isArray() )
+ candidates.addElement( methods[ i ] );
+ }
+ }
+ }
+ if ( candidates.size() == 0 )
+ throw new RuntimeException( "Unknown operation: " + op );
+
+ // get the desired data type for the operation, default is
+ // Double.TYPE if no other match is found
+ Object wantTypeClass = getDataTypeArray( type, operands.length );
+
+ // find the actual method to invoke and invoke it immediately once
+ // it is found
+ Class typeClass = null;
+ Enumeration en = candidates.elements();
+ while ( en.hasMoreElements() ) {
+ Method m = ( Method ) en.nextElement();
+ if ( m.getParameterTypes() [ 0 ].equals( wantTypeClass.getClass() ) ) {
+ typeClass = getDataType( type );
+ Object[] params = getParamsArray( typeClass, operands );
+ Object result = m.invoke( c, params );
+ return ( Number ) result;
+ }
+ }
+ }
+ catch ( Exception e ) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Converts a string representing a data type into the actual type.
+ * @param type one of "int", "long", "float", or "double"
+ * @return one of Integer.TYPE, Long.TYPE, Float.TYPE, or Double.TYPE. If the
+ * given type is null or not one of the allowed types, Double.TYPE will be
+ * returned.
+ */
+ private Class getDataType( String type ) {
+ if ( type == null )
+ return Double.TYPE;
+ if ( type.equals( "int" ) ) {
+ return Integer.TYPE;
+ }
+ else if ( type.equals( "long" ) ) {
+ return Long.TYPE;
+ }
+ else if ( type.equals( "float" ) ) {
+ return Float.TYPE;
+ }
+ else {
+ return Double.TYPE;
+ }
+ }
+
+ /**
+ * Converts a string representing a data type into an Array.
+ * @param type one of "int", "long", "float", or "double"
+ * @param length how long to make the array
+ * @return an Array representing the data type
+ */
+ private Object getDataTypeArray( String type, int length ) {
+ if ( type == null )
+ return Array.newInstance( Double.TYPE, length );
+ if ( type.equals( "int" ) ) {
+ return Array.newInstance( Integer.TYPE, length );
+ }
+ else if ( type.equals( "long" ) ) {
+ return Array.newInstance( Long.TYPE, length );
+ }
+ else if ( type.equals( "float" ) ) {
+ return Array.newInstance( Float.TYPE, length );
+ }
+ else {
+ return Array.newInstance( Double.TYPE, length );
+ }
+ }
+
+ /**
+ * @returns the given operands as an array of the given type.
+ */
+ private Object[] getParams( Class typeClass, String[] operands ) {
+ int paramCount = operands.length;
+ Object[] params = new Object[ paramCount ];
+ if ( typeClass == Double.TYPE ) {
+ for ( int i = 0; i < paramCount; i++ ) {
+ params[ i ] = new Double( operands[ i ] );
+ }
+ }
+ else if ( typeClass == Long.TYPE ) {
+ for ( int i = 0; i < paramCount; i++ ) {
+ params[ i ] = new Long( operands[ i ] );
+ }
+ }
+ else if ( typeClass == Float.TYPE ) {
+ for ( int i = 0; i < paramCount; i++ ) {
+ params[ i ] = new Float( operands[ i ] );
+ }
+ }
+ else {
+ // Integer.TYPE is only other choice
+ for ( int i = 0; i < paramCount; i++ ) {
+ params[ i ] = new Integer( operands[ i ] );
+ }
+ }
+ if ( paramCount > 2 )
+ params = new Object[] {params};
+ return params;
+ }
+
+ /**
+ * Converts the given operands into an array of the given type.
+ */
+ private Object[] getParamsArray( Class typeClass, String[] operands ) {
+ int paramCount = operands.length;
+ if ( typeClass == Double.TYPE ) {
+ double[] array = ( double[] ) Array.newInstance( typeClass, operands.length );
+ for ( int i = 0; i < paramCount; i++ ) {
+ Array.setDouble( array, i, new Double( operands[ i ] ).doubleValue() );
+ }
+ return new Object[] {array};
+ }
+ else if ( typeClass == Long.TYPE ) {
+ long[] array = ( long[] ) Array.newInstance( typeClass, operands.length );
+ for ( int i = 0; i < paramCount; i++ ) {
+ Array.setLong( array, i, new Long( operands[ i ] ).longValue() );
+ }
+ return new Object[] {array};
+ }
+ else if ( typeClass == Float.TYPE ) {
+ float[] array = ( float[] ) Array.newInstance( typeClass, operands.length );
+ for ( int i = 0; i < paramCount; i++ ) {
+ Array.setFloat( array, i, new Float( operands[ i ] ).floatValue() );
+ }
+ return new Object[] {array};
+ }
+ else {
+ // Integer.TYPE is only other choice
+ Object array = Array.newInstance( typeClass, operands.length );
+ for ( int i = 0; i < paramCount; i++ ) {
+ Array.setInt( array, i, new Integer( operands[ i ] ).intValue() );
+ }
+ return new Object[] {array};
+ }
+ }
+
+ public static void main ( String[] args ) {
+ Math math = new Math();
+ System.out.println( math.calculate( "add", new String[] {"6", "5", "4"} ) );
+ }
+}
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/MathTask.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/MathTask.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/MathTask.java (revision 15058)
@@ -0,0 +1,194 @@
+/*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Ant", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+*
");
+
+ int i = 1;
+ for (; i < msgs.length; i++) {
+ Grep grep = new Grep();
+ grep.setIn(msgs[i]);
+ grep.setRegex("(.*?[:].*?[:].*?)[:].*?");
+ grep.setGroup(1);
+ String start = grep.grep();
+ if (start == null) {
+ continue;
+ }
+ SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z");
+ try {
+ Date start_date = sdf.parse(start);
+ if (start_date.getTime() < end_time)
+ break;
+ }
+ catch(Exception e) {
+ e.printStackTrace();
+ continue;
+ }
+ }
+
+ // build a string out of the appropriate pieces
+ StringBuffer sb = new StringBuffer();
+ for (int j = 1; j < i; j++) {
+ sb.append(msgs[j]).append("\n");
+ }
+
+ // set the property with the log contents
+ getProject().setProperty(property, sb.toString());
+ }
+
+ Unset unset = new Unset();
+ unset.setProject(getProject());
+ unset.setName(temp_property);
+ unset.execute();
+ }
+ catch(Exception e) {
+ e.printStackTrace();
+ throw new BuildException(e.getMessage());
+ }
+ }
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Repeat.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Repeat.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/Repeat.java (revision 15058)
@@ -0,0 +1,326 @@
+
+/*
+* Copyright (c) 2001-2004 Ant-Contrib project. All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package ise.antelope.tasks;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import ise.library.PrivilegedAccessor;
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+import ise.antelope.tasks.typedefs.TimeUnit;
+
+/**
+ * Repeatedly executes a set of tasks. Borrowed most of the code from the Limit
+ * task.
+ *
+ * @author Dale Anson
+ * @version $Revision: 1.3 $
+ * @since Ant 1.5
+ */
+public class Repeat extends Task implements TaskContainer {
+
+ // storage for nested tasks
+ private Vector tasks = new Vector();
+
+ // time units, default value is 10 seconds.
+ private long repeatInterval = 10;
+ protected TimeUnit unit = TimeUnit.SECOND_UNIT;
+
+ // property to set if time limit is reached
+ private String timeoutProperty = null;
+ private String timeoutValue = "true";
+
+ // should the build fail if any subtasks fail? Default is no.
+ private boolean failOnError = false;
+
+ private int repeatCount = 1;
+
+ private BooleanConditionTask condition = null;
+
+ /**
+ * Add a task to repeat.
+ *
+ * @param task A task to execute
+ * @exception BuildException won't happen
+ */
+ public void addTask(Task task) throws BuildException {
+ tasks.addElement(task);
+ }
+
+ /**
+ * "until" is the same as a "bool" as used in assert and if. If used, this
+ * task will repeat until either this condition is met or the maximum number
+ * of repetitions has been met, whichever is first.
+ *
+ * @param c The feature to be added to the Until attribute
+ * @exception BuildException Description of Exception
+ */
+ public void addUntil(BooleanConditionTask c) throws BuildException {
+ if (condition == null)
+ condition = c;
+ else
+ throw new BuildException("Can only add one condition.");
+ }
+
+
+ /**
+ * How long to wait between repeating the nested tasks, default is 10 sec.
+ *
+ * @param wait time between repeats
+ */
+ public void setInterval(int wait) {
+ repeatInterval = wait;
+ }
+
+ /**
+ * Sets the unit for the time between repeats. Default is seconds.
+ *
+ * @param unit valid values are "millisecond", "second", "minute", "hour",
+ * "day", and "week".
+ */
+ public void setUnit(String unit) {
+ if (unit == null)
+ return;
+ if (unit.equals(TimeUnit.SECOND)) {
+ setRepeatunit(TimeUnit.SECOND_UNIT);
+ return;
+ }
+ if (unit.equals(TimeUnit.MILLISECOND)) {
+ setRepeatunit(TimeUnit.MILLISECOND_UNIT);
+ return;
+ }
+ if (unit.equals(TimeUnit.MINUTE)) {
+ setRepeatunit(TimeUnit.MINUTE_UNIT);
+ return;
+ }
+ if (unit.equals(TimeUnit.HOUR)) {
+ setRepeatunit(TimeUnit.HOUR_UNIT);
+ return;
+ }
+ if (unit.equals(TimeUnit.DAY)) {
+ setRepeatunit(TimeUnit.DAY_UNIT);
+ return;
+ }
+ if (unit.equals(TimeUnit.WEEK)) {
+ setRepeatunit(TimeUnit.WEEK_UNIT);
+ return;
+ }
+
+ }
+
+ /**
+ * Set a number of milliseconds between repeats.
+ *
+ * @param value the number of milliseconds between repeats.
+ */
+ public void setMilliseconds(int value) {
+ setInterval(value);
+ setRepeatunit(TimeUnit.MILLISECOND_UNIT);
+ }
+
+ /**
+ * Set a number of seconds between repeats.
+ *
+ * @param value the number of seconds to wait.
+ */
+ public void setSeconds(int value) {
+ setInterval(value);
+ setRepeatunit(TimeUnit.SECOND_UNIT);
+ }
+
+ /**
+ * Set a number of minutes between repeats.
+ *
+ * @param value the number of milliseconds to wait.
+ */
+ public void setMinutes(int value) {
+ setInterval(value);
+ setRepeatunit(TimeUnit.MINUTE_UNIT);
+ }
+
+ /**
+ * Set a number of hours between repeats.
+ *
+ * @param value the number of hours to wait.
+ */
+ public void setHours(int value) {
+ setInterval(value);
+ setRepeatunit(TimeUnit.HOUR_UNIT);
+ }
+
+ /**
+ * Set a number of days between repeats.
+ *
+ * @param value the number of days to wait.
+ */
+ public void setDays(int value) {
+ setInterval(value);
+ setRepeatunit(TimeUnit.DAY_UNIT);
+ }
+
+ /**
+ * Set a number of weeks between repeats.
+ *
+ * @param value the number of weeks to wait.
+ */
+ public void setWeeks(int value) {
+ setInterval(value);
+ setRepeatunit(TimeUnit.WEEK_UNIT);
+ }
+
+ /**
+ * Set the max wait time unit, default is minutes.
+ *
+ * @param unit The new repeatUnit value
+ */
+ public void setRepeatunit(TimeUnit unit) {
+ this.unit = unit;
+ }
+
+
+ /**
+ * Determines whether the build should fail if the time limit has expired on
+ * this task. Default is no.
+ *
+ * @param fail if true, fail the build if the time limit has been reached.
+ */
+ public void setFailonerror(boolean fail) {
+ failOnError = fail;
+ }
+
+
+
+ /**
+ * Name the property to set after all repeats are complete.
+ *
+ * @param p name of property
+ */
+ public void setProperty(String p) {
+ timeoutProperty = p;
+ }
+
+
+ /**
+ * The value for the property to set after all repeats are complete,
+ * defaults to true.
+ *
+ * @param v value for the property
+ */
+ public void setValue(String v) {
+ timeoutValue = v;
+ }
+
+ /**
+ * Sets the number of times to repeat, default is 1. Use -1 to repeat
+ * forever.
+ *
+ * @param count The new repeatCount value
+ */
+ public void setCount(int count) {
+ repeatCount = count;
+ }
+
+
+ /**
+ * Execute all nested tasks, repeating.
+ *
+ * @exception BuildException Description of the Exception
+ */
+ public void execute() throws BuildException {
+ try {
+ long repeat_interval = repeatInterval * unit.getMultiplier();
+ if (repeat_interval <= 0) {
+ log("Interval is set to 0, will only execute tasks 1 time.");
+ repeatCount = 1;
+ }
+
+ if (repeatCount >= 1) {
+ for (int i = 0; i < repeatCount; i++) {
+ repeatTasks();
+ if (condition != null && condition.eval()) {
+ break;
+ }
+ if (i + 1 < repeatCount)
+ Thread.currentThread().sleep(repeat_interval);
+ }
+ }
+ else if (repeatCount == -1) {
+ while (true) {
+ repeatTasks();
+ if (condition != null && condition.eval())
+ break;
+ Thread.currentThread().sleep(repeat_interval);
+ }
+ }
+ else if (repeatCount != 0 && repeat_interval == 0) {
+ repeatTasks();
+ }
+ else {
+ // do nothing. To get here, either the repeatCount must be 0, so
+ // don't execute any of the nested tasks, or the repeat_interval
+ // must be less than 0, which is invalid.
+ }
+
+ if (timeoutProperty != null) {
+ if (timeoutValue == null)
+ timeoutValue = "true";
+ getProject().setUserProperty(timeoutProperty, timeoutValue);
+ }
+ }
+ catch (InterruptedException ie) {
+ throw new BuildException(ie.getMessage());
+ }
+ }
+
+ /**
+ * Description of the Method
+ *
+ * @exception BuildException Description of Exception
+ */
+ private void repeatTasks() throws BuildException {
+ try {
+ // executing nested tasks
+ for (int i = 0; i < tasks.size(); i++) {
+ Task currentTask = (Task) tasks.get(i);
+ try {
+ currentTask.perform();
+ }
+ catch (Exception ex) {
+ if (failOnError) {
+ throw ex;
+ }
+ }
+ }
+ }
+ catch (Exception e) {
+ if (failOnError) {
+ throw new BuildException(e.getMessage());
+ }
+ else {
+ log(e.getMessage());
+ }
+ }
+ }
+
+}
+
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/SplitTask.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/SplitTask.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/SplitTask.java (revision 15058)
@@ -0,0 +1,368 @@
+
+package ise.antelope.tasks;
+
+import java.io.*;
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+
+/**
+ * This task is similar to the Unix/Linux split utility, it splits a file into
+ * a number of smaller pieces. It will also split a property value or a string.
+ *
+ * @author Dale Anson
+ * @version $Revision: 1.3 $
+ * @since Ant 1.6
+ */
+public class SplitTask extends Task {
+
+ private String prefix = "x";
+ private int bytes = -1;
+ private int lines = 1000;
+ private String value = null;
+ private File file = null;
+ private File outputDir = null;
+ private boolean failOnError = true;
+
+ /**
+ * Buffer size for read and write operations, default is 1 MB, but this is
+ * a user setting.
+ */
+ public int BUFFER_SIZE = 1024 * 1024;
+
+
+ /**
+ * The start of the file names to write. Files are named using this string,
+ * followed by a "." and a number, e.g. x.0, x.1, etc. The Unix/Linux split
+ * uses a letter scheme for the suffix, that is not supported here.
+ *
+ * Should the dot go away? If the user wants a dot, it could be part of this
+ * attribute. Right now, the dot is there, and there is no way for the user
+ * to make it go away.
+ *
+ * @param x The new prefix value
+ */
+ public void setPrefix( String x ) {
+ prefix = x;
+ }
+
+ /**
+ * Set the number of bytes per part. This is not a required parameter,
+ * the default is to use lines rather than bytes.
+ *
+ * Use bytes or lines, not both. In general, use bytes or size for binary
+ * files, lines for text files.
+ *
+ * @param b number of bytes per part.
+ */
+ public void setBytes( int b ) {
+ bytes = b;
+ lines = -1;
+ }
+
+ /**
+ * The linux split command allows modifiers: b for 512, k for 1K, m for 1
+ * Meg. Use this method for a similar effect. This is not a required
+ * parameter, the default is to use lines rather than size.
+ *
+ * Use bytes or lines, not both. In general, use bytes or size for binary
+ * files, lines for text files.
+ *
+ * @param b the number of bytes per part, with an optional modifier. If
+ * there is no modifier, treat same as setBytes(int). For example,
+ * setSize("100k") is the same as setBytes(100 * 1024). Note that the
+ * maximum size must be smaller than Integer.MAX_VALUE (2147483647).
+ */
+ public void setSize( String b ) {
+ try {
+ int size = calcSize(b);;
+ setBytes( size );
+ }
+ catch ( NumberFormatException e ) {
+ throw new BuildException( "Invalid size parameter: " + b );
+ }
+ }
+
+
+ /**
+ * Set how much memory to use as an internal buffer. The default internal
+ * buffer size is 1 MB.
+ *
+ * @param b the number of bytes per part, with an optional modifier. If
+ * there is no modifier, treat same as setBytes(int). For example,
+ * setSize("100k") is the same as setBytes(100 * 1024). Note that the
+ * maximum size must be smaller than Integer.MAX_VALUE (2147483647).
+ */
+ public void setBuffersize(String b) {
+ try {
+ int size = calcSize(b);;
+ BUFFER_SIZE = size;
+ }
+ catch ( NumberFormatException e ) {
+ throw new BuildException( "Invalid buffer size parameter: " + b );
+ }
+ }
+
+ /**
+ * Set the number of lines per part, default is 1000. This is not a required
+ * parameter, but is the default setting for splitting.
+ *
+ * Use bytes or lines, not both. In general, use bytes or size for binary
+ * files, lines for text files.
+ *
+ * @param x The number of lines per part.
+ */
+ public void setLines( int x ) {
+ lines = x;
+ bytes = -1;
+ }
+
+ /**
+ * Split the text value of the given property.
+ *
+ * One of property, value, or file are required.
+ *
+ * @param p the name of the property whose value will be split.
+ */
+ public void setProperty( String p ) {
+ String v = getProject().getProperty( p );
+ if ( v == null || v.equals( "" ) )
+ throw new BuildException( "Property " + p + " has no value." );
+ setValue( v );
+ }
+
+ /**
+ * Split the given string.
+ *
+ * One of property, value, or file are required.
+ *
+ * @param v a string
+ */
+ public void setValue( String v ) {
+ if ( v == null || v.equals( "" ) )
+ throw new BuildException( "Value is null or empty." );
+ value = v;
+ }
+
+ /**
+ * Split the contents of the given file.
+ *
+ * One of property, value, or file are required.
+ *
+ * @param f the name of the file
+ */
+ public void setFile( File f ) {
+ file = f;
+ }
+
+ /**
+ * Where to put the parts. If file has been set and output directory has not
+ * been set, output to directory containing file.
+ *
+ * @param d the output directory
+ */
+ public void setOutputdir( File d ) {
+ outputDir = d;
+ }
+
+ /**
+ * Determines whether the build should fail if there is an error. Default is
+ * true.
+ *
+ * @param fail true or false
+ */
+ public void setFailonerror( boolean fail ) {
+ failOnError = fail;
+ }
+
+
+ /**
+ * Split the given property, value, or file into pieces.
+ *
+ * @exception BuildException only if failOnError is true
+ */
+ public void execute() throws BuildException {
+ // check params --
+ // must have value or file
+ if ( value == null && file == null )
+ throw new BuildException( "Must have property, value, or file." );
+ // if no file, must have outputDir
+ if ( file == null && outputDir == null )
+ throw new BuildException( "Must have output directory." );
+ // must have only one of value or file
+ if ( value != null && file != null )
+ throw new BuildException( "Must not have more than one of property, value, or file." );
+
+ try {
+ if ( value != null )
+ splitValue();
+ else
+ splitFile();
+ }
+ catch ( Exception e ) {
+ if ( failOnError )
+ throw new BuildException( e.getMessage() );
+ else
+ log( e.getMessage() );
+ }
+ }
+
+ /**
+ * Split a string value into several files. Since the length of a String
+ * can be no more than Integer.MAX_VALUE, no special handling of the split
+ * sizes is required.
+ *
+ * @exception IOException if there is an i/o problem
+ */
+ private void splitValue() throws Exception {
+ if ( !outputDir.exists() && !outputDir.mkdirs() ) {
+ throw new IOException( "Unable to create output directory." );
+ }
+
+ StringReader reader = new StringReader( value );
+ int bytes_read = 0;
+ int suffix = 0;
+ if ( bytes > 0 ) {
+ // make files all the same number of bytes
+ char[] buffer = new char[ bytes ];
+ while ( bytes_read > -1 ) {
+ bytes_read = reader.read( buffer, 0, bytes );
+ if ( bytes_read == -1 )
+ break;
+ FileWriter fw = new FileWriter( new File( outputDir, prefix + "." + String.valueOf( suffix ) ) );
+ fw.write( buffer, 0, bytes_read );
+ fw.flush();
+ fw.close();
+ ++suffix;
+ }
+ }
+ else {
+ // make files all the same number of lines
+ splitByLines( reader );
+ }
+ }
+
+ /**
+ * Split a file into several files. Need some special handling here since
+ * a file could be larger than Integer.MAX_VALUE, in fact, a file can be at
+ * most Long.MAX_VALUE.
+ *
+ * @exception IOException if there is an i/o problem
+ */
+ private void splitFile() throws IOException {
+ if ( !file.exists() )
+ throw new FileNotFoundException( file.toString() );
+ if ( file.length() == 0 )
+ throw new BuildException( "Zero length file." );
+ if ( outputDir == null )
+ outputDir = file.getParentFile();
+ if ( !outputDir.exists() && !outputDir.mkdirs() ) {
+ throw new IOException( "Unable to create output directory." );
+ }
+
+ if ( bytes > 0 ) {
+ int suffix = 0;
+ int num_parts = ( int ) ( file.length() / ( long ) bytes );
+ int last_part_size = ( int ) ( file.length() % ( long ) bytes );
+ boolean one_more = last_part_size > 0;
+ BufferedInputStream bis = new BufferedInputStream( new FileInputStream( file ) );
+ for ( int i = 0; i < num_parts; i++ ) {
+ // make files all the same number of bytes
+ FileOutputStream fos = new FileOutputStream( new File( outputDir, prefix + "." + String.valueOf( suffix ) ) );
+ copyToStream( bis, fos, bytes );
+ fos.flush();
+ fos.close();
+ ++suffix;
+ }
+ if ( one_more ) {
+ FileOutputStream fos = new FileOutputStream( new File( outputDir, prefix + "." + String.valueOf( suffix ) ) );
+ copyToStream( bis, fos, last_part_size );
+ fos.flush();
+ fos.close();
+ }
+ bis.close();
+ }
+ else {
+ // make files all the same number of lines
+ splitByLines( new FileReader( file ) );
+ }
+ }
+
+ private void splitByLines( Reader reader ) throws IOException {
+ int suffix = 0;
+ LineNumberReader lnr = new LineNumberReader( reader );
+ String line = lnr.readLine();
+ BufferedWriter writer = new BufferedWriter( new FileWriter( new File( outputDir, prefix + "." + String.valueOf( suffix ) ) ) );
+ while ( line != null ) {
+ writer.write( line );
+ writer.newLine();
+ if ( lnr.getLineNumber() % lines == 0 ) {
+ writer.flush();
+ writer.close();
+ ++suffix;
+ writer = new BufferedWriter( new FileWriter( new File( outputDir, prefix + "." + String.valueOf( suffix ) ) ) );
+ }
+ line = lnr.readLine();
+ }
+ writer.flush();
+ writer.close();
+ }
+
+ private int calcSize(String b) throws NumberFormatException {
+ if ( b == null || b.length() == 0 )
+ return 0;
+ b = b.toLowerCase();
+ String modifier = b.substring( b.length() - 1 );
+ int multiplier = 1;
+ b = b.substring( 0, b.length() - 1 );
+ if ( modifier.equals( "b" ) ) {
+ multiplier = 512;
+ }
+ else if ( modifier.equals( "k" ) ) {
+ multiplier = 1024;
+ }
+ else if ( modifier.equals( "m" ) ) {
+ multiplier = 1024 * 1024;
+ }
+ else {
+ // modifier is not recognized, so put it back, maybe it's a number
+ b = b + modifier;
+ }
+ int size = Integer.parseInt( b ) * multiplier;
+ if (size <= 0) {
+ throw new NumberFormatException();
+ }
+ return size;
+ }
+
+
+ /**
+ * Copies a stream to another stream.
+ *
+ * @param from stream to copy from
+ * @param to file to write
+ * @param size number of bytes to copy from 'from' to 'to'
+ * @return actual number of bytes copied from 'from' to 'to'
+ * @exception IOException on any file error
+ */
+ private int copyToStream( InputStream from, OutputStream to, int size ) throws IOException {
+ int buffer_size = BUFFER_SIZE;
+ if ( size <= BUFFER_SIZE ) {
+ buffer_size = size;
+ }
+ byte[] buffer = new byte[ Math.min( BUFFER_SIZE, size ) ];
+ int bytes_read;
+ int total = 0;
+ int offset = 0;
+ while ( total < size ) {
+ bytes_read = from.read( buffer, 0, Math.min( buffer_size, size - offset ) );
+ if ( bytes_read == -1 )
+ break;
+ to.write( buffer, 0, bytes_read );
+ total += bytes_read;
+ offset += bytes_read;
+ }
+ to.flush();
+ return total;
+ }
+}
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/StopWatch.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/StopWatch.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/StopWatch.java (revision 15058)
@@ -0,0 +1,230 @@
+/*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2000-2002 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Ant", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+*
+ * StopWatch sw = new StopWatch(); // automatically starts
+ * // do something here...
+ * sw.stop();
+ * System.out.println(sw.toString()); // print the total
+ * sw.start(); // restart the stopwatch
+ * // do some more things...
+ * sw.stop();
+ * System.out.println(sw.format(sw.elapsed()); // print the time since the last start
+ * System.out.println(sw.toString()); // print the cumulative total
+ *
+ *
+ * @author Dale Anson
+ * @version $Revision: 1.2 $
+ */
+public class StopWatch {
+
+ /** an identifying name for this stopwatch */
+ private String name = "";
+
+ /** storage for start time */
+ private long startTime = 0;
+
+ /** storage for stop time */
+ private long stopTime = 0;
+
+ /** cumulative elapsed time */
+ private long totalTime = 0;
+
+ /** is the stopwatch running? */
+ private boolean running = false;
+
+ /**
+ * Starts the stopwatch.
+ */
+ public StopWatch() {
+ this( "" );
+ }
+
+ /**
+ * Starts the stopwatch.
+ * @param name an identifying name for this StopWatch
+ */
+ public StopWatch( String name ) {
+ this.name = name;
+ start();
+ }
+
+ /**
+ * Starts/restarts the stopwatch. stop
must be called prior
+ * to restart.
+ *
+ * @return the start time, the long returned System.currentTimeMillis().
+ */
+ public long start() {
+ if ( !running )
+ startTime = System.currentTimeMillis();
+ running = true;
+ return startTime;
+ }
+
+ /**
+ * Stops the stopwatch.
+ *
+ * @return the stop time, the long returned System.currentTimeMillis().
+ */
+ public long stop() {
+ stopTime = System.currentTimeMillis();
+ if ( running ) {
+ totalTime += stopTime - startTime;
+ }
+ startTime = stopTime;
+ running = false;
+ return stopTime;
+ }
+
+ /**
+ * Total cumulative elapsed time, stops the stopwatch.
+ *
+ * @return the total time
+ */
+ public long total() {
+ stop();
+ long rtn = totalTime;
+ totalTime = 0;
+ return rtn;
+ }
+
+ /**
+ * Elapsed time, difference between the last start time and now.
+ *
+ * @return the elapsed time
+ */
+ public long elapsed() {
+ return System.currentTimeMillis() - startTime;
+ }
+
+ /**
+ * @return the name of this StopWatch
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Formats the given time into decimal seconds.
+ * @return the time formatted as mm:ss.ddd
+ */
+ public String format( long ms ) {
+ String total = String.valueOf( ms );
+ String frontpad = "000";
+ int pad_length = 3 - total.length();
+ if ( pad_length >= 0 )
+ total = "0." + frontpad.substring( 0, pad_length ) + total;
+ else {
+ String dec = total.substring( total.length() - 3 );
+ total = "";
+ int min = 0, sec = 0;
+ min = ( int ) ( ms / 60000 );
+ sec = min > 0 ? ( int ) ( ( ms - ( min * 60000 ) ) / 1000 ) : ( int ) ( ms / 1000 );
+ if ( min > 0 ) {
+ total = String.valueOf( min ) + ":" + ( sec < 10 ? "0" : "" ) + String.valueOf( sec ) + "." + dec;
+ }
+ else {
+ total = String.valueOf( sec ) + "." + dec;
+ }
+ }
+ return total + " sec";
+ }
+
+ /**
+ * Returns the total elapsed time of the stopwatch formatted in decimal seconds.
+ * @return [name: mm:ss.ddd]
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append( "[" );
+ if ( name != null )
+ sb.append( name ).append( ": " );
+ sb.append( format( totalTime ) );
+ sb.append( "]" );
+ return sb.toString();
+ }
+
+ public static void main ( String[] args ) {
+ StopWatch sw = new StopWatch( "test" );
+
+ // test the formatter
+ System.out.println( sw.format( 1 ) );
+ System.out.println( sw.format( 10 ) );
+ System.out.println( sw.format( 100 ) );
+ System.out.println( sw.format( 1000 ) );
+ System.out.println( sw.format( 100000 ) );
+ System.out.println( sw.format( 1000000 ) );
+
+ // test the stopwatch
+ try {
+ System.out.println( "StopWatch: " + sw.getName() );
+ Thread.currentThread().sleep( 2000 );
+ sw.stop();
+ System.out.println( sw.toString() );
+ sw.start();
+ Thread.currentThread().sleep( 2000 );
+ sw.stop();
+ System.out.println( "elapsed: " + sw.format( sw.elapsed() ) );
+ System.out.println( "total: " + sw.format( sw.total() ) );
+ }
+ catch ( Exception e ) {
+ e.printStackTrace();
+ }
+ }
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/StopWatchTask.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/StopWatchTask.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/StopWatchTask.java (revision 15058)
@@ -0,0 +1,149 @@
+/*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Ant", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+* setFile
method, calls a
+ * 'setUp' target in that build file (if it exists), then all targets whose
+ * names start with 'test', and last calls a target named 'tearDown' (if it
+ * exists). Both 'setUp' and 'tearDown' are optional targets in the build file.
+ * setName
. If the
+ * name has not be explicitly set, then the test name is the project
+ * name if there is one, otherwise, the filename of the test file.
+ */
+ public String getName() {
+ return test_name;
+ }
+
+ /**
+ * Set the name for this testcase.
+ *
+ * @param n the name for the testcase
+ */
+ public void setName(String n) {
+ test_name = n;
+ }
+
+ /**
+ * @param b if true, execute the test. This is handy for enabling or
+ * disabling groups of tests in a 'suite' by setting a single property.
+ * Optional, default is true, the test should run.
+ */
+ public void setEnabled(boolean b) {
+ enabled = b;
+ }
+
+ /** Run tests. */
+ public void execute() {
+
+ /*
+ Hashtable parent_targets = getProject().getTargets();
+
+ for (Iterator it = parent_targets.keySet().iterator(); it.hasNext(); ) {
+ log(it.next());
+ }
+ */
+
+ if (!enabled)
+ return;
+
+ // check the test file
+ if (testFile == null)
+ throw ProjectHelper.addLocationToBuildException(new BuildException("missing file for testcase"), getLocation());
+ if (!testFile.exists())
+ throw ProjectHelper.addLocationToBuildException(new BuildException("file not found for testcase: " + testFile), getLocation());
+
+ // make sure asserts are enabled
+ String ae = assertEnabled ? "true" : "false";
+ if (assertEnabled)
+ getProject().setProperty("ant.enable.asserts", ae);
+
+ // create a new project, similar to the "ant" task, but not nearly as involved.
+ // All properties will be copied from the parent project to the subproject, and
+ // any properties set during execution of the subproject will be copied back to
+ // the parent project.
+ Project myProject = new Project();
+ initializeProject(myProject);
+ try {
+ ProjectHelper.configureProject(myProject, testFile);
+ }
+ catch (BuildException be) {
+ throw ProjectHelper.addLocationToBuildException(be, getLocation());
+ }
+
+ // set the test name, use a name that was set as an attribute first,
+ // otherwise, use the project name, and if all else fails, use the name
+ // of the test file
+ if (test_name == null || test_name.equals(""))
+ test_name = myProject.getName();
+ if (test_name == null || test_name.equals(""))
+ test_name = testFile.getName();
+
+ if (showOutput) {
+ // output start of test
+ log(MessageBox.box("Starting test: " + test_name));
+ }
+
+ // get the setUp, tearDown, and test targets
+ Hashtable targets = myProject.getTargets();
+ Enumeration en = targets.keys();
+ while (en.hasMoreElements()) {
+ String target = (String) en.nextElement();
+ if (target.equals("setUp"))
+ setUp = (Target) targets.get(target);
+ else if (target.equals("tearDown"))
+ tearDown = (Target) targets.get(target);
+ else if (target.startsWith("test"))
+ testTargets.addElement(targets.get(target));
+ // also check for imported targets. Imported targets are named like
+ // projectname.targetname, so check for whatever follows the last dot.
+ // This is somewhat naive, as there is no restriction using dots in
+ // target names, so a target named "build.testimonials" would be treated
+ // as a test target.
+ else if (target.lastIndexOf(".") > 0 && target.substring(target.lastIndexOf(".") + 1).startsWith("test")) {
+ testTargets.addElement(targets.get(target));
+ }
+ }
+
+ // run the setUp target
+ if (setUp != null)
+ setUp.execute();
+
+ // run the test targets
+ StringBuffer messages = new StringBuffer();
+ en = testTargets.elements();
+ while (en.hasMoreElements()) {
+ Target target = (Target) en.nextElement();
+ try {
+ myProject.executeTarget(target.getName());
+ if (showOutput)
+ log(target.getName() + " passed.");
+ ++tests_passed;
+ }
+ catch (Exception e) {
+ String error = "ERROR: ";
+ if (e instanceof AssertException) {
+ int level = ((AssertException)e).getLevel();
+ if (level == AssertException.ERROR)
+ ++ tests_failed;
+ else if (level == AssertException.WARN) {
+ ++ tests_warning;
+ error = "WARNING: ";
+ }
+ else {
+ // info or debug level
+ if (showOutput)
+ log(target.getName() + ": " + e.getMessage());
+ continue;
+ }
+ }
+ else
+ ++tests_failed;
+ if (showOutput)
+ log(error + target.getName() + " failed: " + e.getMessage());
+ failures.addElement(error + test_name + ": " + target.getName() + " failed: " + e.getMessage());
+ if (failOnError)
+ throw new BuildException(e.getMessage());
+ }
+ }
+
+ // run the tearDown target
+ if (tearDown != null)
+ tearDown.execute();
+
+ // copy any new properties to parent project
+ addAlmostAll(getProject(), myProject.getProperties());
+ /*
+ Hashtable props = myProject.getProperties();
+ for (en = props.keys(); en.hasMoreElements(); ) {
+ String key = (String)en.nextElement();
+ String value = (String)props.get(key);
+ if (value != null)
+ getProject().setNewProperty(key, value);
+ }
+ */
+ // print any error messages
+ if (showSummary) {
+ log(getSummary());
+ }
+ }
+
+ /**
+ * Gets the summary attribute of the TestCase object
+ *
+ * @return The summary value
+ */
+ public String getSummary() {
+ String title = (test_name == null ? "Test" : test_name) + " Results";
+ StringBuffer msg = new StringBuffer();
+ String ls = System.getProperty("line.separator");
+ // log the failures
+ if (failures.size() > 0) {
+ String error_title = "Errors";
+ StringBuffer error_msg = new StringBuffer();
+ Enumeration en = failures.elements();
+ while (en.hasMoreElements()) {
+ error_msg.append((String) en.nextElement()).append(ls);
+ }
+ int box_width = MessageBox.getMaxWidth();
+ MessageBox.setMaxWidth(box_width - 8);
+ msg.append(MessageBox.box(error_title, error_msg));
+ MessageBox.setMaxWidth(box_width);
+ msg.append(ls);
+ }
+
+ // log the test count info
+ msg.append("Ran: ").append(getRanCount()).append(" out of ").append(getTestCaseCount()).append(" tests.").append(ls);
+ msg.append("Passed: ").append(getPassedCount()).append(ls);
+ msg.append("Warning: ").append(getWarningCount()).append(ls);
+ msg.append("Failed: ").append(getFailedCount()).append(ls);
+ return MessageBox.box(title, msg);
+ }
+
+ /**
+ * Attaches the build listeners of the current project to the new project,
+ * configures a possible logfile, transfers task and data-type definitions,
+ * transfers properties (either all or just the ones specified as user
+ * properties to the current project, depending on inheritall), transfers
+ * the input handler.
+ *
+ * @param newProject
+ */
+ private void initializeProject(Project newProject) {
+ newProject.setBaseDir(getProject().getBaseDir());
+ newProject.setInputHandler(getProject().getInputHandler());
+
+ Iterator iter = getProject().getBuildListeners().iterator();
+ while (iter.hasNext()) {
+ newProject.addBuildListener((BuildListener) iter.next());
+ }
+
+ getProject().initSubProject(newProject);
+
+ // copy properties
+ /// are these necessary? Does addAlmostAll cover these properties?
+ getProject().copyInheritedProperties(newProject);
+ getProject().copyUserProperties(newProject);
+
+ // set all properties from calling project
+ addAlmostAll(newProject, getProject().getProperties());
+
+ }
+
+ /**
+ * Copies all properties from the given table to the given project -
+ * omitting those that have already been set in the project as well as
+ * properties named basedir or ant.file.
+ *
+ * @param props properties to copy to the project
+ * @param project The feature to be added to the AlmostAll attribute
+ */
+ private void addAlmostAll(Project project, Hashtable props) {
+ Enumeration e = props.keys();
+ while (e.hasMoreElements()) {
+ String key = e.nextElement().toString();
+ if ("basedir".equals(key) || "ant.file".equals(key)) {
+ // basedir and ant.file get special treatment in execute()
+ continue;
+ }
+
+ String value = props.get(key).toString();
+ // don't re-set user properties, avoid the warning message
+ if (project.getProperty(key) == null) {
+ // no user property
+ project.setNewProperty(key, value);
+ }
+ }
+ }
+
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/TestStatisticAccumulator.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/TestStatisticAccumulator.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/TestStatisticAccumulator.java (revision 15058)
@@ -0,0 +1,13 @@
+package ise.antelope.tasks;
+
+import java.util.Enumeration;
+
+interface TestStatisticAccumulator {
+ public int getFailedCount();
+ public Enumeration getFailures();
+ public int getWarningCount();
+ public int getPassedCount();
+ public int getRanCount();
+ public String getSummary();
+ public int getTestCaseCount();
+}
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/TryTask.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/TryTask.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/TryTask.java (revision 15058)
@@ -0,0 +1,318 @@
+/*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Ant", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+*
+ * <root-tag myattr="true">
+ * <inner-tag someattr="val">Text</inner-tag>
+ * <a2><a3><a4>false</a4></a3></a2>
+ * <x>x1</x>
+ * <x>x2</x>
+ * </root-tag>
+ *
+ *
+ *
+ * root-tag(myattr)=true
+ * root-tag.inner-tag=Text
+ * root-tag.inner-tag(someattr)=val
+ * root-tag.a2.a3.a4=false
+ * root-tag.x=x1,x2
+ *
+ *
+ *
+ * root-tag.myattr=true
+ * root-tag.inner-tag=Text
+ * root-tag.inner-tag.someattr=val
+ * root-tag.a2.a3.a4=false
+ * root-tag.x=x1,x2
+ *
+ *
+ *
+ *
+ *
+ *
+ * <root-tag>
+ * <build>
+ * <build folder="build">
+ * <classes id="build.classes" location="${build.folder}/classes"/>
+ * <reference refid="build.classes"/>
+ * </build>
+ * <compile>
+ * <classpath pathid="compile.classpath">
+ * <pathelement location="${build.classes}"/>
+ * </classpath>
+ * </compile>
+ * <run-time>
+ * <jars>*.jar</jars>
+ * <classpath pathid="run-time.classpath">
+ * <path refid="compile.classpath"/>
+ * <pathelement path="${run-time.jars}"/>
+ * </classpath>
+ * </run-time>
+ * </root-tag>
+ *
+ *
+ *
+ * <property name="build" location="build"/>
+ * <property name="build.classes" location="${build.location}/classes"/>
+ * <property name="build.reference" refid="build.classes"/>
+ *
+ * <property name="run-time.jars" value="*.jar/>
+ *
+ * <classpath id="compile.classpath">
+ * <pathelement location="${build.classes}"/>
+ * </classpath>
+ *
+ * <classpath id="run-time.classpath">
+ * <path refid="compile.classpath"/>
+ * <pathelement path="${run-time.jars}"/>
+ * </classpath>
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * @ant.task name="xmlproperty" category="xml"
+ */
+
+public class XmlPropertyTask extends org.apache.tools.ant.Task {
+
+ private File src;
+ private String xml = null;
+ private String prefix = "";
+ private boolean keepRoot = true;
+ private boolean validate = false;
+ private boolean collapseAttributes = false;
+ private boolean semanticAttributes = false;
+ private boolean includeSemanticAttribute = false;
+ private File rootDirectory = null;
+ private FileUtils fileUtils = FileUtils.newFileUtils();
+ private Hashtable addedAttributes = new Hashtable();
+ private XMLCatalog xmlCatalog = new XMLCatalog();
+
+ private static final String ID = "id";
+ private static final String REF_ID = "refid";
+ private static final String LOCATION = "location";
+ private static final String VALUE = "value";
+ private static final String PATH = "path";
+ private static final String PATHID = "pathid";
+ private static final String[] ATTRIBUTES = new String[] {
+ ID, REF_ID, LOCATION, VALUE, PATH, PATHID
+ };
+
+ /**
+ * Constructor.
+ */
+ public XmlPropertyTask() {
+ super();
+ }
+
+ /**
+ * Initializes the task.
+ */
+
+ public void init() {
+ super.init();
+ xmlCatalog.setProject( getProject() );
+ }
+
+
+ /**
+ * @return the xmlCatalog as the entityresolver.
+ */
+ protected EntityResolver getEntityResolver() {
+ return xmlCatalog;
+ }
+
+ /**
+ * Run the task.
+ * @throws BuildException The exception raised during task execution.
+ * @todo validate the source file is valid before opening, print a better error message
+ * @todo add a verbose level log message listing the name of the file being loaded
+ */
+ public void execute()
+ throws BuildException {
+
+ try {
+ InputStream is = getInputStream();
+ if ( is == null ) {
+ String msg = "XmlProperty task requires a file or xml attribute";
+ throw new BuildException( msg );
+ }
+
+ log( "Loading " + ( src != null ? src.getAbsolutePath() : "xml properties" ), Project.MSG_VERBOSE );
+
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating( validate );
+ factory.setNamespaceAware( false );
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ builder.setEntityResolver( getEntityResolver() );
+ Document document = builder.parse( is );
+ Element topElement = document.getDocumentElement();
+
+ // Keep a hashtable of attributes added by this task.
+ // This task is allow to override its own properties
+ // but not other properties. So we need to keep track
+ // of which properties we've added.
+ addedAttributes = new Hashtable();
+
+ if ( keepRoot ) {
+ addNodeRecursively( topElement, prefix, null );
+ }
+ else {
+ NodeList topChildren = topElement.getChildNodes();
+ int numChildren = topChildren.getLength();
+ for ( int i = 0; i < numChildren; i++ ) {
+ addNodeRecursively( topChildren.item( i ), prefix, null );
+ }
+ }
+
+ }
+ catch ( SAXException sxe ) {
+ // Error generated during parsing
+ Exception x = sxe;
+ if ( sxe.getException() != null ) {
+ x = sxe.getException();
+ }
+ throw new BuildException( x );
+
+ }
+ catch ( ParserConfigurationException pce ) {
+ // Parser with specified options can't be built
+ throw new BuildException( pce );
+ }
+ catch ( IOException ioe ) {
+ // I/O error
+ throw new BuildException( ioe );
+ }
+ }
+
+ private InputStream getInputStream() throws IOException {
+ if ( src != null && src.exists() )
+ return new BufferedInputStream( new FileInputStream( src ) );
+ else if ( xml != null )
+ return new BufferedInputStream( new ByteArrayInputStream( xml.getBytes() ));
+ else
+ return null;
+ }
+
+ /** Iterate through all nodes in the tree. */
+ private void addNodeRecursively( Node node, String prefix,
+ Object container ) {
+
+ // Set the prefix for this node to include its tag name.
+ String nodePrefix = prefix;
+ if ( node.getNodeType() != Node.TEXT_NODE ) {
+ if ( prefix.trim().length() > 0 ) {
+ nodePrefix += ".";
+ }
+ nodePrefix += node.getNodeName();
+ }
+
+ // Pass the container to the processing of this node,
+ Object nodeObject = processNode( node, nodePrefix, container );
+
+ // now, iterate through children.
+ if ( node.hasChildNodes() ) {
+
+ NodeList nodeChildren = node.getChildNodes();
+ int numChildren = nodeChildren.getLength();
+
+ for ( int i = 0; i < numChildren; i++ ) {
+ // For each child, pass the object added by
+ // processNode to its children -- in other word, each
+ // object can pass information along to its children.
+ addNodeRecursively( nodeChildren.item( i ), nodePrefix,
+ nodeObject );
+ }
+ }
+ }
+
+ void addNodeRecursively( org.w3c.dom.Node node, String prefix ) {
+ addNodeRecursively( node, prefix, null );
+ }
+
+ /**
+ * Process the given node, adding any required attributes from
+ * this child node alone -- but not processing any
+ * children.
+ *
+ * @param node the XML Node to parse
+ * @param prefix A string to prepend to any properties that get
+ * added by this node.
+ * @param container Optionally, an object that a parent node
+ * generated that this node might belong to. For example, this
+ * node could be within a node that generated a Path.
+ * @return the Object created by this node. Generally, this is
+ * either a String if this node resulted in setting an attribute,
+ * or a Path.
+ */
+ public Object processNode ( Node node, String prefix, Object container ) {
+
+ // Parse the attribute(s) and text of this node, adding
+ // properties for each.
+ // if the "path" attribute is specified, then return the created path
+ // which will be passed to the children of this node.
+ Object addedPath = null;
+
+ // The value of an id attribute of this node.
+ String id = null;
+
+ if ( node.hasAttributes() ) {
+
+ NamedNodeMap nodeAttributes = node.getAttributes();
+
+ // Is there an id attribute?
+ Node idNode = nodeAttributes.getNamedItem( ID );
+ id = ( semanticAttributes && idNode != null
+ ? idNode.getNodeValue() : null );
+
+ // Now, iterate through the attributes adding them.
+ for ( int i = 0; i < nodeAttributes.getLength(); i++ ) {
+
+ Node attributeNode = nodeAttributes.item( i );
+
+ if ( !semanticAttributes ) {
+ String attributeName = getAttributeName( attributeNode );
+ String attributeValue = getAttributeValue( attributeNode );
+ addProperty( prefix + attributeName, attributeValue, null );
+ }
+ else {
+
+ String nodeName = attributeNode.getNodeName();
+ String attributeValue = getAttributeValue( attributeNode );
+
+ Path containingPath = ( container != null
+ && container instanceof Path ? ( Path ) container : null );
+
+ /*
+ * The main conditional logic -- if the attribute
+ * is somehow "special" (i.e., it has known
+ * semantic meaning) then deal with it
+ * appropriately.
+ */
+ if ( nodeName.equals( ID ) ) {
+ // ID has already been found above.
+ continue;
+ }
+ else if ( containingPath != null
+ && nodeName.equals( PATH ) ) {
+ // A "path" attribute for a node within a Path object.
+ containingPath.setPath( attributeValue );
+ }
+ else if ( container instanceof Path
+ && nodeName.equals( REF_ID ) ) {
+ // A "refid" attribute for a node within a Path object.
+ containingPath.setPath( attributeValue );
+ }
+ else if ( container instanceof Path
+ && nodeName.equals( LOCATION ) ) {
+ // A "location" attribute for a node within a
+ // Path object.
+ containingPath.setLocation( resolveFile( attributeValue ) );
+ }
+ else if ( nodeName.equals( PATHID ) ) {
+ // A node identifying a new path
+ if ( container != null ) {
+ throw new BuildException( "XmlProperty does not "
+ + "support nested paths" );
+ }
+
+ addedPath = new Path( getProject() );
+ getProject().addReference( attributeValue, addedPath );
+ }
+ else {
+ // An arbitrary attribute.
+ String attributeName = getAttributeName( attributeNode );
+ addProperty( prefix + attributeName, attributeValue, id );
+ }
+ }
+ }
+ }
+
+ String nodeText = null;
+ if ( node.getNodeType() == Node.TEXT_NODE ) {
+ // For the text node, add a property.
+ nodeText = getAttributeValue( node );
+ }
+ else if ( ( node.getNodeType() == Node.ELEMENT_NODE )
+ && ( node.getChildNodes().getLength() == 1 )
+ && ( node.getFirstChild().getNodeType() == Node.CDATA_SECTION_NODE ) ) {
+
+ nodeText = node.getFirstChild().getNodeValue();
+ }
+
+ if ( nodeText != null ) {
+ // If the containing object was a String, then use it as the ID.
+ if ( semanticAttributes && id == null
+ && container instanceof String ) {
+ id = ( String ) container;
+ }
+
+ if ( nodeText.trim().length() != 0 ) {
+ addProperty( prefix, nodeText, id );
+ }
+ }
+
+ // Return the Path we added or the ID of this node for
+ // children to reference if needed. Path objects are
+ // definitely used by child path elements, and ID may be used
+ // for a child text node.
+ return ( addedPath != null ? addedPath : id );
+ }
+
+ /**
+ * Actually add the given property/value to the project
+ * after writing a log message.
+ */
+ private void addProperty ( String name, String value, String id ) {
+ String msg = name + ":" + value;
+ if ( id != null ) {
+ msg += ( "(id=" + id + ")" );
+ }
+ log( msg, Project.MSG_DEBUG );
+
+ if ( addedAttributes.containsKey( name ) ) {
+ // If this attribute was added by this task, then
+ // we append this value to the existing value.
+ // We use the setProperty method which will
+ // forcibly override the property if it already exists.
+ // We need to put these properties into the project
+ // when we read them, though (instead of keeping them
+ // outside of the project and batch adding them at the end)
+ // to allow other properties to reference them.
+ value = ( String ) addedAttributes.get( name ) + "," + value;
+ getProject().setProperty( name, value );
+ }
+ else {
+ getProject().setNewProperty( name, value );
+ }
+ addedAttributes.put( name, value );
+ if ( id != null ) {
+ getProject().addReference( id, value );
+ }
+ }
+
+ /**
+ * Return a reasonable attribute name for the given node.
+ * If we are using semantic attributes or collapsing
+ * attributes, the returned name is ".nodename".
+ * Otherwise, we return "(nodename)". This is long-standing
+ * (and default) <xmlproperty> behavior.
+ */
+ private String getAttributeName ( Node attributeNode ) {
+ String attributeName = attributeNode.getNodeName();
+
+ if ( semanticAttributes ) {
+ // Never include the "refid" attribute as part of the
+ // attribute name.
+ if ( attributeName.equals( REF_ID ) ) {
+ return "";
+ // Otherwise, return it appended unless property to hide it is set.
+ }
+ else if ( !isSemanticAttribute( attributeName )
+ || includeSemanticAttribute ) {
+ return "." + attributeName;
+ }
+ else {
+ return "";
+ }
+ }
+ else if ( collapseAttributes ) {
+ return "." + attributeName;
+ }
+ else {
+ return "(" + attributeName + ")";
+ }
+ }
+
+ /**
+ * Return whether the provided attribute name is recognized or not.
+ */
+ private static boolean isSemanticAttribute ( String attributeName ) {
+ for ( int i = 0; i < ATTRIBUTES.length; i++ ) {
+ if ( attributeName.equals( ATTRIBUTES[ i ] ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the value for the given attribute.
+ * If we are not using semantic attributes, its just the
+ * literal string value of the attribute.
+ *
+ * value
is 12 and unit
is "hours", then this
+ * condition checks that the difference between the 2 datetimes is 12 hours.
+ *
+ * @param unit valid values are "millisecond", "second", "minute", "hour",
+ * "day", "week", "month", "year".
+ */
+ public void setUnit(String unit) {
+ if (unit == null)
+ return;
+ this.unit = unit;
+ }
+
+ /**
+ * @return true if the difference between the two dates
+ * or times is the same as the expected value.
+ * @exception BuildException if the attributes are not set correctly
+ */
+ public boolean eval() throws BuildException {
+ try {
+ Date d1;
+ Date d2;
+ if (format == null)
+ throw new BuildException("format is required");
+
+ SimpleDateFormat df = new SimpleDateFormat(format);
+ df.setLenient(lenient);
+
+ if (date1 != null && date2 != null) {
+ // handle date difference
+ d1 = df.parse(date1);
+ d2 = df.parse(date2);
+ }
+ else
+ throw new BuildException("Both datetime1 and datetime2 must be set.");
+
+ Calendar cal1 = Calendar.getInstance();
+ Calendar cal2 = Calendar.getInstance();
+ cal1.setTime(d1);
+ cal2.setTime(d2);
+
+ Calendar before = cal1.before(cal2) ? cal1 : cal2;
+ Calendar after = cal1.before(cal2) ? cal2 : cal1;
+
+ int cal_unit = Calendar.DATE;
+
+ if (unit.equals(TimeUnit.SECOND)) {
+ cal_unit = Calendar.SECOND;
+ }
+ else if (unit.equals(TimeUnit.MILLISECOND)) {
+ cal_unit = Calendar.MILLISECOND;
+ }
+ else if (unit.equals(TimeUnit.MINUTE)) {
+ cal_unit = Calendar.MINUTE;
+ }
+ else if (unit.equals(TimeUnit.HOUR)) {
+ cal_unit = Calendar.HOUR;
+ }
+ else if (unit.equals(TimeUnit.DAY)) {
+ cal_unit = Calendar.DATE;
+ }
+ else if (unit.equals(TimeUnit.WEEK)) {
+ cal_unit = Calendar.WEEK_OF_YEAR;
+ }
+ else if (unit.equals(TimeUnit.MONTH)) {
+ cal_unit = Calendar.MONTH;
+ }
+ else if (unit.equals(TimeUnit.YEAR)) {
+ cal_unit = Calendar.YEAR;
+ }
+ else
+ throw new BuildException("Unknown unit: " + unit);
+
+ int count = 0;
+ while (before.before(after)) {
+ before.add(cal_unit, 1);
+ ++count;
+ }
+
+ return count == value;
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ throw new BuildException(e.getMessage());
+ }
+ }
+}
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/condition/EndsWith.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/condition/EndsWith.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/condition/EndsWith.java (revision 15058)
@@ -0,0 +1,85 @@
+/*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Ant", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+* setSeparator
or by the default delimiters
+ * for StringTokenizer. If the default delimiters for StringTokenizer are
+ * used, the returned string will be a list of comma separated values.
+ *
+ * @param s
+ * @return Description of the Returned Value
+ */
+ public String execute(String s) {
+ if (s == null)
+ return "";
+ if (separator != null && separator.length() == 0)
+ separator = null;
+ List list = new ArrayList();
+ StringTokenizer st = separator == null ? new StringTokenizer(s) : new StringTokenizer(s, separator);
+ while(st.hasMoreTokens()) {
+ list.add(st.nextToken());
+ }
+ Collections.sort(list);
+ StringBuffer sorted = new StringBuffer();
+ String sep = separator == null ? "," : separator.substring(0, 1);
+ for (Iterator it = list.iterator(); it.hasNext(); ) {
+ sorted.append((String)it.next());
+ if (it.hasNext())
+ sorted.append(sep);
+ }
+ return sorted.toString();
+ }
+}
+
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/StringOp.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/StringOp.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/StringOp.java (revision 15058)
@@ -0,0 +1,5 @@
+package ise.antelope.tasks.typedefs.string;
+
+public interface StringOp {
+ public String execute(String s);
+}
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/Substring.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/Substring.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/Substring.java (revision 15058)
@@ -0,0 +1,44 @@
+package ise.antelope.tasks.typedefs.string;
+
+/**
+ * Copyright 2003
+ *
+ * @version $Revision: 1.1 $
+ */
+public class Substring implements StringOp {
+
+ private int beginIndex = 0;
+ private int endIndex = -1;
+
+ public void setBeginindex(int i) {
+ if (i < 0)
+ throw new IllegalArgumentException("beginindex must be <= 0");
+ beginIndex = i;
+ }
+
+ public void setEndindex(int i) {
+ if (i < 0)
+ throw new IllegalArgumentException("endindex must be <= 0");
+ endIndex = i;
+ }
+ /**
+ * Description of the Method
+ *
+ * @param s
+ * @return Description of the Returned Value
+ */
+ public String execute(String s) {
+ if (s == null)
+ return "";
+ if (beginIndex == endIndex)
+ return "";
+ if (endIndex == -1)
+ endIndex = s.length();
+ if (endIndex < beginIndex)
+ throw new IllegalArgumentException("endindex must be greater than beginindex");
+ return s.substring(beginIndex, endIndex);
+
+ }
+}
+
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/Trim.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/Trim.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/Trim.java (revision 15058)
@@ -0,0 +1,20 @@
+package ise.antelope.tasks.typedefs.string;
+
+/**
+ * Copyright 2003
+ *
+ * @version $Revision: 1.1 $
+ */
+public class Trim implements StringOp {
+ /**
+ * Description of the Method
+ *
+ * @param s
+ * @return Description of the Returned Value
+ */
+ public String execute(String s) {
+ return s.trim();
+ }
+}
+
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/UpperCase.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/UpperCase.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/typedefs/string/UpperCase.java (revision 15058)
@@ -0,0 +1,21 @@
+
+package ise.antelope.tasks.typedefs.string;
+
+/**
+ * Copyright 2003
+ *
+ * @version $Revision: 1.1 $
+ */
+public class UpperCase implements StringOp {
+ /**
+ * Description of the Method
+ *
+ * @param s
+ * @return Description of the Returned Value
+ */
+ public String execute(String s) {
+ return s.toUpperCase();
+ }
+}
+
+
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/Base64.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/Base64.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/Base64.java (revision 15058)
@@ -0,0 +1,1432 @@
+
+package ise.antelope.tasks.util;
+
+/**
+ * Encodes and decodes to and from Base64 notation.
+ *
+ *
+ *
+ *
+ *
+ * GZIP: gzip-compresses object before encoding it.
+ * DONT_BREAK_LINES: don't break lines at 76 characters
+ * Note: Technically, this makes your encoding non-compliant.
+ *
+ * encodeObject( myObj, Base64.GZIP )
or
+ * encodeObject( myObj, Base64.GZIP | Base64.DONT_BREAK_LINES )
+ *
+ * @param serializableObject The object to encode
+ * @param options Specified options
+ * @return The Base64-encoded object
+ * @see Base64#GZIP
+ * @see Base64#DONT_BREAK_LINES
+ * @since 2.0
+ */
+ public static String encodeObject( java.io.Serializable serializableObject, int options ) {
+ // Streams
+ java.io.ByteArrayOutputStream baos = null;
+ java.io.OutputStream b64os = null;
+ java.io.ObjectOutputStream oos = null;
+ java.util.zip.GZIPOutputStream gzos = null;
+
+ // Isolate options
+ int gzip = ( options & GZIP );
+ int dontBreakLines = ( options & DONT_BREAK_LINES );
+
+ try {
+ // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
+ baos = new java.io.ByteArrayOutputStream();
+ b64os = new Base64.OutputStream( baos, ENCODE | dontBreakLines );
+
+ // GZip?
+ if ( gzip == GZIP ) {
+ gzos = new java.util.zip.GZIPOutputStream( b64os );
+ oos = new java.io.ObjectOutputStream( gzos );
+ } // end if: gzip
+ else
+ oos = new java.io.ObjectOutputStream( b64os );
+
+ oos.writeObject( serializableObject );
+ } // end try
+ catch ( java.io.IOException e ) {
+ e.printStackTrace();
+ return null;
+ } // end catch
+ finally {
+ try {
+ oos.close();
+ }
+ catch ( Exception e ) {}
+ try {
+ gzos.close();
+ }
+ catch ( Exception e ) {}
+ try {
+ b64os.close();
+ }
+ catch ( Exception e ) {}
+ try {
+ baos.close();
+ }
+ catch ( Exception e ) {}
+ } // end finally
+
+ // Return value according to relevant encoding.
+
+ try {
+ return new String( baos.toByteArray(), PREFERRED_ENCODING );
+ } // end try
+ catch ( java.io.UnsupportedEncodingException uue ) {
+ return new String( baos.toByteArray() );
+ } // end catch
+
+ } // end encode
+
+
+
+ /**
+ * Encodes a byte array into Base64 notation.
+ * Does not GZip-compress data.
+ *
+ * @param source The data to convert
+ * @since 1.4
+ */
+ public static String encodeBytes( byte[] source ) {
+ return encodeBytes( source, 0, source.length, NO_OPTIONS );
+ } // end encodeBytes
+
+
+
+ /**
+ * Encodes a byte array into Base64 notation.
+ *
+ * GZIP: gzip-compresses object before encoding it.
+ * DONT_BREAK_LINES: don't break lines at 76 characters
+ * Note: Technically, this makes your encoding non-compliant.
+ *
+ * encodeBytes( myData, Base64.GZIP )
or
+ * encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES )
+ *
+ *
+ * @param source The data to convert
+ * @param options Specified options
+ * @see Base64#GZIP
+ * @see Base64#DONT_BREAK_LINES
+ * @since 2.0
+ */
+ public static String encodeBytes( byte[] source, int options ) {
+ return encodeBytes( source, 0, source.length, options );
+ } // end encodeBytes
+
+
+ /**
+ * Encodes a byte array into Base64 notation.
+ * Does not GZip-compress data.
+ *
+ * @param source The data to convert
+ * @param off Offset in array where conversion should begin
+ * @param len Length of data to convert
+ * @since 1.4
+ */
+ public static String encodeBytes( byte[] source, int off, int len ) {
+ return encodeBytes( source, off, len, NO_OPTIONS );
+ } // end encodeBytes
+
+
+
+ /**
+ * Encodes a byte array into Base64 notation.
+ *
+ * GZIP: gzip-compresses object before encoding it.
+ * DONT_BREAK_LINES: don't break lines at 76 characters
+ * Note: Technically, this makes your encoding non-compliant.
+ *
+ * encodeBytes( myData, Base64.GZIP )
or
+ * encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES )
+ *
+ *
+ * @param source The data to convert
+ * @param off Offset in array where conversion should begin
+ * @param len Length of data to convert
+ * @param options Specified options
+ * @see Base64#GZIP
+ * @see Base64#DONT_BREAK_LINES
+ * @since 2.0
+ */
+ public static String encodeBytes( byte[] source, int off, int len, int options ) {
+ // Isolate options
+ int dontBreakLines = ( options & DONT_BREAK_LINES );
+ int gzip = ( options & GZIP );
+
+ // Compress?
+ if ( gzip == GZIP ) {
+ java.io.ByteArrayOutputStream baos = null;
+ java.util.zip.GZIPOutputStream gzos = null;
+ Base64.OutputStream b64os = null;
+
+
+ try {
+ // GZip -> Base64 -> ByteArray
+ baos = new java.io.ByteArrayOutputStream();
+ b64os = new Base64.OutputStream( baos, ENCODE | dontBreakLines );
+ gzos = new java.util.zip.GZIPOutputStream( b64os );
+
+ gzos.write( source, off, len );
+ gzos.close();
+ } // end try
+ catch ( java.io.IOException e ) {
+ e.printStackTrace();
+ return null;
+ } // end catch
+ finally {
+ try {
+ gzos.close();
+ }
+ catch ( Exception e ) {}
+ try {
+ b64os.close();
+ }
+ catch ( Exception e ) {}
+ try {
+ baos.close();
+ }
+ catch ( Exception e ) {}
+ } // end finally
+
+ // Return value according to relevant encoding.
+
+ try {
+ return new String( baos.toByteArray(), PREFERRED_ENCODING );
+ } // end try
+ catch ( java.io.UnsupportedEncodingException uue ) {
+ return new String( baos.toByteArray() );
+ } // end catch
+ } // end if: compress
+
+ // Else, don't compress. Better not to use streams at all then.
+
+ else {
+ // Convert option to boolean in way that code likes it.
+ boolean breakLines = dontBreakLines == 0;
+
+ int len43 = len * 4 / 3;
+ byte[] outBuff = new byte[ ( len43 ) // Main 4:3
+ + ( ( len % 3 ) > 0 ? 4 : 0 ) // Account for padding
+ + ( breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0 ) ]; // New lines
+ int d = 0;
+ int e = 0;
+ int len2 = len - 2;
+ int lineLength = 0;
+ for ( ; d < len2; d += 3, e += 4 ) {
+ encode3to4( source, d + off, 3, outBuff, e );
+
+ lineLength += 4;
+ if ( breakLines && lineLength == MAX_LINE_LENGTH ) {
+ outBuff[ e + 4 ] = NEW_LINE;
+ e++;
+ lineLength = 0;
+ } // end if: end of line
+ } // en dfor: each piece of array
+
+
+ if ( d < len ) {
+ encode3to4( source, d + off, len - d, outBuff, e );
+ e += 4;
+ } // end if: some padding needed
+
+
+ // Return value according to relevant encoding.
+ try {
+ return new String( outBuff, 0, e, PREFERRED_ENCODING );
+ } // end try
+ catch ( java.io.UnsupportedEncodingException uue ) {
+ return new String( outBuff, 0, e );
+ } // end catch
+
+ } // end else: don't compress
+
+ } // end encodeBytes
+
+
+
+
+
+ /* ******** D E C O D I N G M E T H O D S ******** */
+
+
+ /**
+ * Decodes four bytes from array source
+ * and writes the resulting bytes (up to three of them)
+ * to destination.
+ * The source and destination arrays can be manipulated
+ * anywhere along their length by specifying
+ * srcOffset and destOffset.
+ * This method does not check to make sure your arrays
+ * are large enough to accomodate srcOffset + 4 for
+ * the source array or destOffset + 3 for
+ * the destination array.
+ * This method returns the actual number of bytes that
+ * were converted from the Base64 encoding.
+ *
+ *
+ * @param source the array to convert
+ * @param srcOffset the index where conversion begins
+ * @param destination the array to hold the conversion
+ * @param destOffset the index where output will be put
+ * @return the number of decoded bytes converted
+ * @since 1.3
+ */
+ private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset ) {
+ // Example: Dk==
+ if ( source[ srcOffset + 2 ] == EQUALS_SIGN ) {
+ // Two ways to do the same thing. Don't know which way I like best.
+ //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 )
+ // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 );
+ int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 )
+ | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 );
+
+ destination[ destOffset ] = ( byte ) ( outBuff >>> 16 );
+ return 1;
+ }
+
+ // Example: DkL=
+ else if ( source[ srcOffset + 3 ] == EQUALS_SIGN ) {
+ // Two ways to do the same thing. Don't know which way I like best.
+ //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 )
+ // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
+ // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 );
+ int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 )
+ | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
+ | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 );
+
+ destination[ destOffset ] = ( byte ) ( outBuff >>> 16 );
+ destination[ destOffset + 1 ] = ( byte ) ( outBuff >>> 8 );
+ return 2;
+ }
+
+ // Example: DkLE
+ else {
+ try {
+ // Two ways to do the same thing. Don't know which way I like best.
+ //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 )
+ // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
+ // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 )
+ // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 );
+ int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 )
+ | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 )
+ | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 )
+ | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) );
+
+
+ destination[ destOffset ] = ( byte ) ( outBuff >> 16 );
+ destination[ destOffset + 1 ] = ( byte ) ( outBuff >> 8 );
+ destination[ destOffset + 2 ] = ( byte ) ( outBuff );
+
+ return 3;
+ }
+ catch ( Exception e ) {
+ System.out.println( "" + source[ srcOffset ] + ": " + ( DECODABET[ source[ srcOffset ] ] ) );
+ System.out.println( "" + source[ srcOffset + 1 ] + ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) );
+ System.out.println( "" + source[ srcOffset + 2 ] + ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) );
+ System.out.println( "" + source[ srcOffset + 3 ] + ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) );
+ return -1;
+ } //e nd catch
+ }
+ } // end decodeToBytes
+
+
+
+
+ /**
+ * Very low-level access to decoding ASCII characters in
+ * the form of a byte array. Does not support automatically
+ * gunzipping or any other "fancy" features.
+ *
+ * @param source The Base64 encoded data
+ * @param off The offset of where to begin decoding
+ * @param len The length of characters to decode
+ * @return decoded data
+ * @since 1.3
+ */
+ public static byte[] decode( byte[] source, int off, int len ) {
+ int len34 = len * 3 / 4;
+ byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output
+ int outBuffPosn = 0;
+
+ byte[] b4 = new byte[ 4 ];
+ int b4Posn = 0;
+ int i = 0;
+ byte sbiCrop = 0;
+ byte sbiDecode = 0;
+ for ( i = off; i < off + len; i++ ) {
+ sbiCrop = ( byte ) ( source[ i ] & 0x7f ); // Only the low seven bits
+ sbiDecode = DECODABET[ sbiCrop ];
+
+ if ( sbiDecode >= WHITE_SPACE_ENC ) // White space, Equals sign or better
+ {
+ if ( sbiDecode >= EQUALS_SIGN_ENC ) {
+ b4[ b4Posn++ ] = sbiCrop;
+ if ( b4Posn > 3 ) {
+ outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn );
+ b4Posn = 0;
+
+ // If that was the equals sign, break out of 'for' loop
+ if ( sbiCrop == EQUALS_SIGN )
+ break;
+ } // end if: quartet built
+
+ } // end if: equals sign or better
+
+ } // end if: white space, equals sign or better
+
+ else {
+ System.err.println( "Bad Base64 input character at " + i + ": " + source[ i ] + "(decimal)" );
+ return null;
+ } // end else:
+ } // each input character
+
+
+ byte[] out = new byte[ outBuffPosn ];
+ System.arraycopy( outBuff, 0, out, 0, outBuffPosn );
+ return out;
+ } // end decode
+
+
+
+
+ /**
+ * Decodes data from Base64 notation, automatically
+ * detecting gzip-compressed data and decompressing it.
+ *
+ * @param s the string to decode
+ * @return the decoded data
+ * @since 1.4
+ */
+ public static byte[] decode( String s ) {
+ byte[] bytes;
+ try {
+ bytes = s.getBytes( PREFERRED_ENCODING );
+ } // end try
+ catch ( java.io.UnsupportedEncodingException uee ) {
+ bytes = s.getBytes();
+ } // end catch
+ //
+
+ // Decode
+ bytes = decode( bytes, 0, bytes.length );
+
+
+ // Check to see if it's gzip-compressed
+ // GZIP Magic Two-Byte Number: 0x8b1f (35615)
+ if ( bytes != null && bytes.length >= 4 ) {
+
+ int head = ( ( int ) bytes[ 0 ] & 0xff ) | ( ( bytes[ 1 ] << 8 ) & 0xff00 );
+ if ( java.util.zip.GZIPInputStream.GZIP_MAGIC == head ) {
+ java.io.ByteArrayInputStream bais = null;
+ java.util.zip.GZIPInputStream gzis = null;
+ java.io.ByteArrayOutputStream baos = null;
+ byte[] buffer = new byte[ 2048 ];
+ int length = 0;
+
+ try {
+ baos = new java.io.ByteArrayOutputStream();
+ bais = new java.io.ByteArrayInputStream( bytes );
+ gzis = new java.util.zip.GZIPInputStream( bais );
+
+ while ( ( length = gzis.read( buffer ) ) >= 0 ) {
+ baos.write( buffer, 0, length );
+ } // end while: reading input
+
+ // No error? Get new bytes.
+ bytes = baos.toByteArray();
+
+ } // end try
+ catch ( java.io.IOException e ) {
+ // Just return originally-decoded bytes
+ } // end catch
+
+ finally {
+ try {
+ baos.close();
+ }
+ catch ( Exception e ) {}
+ try {
+ gzis.close();
+ }
+ catch ( Exception e ) {}
+ try {
+ bais.close();
+ }
+ catch ( Exception e ) {}
+ } // end finally
+
+ } // end if: gzipped
+ } // end if: bytes.length >= 2
+
+
+ return bytes;
+ } // end decode
+
+
+
+
+ /**
+ * Attempts to decode Base64 data and deserialize a Java
+ * Object within. Returns null if there was an error.
+ *
+ * @param encodedObject The Base64 data to decode
+ * @return The decoded and deserialized object
+ * @since 1.5
+ */
+ public static Object decodeToObject( String encodedObject ) {
+ // Decode and gunzip if necessary
+ byte[] objBytes = decode( encodedObject );
+
+ java.io.ByteArrayInputStream bais = null;
+ java.io.ObjectInputStream ois = null;
+ Object obj = null;
+
+ try {
+ bais = new java.io.ByteArrayInputStream( objBytes );
+ ois = new java.io.ObjectInputStream( bais );
+
+ obj = ois.readObject();
+ } // end try
+ catch ( java.io.IOException e ) {
+ e.printStackTrace();
+ obj = null;
+ } // end catch
+ catch ( java.lang.ClassNotFoundException e ) {
+ e.printStackTrace();
+ obj = null;
+ } // end catch
+ finally {
+ try {
+ bais.close();
+ }
+ catch ( Exception e ) {}
+ try {
+ ois.close();
+ }
+ catch ( Exception e ) {}
+ } // end finally
+
+
+ return obj;
+ } // end decodeObject
+
+
+
+ /**
+ * Convenience method for encoding data to a file.
+ *
+ * @param dataToEncode byte array of data to encode in base64 form
+ * @param filename Filename for saving encoded data
+ * @return true if successful, false otherwise
+ *
+ * @since 2.1
+ */
+ public static boolean encodeToFile( byte[] dataToEncode, String filename ) {
+ boolean success = false;
+ Base64.OutputStream bos = null;
+ try {
+ bos = new Base64.OutputStream(
+ new java.io.FileOutputStream( filename ), Base64.ENCODE );
+ bos.write( dataToEncode );
+ success = true;
+ } // end try
+ catch ( java.io.IOException e ) {
+
+ success = false;
+ } // end catch: IOException
+ finally {
+ try {
+ bos.close();
+ }
+ catch ( Exception e ) {}
+ } // end finally
+
+
+ return success;
+ } // end encodeToFile
+
+
+ /**
+ * Convenience method for decoding data to a file.
+ *
+ * @param dataToDecode Base64-encoded data as a string
+ * @param filename Filename for saving decoded data
+ * @return true if successful, false otherwise
+ *
+ * @since 2.1
+ */
+ public static boolean decodeToFile( String dataToDecode, String filename ) {
+ boolean success = false;
+ Base64.OutputStream bos = null;
+ try {
+ bos = new Base64.OutputStream(
+ new java.io.FileOutputStream( filename ), Base64.DECODE );
+ bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) );
+ success = true;
+ } // end try
+ catch ( java.io.IOException e ) {
+ success = false;
+ } // end catch: IOException
+ finally {
+ try {
+ bos.close();
+ }
+ catch ( Exception e ) {}
+ } // end finally
+
+
+ return success;
+ } // end decodeToFile
+
+
+
+
+ /**
+ * Convenience method for reading a base64-encoded
+ * file and decoding it.
+ *
+ * @param filename Filename for reading encoded data
+ * @return decoded byte array or null if unsuccessful
+ *
+ * @since 2.1
+ */
+ public static byte[] decodeFromFile( String filename ) {
+ byte[] decodedData = null;
+ Base64.InputStream bis = null;
+ try {
+ // Set up some useful variables
+ java.io.File file = new java.io.File( filename );
+ byte[] buffer = null;
+ int length = 0;
+ int numBytes = 0;
+
+ // Check for size of file
+ if ( file.length() > Integer.MAX_VALUE ) {
+ System.err.println( "File is too big for this convenience method (" + file.length() + " bytes)." );
+ return null;
+ } // end if: file too big for int index
+ buffer = new byte[ ( int ) file.length() ];
+
+ // Open a stream
+ bis = new Base64.InputStream(
+ new java.io.BufferedInputStream(
+ new java.io.FileInputStream( file ) ), Base64.DECODE );
+
+ // Read until done
+ while ( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 )
+ length += numBytes;
+
+ // Save in a variable to return
+ decodedData = new byte[ length ];
+ System.arraycopy( buffer, 0, decodedData, 0, length );
+
+ } // end try
+ catch ( java.io.IOException e ) {
+ System.err.println( "Error decoding from file " + filename );
+ } // end catch: IOException
+ finally {
+ try {
+ bis.close();
+ }
+ catch ( Exception e ) {}
+ } // end finally
+
+
+ return decodedData;
+ } // end decodeFromFile
+
+
+
+ /**
+ * Convenience method for reading a binary file
+ * and base64-encoding it.
+ *
+ * @param filename Filename for reading binary data
+ * @return base64-encoded string or null if unsuccessful
+ *
+ * @since 2.1
+ */
+ public static String encodeFromFile( String filename ) {
+ String encodedData = null;
+ Base64.InputStream bis = null;
+ try {
+ // Set up some useful variables
+ java.io.File file = new java.io.File( filename );
+ byte[] buffer = new byte[ ( int ) ( file.length() * 1.4 ) ];
+ int length = 0;
+ int numBytes = 0;
+
+ // Open a stream
+ bis = new Base64.InputStream(
+ new java.io.BufferedInputStream(
+ new java.io.FileInputStream( file ) ), Base64.ENCODE );
+
+ // Read until done
+ while ( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 )
+ length += numBytes;
+
+ // Save in a variable to return
+ encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING );
+
+ } // end try
+ catch ( java.io.IOException e ) {
+ System.err.println( "Error encoding from file " + filename );
+ } // end catch: IOException
+ finally {
+ try {
+ bis.close();
+ }
+ catch ( Exception e ) {}
+ } // end finally
+
+
+ return encodedData;
+ } // end encodeFromFile
+
+
+
+
+ /* ******** I N N E R C L A S S I N P U T S T R E A M ******** */
+
+
+
+ /**
+ * A {@link Base64.InputStream} will read data from another
+ * java.io.InputStream, given in the constructor,
+ * and encode/decode to/from Base64 notation on the fly.
+ *
+ * @see Base64
+ * @since 1.3
+ */
+ public static class InputStream extends java.io.FilterInputStream {
+ private boolean encode; // Encoding or decoding
+ private int position; // Current position in the buffer
+ private byte[] buffer; // Small buffer holding converted data
+ private int bufferLength; // Length of buffer (3 or 4)
+ private int numSigBytes; // Number of meaningful bytes in the buffer
+ private int lineLength;
+ private boolean breakLines; // Break lines at less than 80 characters
+
+
+ /**
+ * Constructs a {@link Base64.InputStream} in DECODE mode.
+ *
+ * @param in the java.io.InputStream from which to read data.
+ * @since 1.3
+ */
+ public InputStream( java.io.InputStream in ) {
+ this( in, DECODE );
+ } // end constructor
+
+
+ /**
+ * Constructs a {@link Base64.InputStream} in
+ * either ENCODE or DECODE mode.
+ *
+ * ENCODE or DECODE: Encode or Decode as data is read.
+ * DONT_BREAK_LINES: don't break lines at 76 characters
+ * (only meaningful when encoding)
+ * Note: Technically, this makes your encoding non-compliant.
+ *
+ * new Base64.InputStream( in, Base64.DECODE )
+ *
+ *
+ * @param in the java.io.InputStream from which to read data.
+ * @param options Specified options
+ * @see Base64#ENCODE
+ * @see Base64#DECODE
+ * @see Base64#DONT_BREAK_LINES
+ * @since 2.0
+ */
+ public InputStream( java.io.InputStream in, int options ) {
+ super( in );
+ this.breakLines = ( options & DONT_BREAK_LINES ) != DONT_BREAK_LINES;
+ this.encode = ( options & ENCODE ) == ENCODE;
+ this.bufferLength = encode ? 4 : 3;
+ this.buffer = new byte[ bufferLength ];
+ this.position = -1;
+ this.lineLength = 0;
+ } // end constructor
+
+ /**
+ * Reads enough of the input stream to convert
+ * to/from Base64 and returns the next byte.
+ *
+ * @return next byte
+ * @since 1.3
+ */
+ public int read() throws java.io.IOException {
+ // Do we need to get data?
+ if ( position < 0 ) {
+ if ( encode ) {
+ byte[] b3 = new byte[ 3 ];
+ int numBinaryBytes = 0;
+ for ( int i = 0; i < 3; i++ ) {
+ try {
+ int b = in.read();
+
+ // If end of stream, b is -1.
+ if ( b >= 0 ) {
+ b3[ i ] = ( byte ) b;
+ numBinaryBytes++;
+ } // end if: not end of stream
+
+ } // end try: read
+
+ catch ( java.io.IOException e ) {
+ // Only a problem if we got no data at all.
+ if ( i == 0 )
+ throw e;
+
+ } // end catch
+ } // end for: each needed input byte
+
+
+ if ( numBinaryBytes > 0 ) {
+ encode3to4( b3, 0, numBinaryBytes, buffer, 0 );
+ position = 0;
+ numSigBytes = 4;
+ } // end if: got data
+ else {
+ return -1;
+ } // end else
+ } // end if: encoding
+
+ // Else decoding
+
+ else {
+ byte[] b4 = new byte[ 4 ];
+ int i = 0;
+ for ( i = 0; i < 4; i++ ) {
+ // Read four "meaningful" bytes:
+ int b = 0;
+ do {
+ b = in.read();
+ }
+ while ( b >= 0 && DECODABET[ b & 0x7f ] <= WHITE_SPACE_ENC );
+
+ if ( b < 0 )
+ break; // Reads a -1 if end of stream
+
+ b4[ i ] = ( byte ) b;
+ } // end for: each needed input byte
+
+ if ( i == 4 ) {
+ numSigBytes = decode4to3( b4, 0, buffer, 0 );
+ position = 0;
+ } // end if: got four characters
+ else if ( i == 0 ) {
+ return -1;
+ } // end else if: also padded correctly
+ else {
+ // Must have broken out from above.
+ throw new java.io.IOException( "Improperly padded Base64 input." );
+ } // end
+
+ } // end else: decode
+ } // end else: get data
+
+ // Got data?
+
+ if ( position >= 0 ) {
+ // End of relevant data?
+ if ( /*!encode &&*/ position >= numSigBytes )
+ return -1;
+
+ if ( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) {
+ lineLength = 0;
+ return '\n';
+ } // end if
+ else {
+ lineLength++; // This isn't important when decoding
+ // but throwing an extra "if" seems
+ // just as wasteful.
+
+ int b = buffer[ position++ ];
+
+ if ( position >= bufferLength )
+ position = -1;
+
+ return b & 0xFF; // This is how you "cast" a byte that's
+ // intended to be unsigned.
+ } // end else
+ } // end if: position >= 0
+
+ // Else error
+
+ else {
+ // When JDK1.4 is more accepted, use an assertion here.
+ throw new java.io.IOException( "Error in Base64 code reading stream." );
+ } // end else
+ } // end read
+
+
+ /**
+ * Calls {@link #read()} repeatedly until the end of stream
+ * is reached or len bytes are read.
+ * Returns number of bytes read into array or -1 if
+ * end of stream is encountered.
+ *
+ * @param dest array to hold values
+ * @param off offset for array
+ * @param len max number of bytes to read into array
+ * @return bytes read into array or -1 if end of stream is encountered.
+ * @since 1.3
+ */
+ public int read( byte[] dest, int off, int len ) throws java.io.IOException {
+ int i;
+ int b;
+ for ( i = 0; i < len; i++ ) {
+ b = read();
+
+ //if( b < 0 && i == 0 )
+ // return -1;
+
+ if ( b >= 0 )
+ dest[ off + i ] = ( byte ) b;
+ else if ( i == 0 )
+ return -1;
+ else
+ break; // Out of 'for' loop
+ } // end for: each byte read
+
+ return i;
+ } // end read
+
+ } // end inner class InputStream
+
+
+
+
+
+
+ /* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */
+
+
+
+ /**
+ * A {@link Base64.OutputStream} will write data to another
+ * java.io.OutputStream, given in the constructor,
+ * and encode/decode to/from Base64 notation on the fly.
+ *
+ * @see Base64
+ * @since 1.3
+ */
+ public static class OutputStream extends java.io.FilterOutputStream {
+ private boolean encode;
+ private int position;
+ private byte[] buffer;
+ private int bufferLength;
+ private int lineLength;
+ private boolean breakLines;
+ private byte[] b4; // Scratch used in a few places
+ private boolean suspendEncoding;
+
+ /**
+ * Constructs a {@link Base64.OutputStream} in ENCODE mode.
+ *
+ * @param out the java.io.OutputStream to which data will be written.
+ * @since 1.3
+ */
+ public OutputStream( java.io.OutputStream out ) {
+ this( out, ENCODE );
+ } // end constructor
+
+
+ /**
+ * Constructs a {@link Base64.OutputStream} in
+ * either ENCODE or DECODE mode.
+ *
+ * ENCODE or DECODE: Encode or Decode as data is read.
+ * DONT_BREAK_LINES: don't break lines at 76 characters
+ * (only meaningful when encoding)
+ * Note: Technically, this makes your encoding non-compliant.
+ *
+ * new Base64.OutputStream( out, Base64.ENCODE )
+ *
+ * @param out the java.io.OutputStream to which data will be written.
+ * @param options Specified options.
+ * @see Base64#ENCODE
+ * @see Base64#DECODE
+ * @see Base64#DONT_BREAK_LINES
+ * @since 1.3
+ */
+ public OutputStream( java.io.OutputStream out, int options ) {
+ super( out );
+ this.breakLines = ( options & DONT_BREAK_LINES ) != DONT_BREAK_LINES;
+ this.encode = ( options & ENCODE ) == ENCODE;
+ this.bufferLength = encode ? 3 : 4;
+ this.buffer = new byte[ bufferLength ];
+ this.position = 0;
+ this.lineLength = 0;
+ this.suspendEncoding = false;
+ this.b4 = new byte[ 4 ];
+ } // end constructor
+
+
+ /**
+ * Writes the byte to the output stream after
+ * converting to/from Base64 notation.
+ * When encoding, bytes are buffered three
+ * at a time before the output stream actually
+ * gets a write() call.
+ * When decoding, bytes are buffered four
+ * at a time.
+ *
+ * @param theByte the byte to write
+ * @since 1.3
+ */
+ public void write( int theByte ) throws java.io.IOException {
+ // Encoding suspended?
+ if ( suspendEncoding ) {
+ super.out.write( theByte );
+ return ;
+ } // end if: supsended
+
+ // Encode?
+ if ( encode ) {
+ buffer[ position++ ] = ( byte ) theByte;
+ if ( position >= bufferLength ) // Enough to encode.
+ {
+ out.write( encode3to4( b4, buffer, bufferLength ) );
+
+ lineLength += 4;
+ if ( breakLines && lineLength >= MAX_LINE_LENGTH ) {
+ out.write( NEW_LINE );
+ lineLength = 0;
+ } // end if: end of line
+
+ position = 0;
+ } // end if: enough to output
+ } // end if: encoding
+
+ // Else, Decoding
+
+ else {
+ // Meaningful Base64 character?
+ if ( DECODABET[ theByte & 0x7f ] > WHITE_SPACE_ENC ) {
+ buffer[ position++ ] = ( byte ) theByte;
+ if ( position >= bufferLength ) // Enough to output.
+ {
+ int len = Base64.decode4to3( buffer, 0, b4, 0 );
+ out.write( b4, 0, len );
+ //out.write( Base64.decode4to3( buffer ) );
+ position = 0;
+ } // end if: enough to output
+ } // end if: meaningful base64 character
+
+ else if ( DECODABET[ theByte & 0x7f ] != WHITE_SPACE_ENC ) {
+ throw new java.io.IOException( "Invalid character in Base64 data." );
+ } // end else: not white space either
+ } // end else: decoding
+ } // end write
+
+
+
+ /**
+ * Calls {@link #write(int)} repeatedly until len
+ * bytes are written.
+ *
+ * @param theBytes array from which to read bytes
+ * @param off offset for array
+ * @param len max number of bytes to read into array
+ * @since 1.3
+ */
+ public void write( byte[] theBytes, int off, int len ) throws java.io.IOException {
+ // Encoding suspended?
+ if ( suspendEncoding ) {
+ super.out.write( theBytes, off, len );
+ return ;
+ } // end if: supsended
+
+ for ( int i = 0; i < len; i++ ) {
+ write( theBytes[ off + i ] );
+ } // end for: each byte written
+
+ } // end write
+
+
+
+ /**
+ * Method added by PHIL. [Thanks, PHIL. -Rob]
+ * This pads the buffer without closing the stream.
+ */
+ public void flushBase64() throws java.io.IOException {
+ if ( position > 0 ) {
+ if ( encode ) {
+ out.write( encode3to4( b4, buffer, position ) );
+ position = 0;
+ } // end if: encoding
+ else {
+ throw new java.io.IOException( "Base64 input not properly padded." );
+ } // end else: decoding
+ } // end if: buffer partially full
+
+ } // end flush
+
+
+ /**
+ * Flushes and closes (I think, in the superclass) the stream.
+ *
+ * @since 1.3
+ */
+ public void close() throws java.io.IOException {
+ // 1. Ensure that pending characters are written
+ flushBase64();
+
+ // 2. Actually close the stream
+ // Base class both flushes and closes.
+ super.close();
+
+ buffer = null;
+ out = null;
+ } // end close
+
+
+
+ /**
+ * Suspends encoding of the stream.
+ * May be helpful if you need to embed a piece of
+ * base640-encoded data in a stream.
+ *
+ * @since 1.5.1
+ */
+ public void suspendEncoding() throws java.io.IOException {
+ flushBase64();
+ this.suspendEncoding = true;
+ } // end suspendEncoding
+
+
+ /**
+ * Resumes encoding of the stream.
+ * May be helpful if you need to embed a piece of
+ * base640-encoded data in a stream.
+ *
+ * @since 1.5.1
+ */
+ public void resumeEncoding() {
+ this.suspendEncoding = false;
+ } // end resumeEncoding
+
+
+
+ } // end inner class OutputStream
+
+ public static void main (String[] args) {
+ String command = args[0];
+ System.out.println(command);
+ String to_change = args[1];
+ System.out.println(to_change);
+ String answer = null;
+ if ("decode".equals(command)) {
+ answer = new String(Base64.decode(to_change));
+ }
+ else if ("encode".equals(command)) {
+ answer = Base64.encodeBytes(to_change.getBytes());
+ }
+ else {
+ System.out.println("invalid command, 'decode' and 'encode' are valid commands");
+ System.exit(1);
+ }
+ System.out.println(answer);
+ System.exit(0);
+ }
+
+} // end class Base64
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/math/Math.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/math/Math.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/math/Math.java (revision 15058)
@@ -0,0 +1,1035 @@
+package ise.antelope.tasks.util.math;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigInteger;
+import java.math.BigDecimal;
+import java.util.Vector;
+import java.util.Enumeration;
+
+/**
+ * Provides access to java.lang.Math and java.lang.StrictMath for Ant. Provides
+ * add, subtract, multiply, divide and mod methods as well as access to all methods
+ * java.lang.Math and java.lang.StrictMath via reflection.
+ * add(new int[]{1, 2, 3})
+ * is equivalent to
+ * add(add(1, 2), 3)
+ * which is equivalent to 1 + 2 + 3.
+ * @param op the operation to perform
+ * @type the data type of the operands. All operands will be cast to the same
+ * data type
+ * @param operands these strings must parse to numbers.
+ */
+ private Number calculateArray( String op, String type, String[] operands ) {
+ try {
+ Class c = this.getClass();
+
+ // find candidate methods for the requested operation
+ Vector candidates = new Vector();
+ Method[] methods = c.getDeclaredMethods();
+ for ( int i = 0; i < methods.length; i++ ) {
+ String name = methods[ i ].getName();
+ if ( name.equals( op ) ) {
+ if ( methods[ i ].getParameterTypes().length == 1 ) {
+ if ( methods[ i ].getParameterTypes() [ 0 ].isArray() )
+ candidates.addElement( methods[ i ] );
+ }
+ }
+ }
+ if ( candidates.size() == 0 )
+ throw new RuntimeException( "Unknown operation: " + op );
+
+ // get the desired data type for the operation, default is
+ // Double.TYPE if no other match is found
+ Object wantTypeClass = getDataTypeArray( type, operands.length );
+
+ // find the actual method to invoke and invoke it immediately once
+ // it is found
+ Class typeClass = null;
+ Enumeration en = candidates.elements();
+ while ( en.hasMoreElements() ) {
+ Method m = ( Method ) en.nextElement();
+ if ( m.getParameterTypes() [ 0 ].equals( wantTypeClass.getClass() ) ) {
+ typeClass = getDataType( type );
+ Object[] params = getParamsArray( typeClass, operands );
+ try {
+ //System.out.println( "Math.calculateArray, invoking: " + m.toString() );
+ Object result = m.invoke( c, params );
+ return ( Number ) result;
+ }
+ catch ( InvocationTargetException ite ) {
+ Throwable t = ite.getCause();
+ if ( t != null && t instanceof ArithmeticException ) {
+ //System.out.println( "caught ArithmeticException in Math" );
+ throw ( ArithmeticException ) t;
+ }
+ else {
+ //System.out.println( "throwing " + ite.getMessage() );
+ throw ite;
+ }
+ }
+ }
+ }
+ }
+ catch ( Exception e ) {
+ //e.printStackTrace();
+ if ( e instanceof ArithmeticException ) {
+ //System.out.println("rethrowing " + e.getMessage());
+ throw ( ArithmeticException ) e;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Converts a string representing a data type into the actual type.
+ * @param type one of "int", "long", "float", or "double"
+ * @return one of Integer.TYPE, Long.TYPE, Float.TYPE, or Double.TYPE. If the
+ * given type is null or not one of the allowed types, Double.TYPE will be
+ * returned.
+ */
+ private Class getDataType( String type ) {
+ if ( type == null )
+ return Double.TYPE;
+ if ( type.equals( "int" ) ) {
+ return Integer.TYPE;
+ }
+ else if ( type.equals( "long" ) ) {
+ return Long.TYPE;
+ }
+ else if ( type.equals( "float" ) ) {
+ return Float.TYPE;
+ }
+ else if ( type.equals( "bigint" ) ) {
+ try {
+ return Class.forName( "java.math.BigInteger" );
+ }
+ catch ( Exception e ) {
+ //e.printStackTrace();
+ }
+ }
+ else if ( type.equals( "bigdecimal" ) ) {
+ try {
+ return Class.forName( "java.math.BigDecimal" );
+ }
+ catch ( Exception e ) {
+ //e.printStackTrace();
+ }
+ }
+ return Double.TYPE;
+ }
+
+ /**
+ * Converts a string representing a data type into an Array.
+ * @param type one of "int", "long", "float", or "double"
+ * @param length how long to make the array
+ * @return an Array representing the data type
+ */
+ private Object getDataTypeArray( String type, int length ) {
+ if ( type == null )
+ return Array.newInstance( Double.TYPE, length );
+ if ( type.equals( "int" ) ) {
+ return Array.newInstance( Integer.TYPE, length );
+ }
+ else if ( type.equals( "long" ) ) {
+ return Array.newInstance( Long.TYPE, length );
+ }
+ else if ( type.equals( "float" ) ) {
+ return Array.newInstance( Float.TYPE, length );
+ }
+ else if ( type.equals( "bigdecimal" ) ) {
+ return Array.newInstance( BIGDECIMAL_TYPE, length );
+ }
+ else if ( type.equals( "bigint" ) ) {
+ return Array.newInstance( BIGINT_TYPE, length );
+ }
+ else {
+ return Array.newInstance( Double.TYPE, length );
+ }
+ }
+
+ /**
+ * @returns the given operands as an array of the given type.
+ */
+ private Object[] getParams( Class typeClass, String[] operands ) {
+ int paramCount = operands.length;
+ Object[] params = new Object[ paramCount ];
+ if ( typeClass == BIGDECIMAL_TYPE ) {
+ for ( int i = 0; i < paramCount; i++ ) {
+ params[ i ] = new BigDecimal( operands[ i ] );
+ }
+ }
+ else if ( typeClass == BIGINT_TYPE ) {
+ for ( int i = 0; i < paramCount; i++ ) {
+ params[ i ] = new BigInteger( operands[ i ] );
+ }
+ }
+ else if ( typeClass == Double.TYPE ) {
+ for ( int i = 0; i < paramCount; i++ ) {
+ params[ i ] = new Double( operands[ i ] );
+ }
+ }
+ else if ( typeClass == Long.TYPE ) {
+ for ( int i = 0; i < paramCount; i++ ) {
+ params[ i ] = new Long( operands[ i ] );
+ }
+ }
+ else if ( typeClass == Float.TYPE ) {
+ for ( int i = 0; i < paramCount; i++ ) {
+ params[ i ] = new Float( operands[ i ] );
+ }
+ }
+ else {
+ // Integer.TYPE is only other choice
+ for ( int i = 0; i < paramCount; i++ ) {
+ params[ i ] = new Integer( operands[ i ] );
+ }
+ }
+ if ( paramCount > 2 )
+ params = new Object[] {params};
+ return params;
+ }
+
+ /**
+ * Converts the given operands into an array of the given type.
+ */
+ private Object[] getParamsArray( Class typeClass, String[] operands ) {
+ int paramCount = operands.length;
+ if ( typeClass == BIGDECIMAL_TYPE ) {
+ BigDecimal[] array = ( BigDecimal[] ) Array.newInstance( typeClass, operands.length );
+ for ( int i = 0; i < paramCount; i++ ) {
+ array[ i ] = new BigDecimal( operands[ i ] );
+ }
+ return new Object[] {array};
+ }
+ else if ( typeClass == BIGINT_TYPE ) {
+ BigInteger[] array = ( BigInteger[] ) Array.newInstance( typeClass, operands.length );
+ for ( int i = 0; i < paramCount; i++ ) {
+ array[ i ] = new BigInteger( operands[ i ] );
+ }
+ return new Object[] {array};
+ }
+ else if ( typeClass == Double.TYPE ) {
+ double[] array = ( double[] ) Array.newInstance( typeClass, operands.length );
+ for ( int i = 0; i < paramCount; i++ ) {
+ Array.setDouble( array, i, new Double( operands[ i ] ).doubleValue() );
+ }
+ return new Object[] {array};
+ }
+ else if ( typeClass == Long.TYPE ) {
+ long[] array = ( long[] ) Array.newInstance( typeClass, operands.length );
+ for ( int i = 0; i < paramCount; i++ ) {
+ Array.setLong( array, i, new Long( operands[ i ] ).longValue() );
+ }
+ return new Object[] {array};
+ }
+ else if ( typeClass == Float.TYPE ) {
+ float[] array = ( float[] ) Array.newInstance( typeClass, operands.length );
+ for ( int i = 0; i < paramCount; i++ ) {
+ Array.setFloat( array, i, new Float( operands[ i ] ).floatValue() );
+ }
+ return new Object[] {array};
+ }
+ else {
+ // Integer.TYPE is only other choice
+ Object array = Array.newInstance( typeClass, operands.length );
+ for ( int i = 0; i < paramCount; i++ ) {
+ if (operands[i].indexOf(".") > 0)
+ operands[i] = operands[i].substring(0, operands[i].indexOf("."));
+ Array.setInt( array, i, new Integer( operands[ i ] ).intValue() );
+ }
+ return new Object[] {array};
+ }
+ }
+
+ public class Candidate {
+ private Class c;
+ private Method m;
+ public Candidate( Class c, Method m ) {
+ this.c = c;
+ this.m = m;
+ }
+ public Class getCandidateClass() {
+ return c;
+ }
+ public Method getCandidateMethod() {
+ return m;
+ }
+ }
+}
Index: /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/math/Num.java
===================================================================
--- /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/math/Num.java (revision 15058)
+++ /release-kits/shared/ant-tasks/tasks/antelope/src/ise/antelope/tasks/util/math/Num.java (revision 15058)
@@ -0,0 +1,88 @@
+package ise.antelope.tasks.util.math;
+
+
+/**
+ * Represents a number.
+ *
+ * <target name="foo">
+ * <antcall target="bar">
+ * <param name="property1" value="aaaaa" />
+ * <param name="foo" value="baz" />
+ * </antcall>
+ * </target>
+ *
+ * <target name="bar" depends="init">
+ * <echo message="prop is ${property1} ${foo}" />
+ * </target>
+ *
+ *
+ * boolean
flag.
+ */
+ public void setInheritAll(boolean inherit) {
+ inheritAll = inherit;
+ }
+
+ /**
+ * If true, pass all references to the new Ant project.
+ * Defaults to false.
+ * @param inheritRefs boolean
flag.
+ */
+ public void setInheritRefs(boolean inheritRefs) {
+ this.inheritRefs = inheritRefs;
+ }
+
+ /**
+ * Initialize this task by creating new instance of the ant task and
+ * configuring it by calling its own init method.
+ */
+ public void init() {
+ callee = (Ant) getProject().createTask("ant");
+ callee.setOwningTarget(getOwningTarget());
+ callee.setTaskName(getTaskName());
+ callee.setLocation(getLocation());
+ callee.init();
+ }
+
+ /**
+ * Delegate the work to the ant task instance, after setting it up.
+ * @throws BuildEximport org.apache.tools.ant.Task;ception on validation failure or if the target didn't
+ * execute.
+ */
+ public void execute() throws BuildException {
+ if (callee == null) {
+ init();
+ }
+ if (!targetSet) {
+ throw new BuildException(
+ "Attribute target or at least one nested target is required.",
+ getLocation());
+ }
+
+ //figure out what the address of this instance should be
+ String callingAddress = this.getOwningTarget().getAddress();
+ int subAddress = this.getOwningTarget().getNextSubAddress();
+ this.getOwningTarget().incrementNextSubAddress();
+
+ if ( callingAddress == null ) {
+ address = "" + subAddress;
+ } else {
+ address = callingAddress + "." + subAddress;
+ }
+
+
+ //check that the target should be run given address,resume.mode, rusume.from and resume.to
+ String resumeFrom = this.getProject().getProperty("resume.from");
+ String resumeTo = this.getProject().getProperty("resume.to");
+ String resumeMode = this.getProject().getProperty("resume.mode");
+
+ boolean shouldExecOnFrom = false, shouldExecOnTo = false;
+
+ //given resumeFrom, might we execute?
+ if ( resumeFrom == null ) {
+ shouldExecOnFrom = true;
+
+ } else {
+
+ //if the resumeFrom is a descendent of this, we must execute it no matter the Mode
+ if ( isDescendantOf(resumeFrom,address) ) {
+ shouldExecOnFrom = true;
+
+ } else {
+
+ if ( resumeMode == null ) {
+ //fallthrough mode
+ if ( isAfter(address,resumeFrom) ) {
+ shouldExecOnFrom = true;
+ } else {
+ shouldExecOnFrom = false;
+ }
+
+ } else if ( resumeMode.equals("descend") ) {
+ //descend mode
+ if ( isDescendantOf(address,resumeFrom) ) {
+ shouldExecOnFrom = true;
+ } else {
+ shouldExecOnFrom = false;
+ }
+
+ } else {
+ throw new BuildException(
+ "Only 'fallthrough' and 'descend' resume-modes are supported.",
+ getLocation()
+ );
+ }
+
+ }
+
+ }
+
+ //given resumeTo, might we execute?
+ if ( resumeTo == null ) {
+ shouldExecOnTo = true;
+ } else {
+ if ( !isAfter(address,resumeTo) || isEqualTo(address,resumeTo) ) {
+ shouldExecOnTo = true;
+ } else {
+ shouldExecOnTo = false;
+ }
+ }
+
+ //check that both are true
+ boolean execute = ( shouldExecOnFrom && shouldExecOnTo );
+
+ if ( execute ) {
+ callee.setAntfile(getProject().getProperty("ant.file"));
+ callee.setInheritAll(inheritAll);
+ callee.setInheritRefs(inheritRefs);
+ Target calleeTarget = (Target)callee.getProject().getTargets().get(theTarget);
+ calleeTarget.setAddress(address);
+
+ if( false ) {
+ throw new BuildException(
+ "\n theTarget " + theTarget + "\n calleeTarget: " + calleeTarget + "\n address: " + calleeTarget.getAddress(),
+ getLocation()
+ );
+ }
+ callee.execute(theTarget,address);
+ }
+ }
+
+ /**
+ * Create a new Property to pass to the invoked target(s).
+ * @return a Property
object.
+ */
+ public Property createParam() {
+ if (callee == null) {
+ init();
+ }
+ return callee.createProperty();
+ }
+
+ /**
+ * Reference element identifying a data type to carry
+ * over to the invoked target.
+ * @param r the specified Ant.Reference
.
+ * @since Ant 1.5
+ */
+ public void addReference(Ant.Reference r) {
+ if (callee == null) {
+ init();
+ }
+ callee.addReference(r);
+ }
+
+ /**
+ * Set of properties to pass to the new project.
+ * @param ps the PropertySet
to pass.
+ * @since Ant 1.6
+ */
+ public void addPropertyset(PropertySet ps) {
+ if (callee == null) {
+ init();
+ }
+ callee.addPropertyset(ps);
+ }
+
+
+ /**
+ * Set target to execute.
+ * @param target the name of the target to execute.
+ */
+ public void setTarget(String target) {
+ if (callee == null) {
+ init();
+ }
+ callee.setTarget(target);
+ theTarget = target;
+ targetSet = true;
+ }
+
+ /**
+ * Add a target to the list of targets to invoke.
+ * @param t Ant.TargetElement
representing the target.
+ * @since Ant 1.6.3
+ */
+ public void addConfiguredTarget(Ant.TargetElement t) {
+ if (callee == null) {
+ init();
+ }
+ callee.addConfiguredTarget(t);
+ targetSet = true;
+ }
+
+ /**
+ * @see Task#handleOutput(String)
+ *
+ * @since Ant 1.5
+ */
+ public void handleOutput(String output) {
+ if (callee != null) {
+ callee.handleOutput(output);
+ } else {
+ super.handleOutput(output);
+ }
+ }
+
+ /**
+ * @see Task#handleInput(byte[], int, int)
+ *
+ * @since Ant 1.6
+ */
+ public int handleInput(byte[] buffer, int offset, int length)
+ throws IOException {
+ if (callee != null) {
+ return callee.handleInput(buffer, offset, length);
+ } else {
+ return super.handleInput(buffer, offset, length);
+ }
+ }
+
+ /**
+ * @see Task#handleFlush(String)
+ *
+ * @since Ant 1.5.2
+ */
+ public void handleFlush(String output) {
+ if (callee != null) {
+ callee.handleFlush(output);
+ } else {
+ super.handleFlush(output);
+ }
+ }
+
+ /**
+ * @see Task#handleErrorOutput(String)
+ *
+ * @since Ant 1.5
+ */
+ public void handleErrorOutput(String output) {
+ if (callee != null) {
+ callee.handleErrorOutput(output);
+ } else {
+ super.handleErrorOutput(output);
+ }
+ }
+
+ /**
+ * @see Task#handleErrorFlush(String)
+ *
+ * @since Ant 1.5.2
+ */
+ public void handleErrorFlush(String output) {
+ if (callee != null) {
+ callee.handleErrorFlush(output);
+ } else {
+ super.handleErrorFlush(output);
+ }
+ }
+
+
+
+
+
+
+ /* --- node address relations --- */
+ public static boolean isAfter(String x, String y) {
+
+ System.out.println( "x: " + x );
+ System.out.println( "y: " + y );
+
+ if ( x.equals("") || y.equals("") ) {
+ throw new BuildException("Error - x or y not specified !!");
+ }
+
+ //check that both are in the form int.int.int
+
+ //break into chambers
+ String[] xs = x.split("\\.");
+ String[] ys = y.split("\\.");
+
+ //figure out n
+ int n = ys.length;
+
+ //step through, making sure x values are higher than or equal to y values
+ for ( int i=0; iboolean
flag.
+ */
+ public void setInheritAll(boolean inherit) {
+ inheritAll = inherit;
+ }
+
+ /**
+ * If true, pass all references to the new Ant project.
+ * Defaults to false.
+ * @param inheritRefs boolean
flag.
+ */
+ public void setInheritRefs(boolean inheritRefs) {
+ this.inheritRefs = inheritRefs;
+ }
+
+ /**
+ * Initialize this task by creating new instance of the ant task and
+ * configuring it by calling its own init method.
+ */
+ public void init() {
+ callee = (Ant) getProject().createTask("ant");
+ callee.setOwningTarget(getOwningTarget());
+ callee.setTaskName(getTaskName());
+ callee.setLocation(getLocation());
+ callee.init();
+ }
+
+ /**
+ * Delegate the work to the ant task instance, after setting it up.
+ * @throws BuildException on validation failure or if the target didn't
+ * execute.
+ */
+ public void execute() throws BuildException {
+ if (callee == null) {
+ init();
+ }
+
+ if (!targetSet) {
+ throw new BuildException(
+ "Attribute target or at least one nested target is required.",
+ getLocation());
+ }
+
+ //check that the target should be run given its address, the resume mode and the rusumefrom property
+ String resumeFrom = this.getProject().getProperty("resume.from");
+ String resumeTo = this.getProject().getProperty("resume.to");
+ String resumeMode = this.getProject().getProperty("resume.mode");
+
+ boolean shouldExecOnFrom = false, shouldExecOnTo = false, shouldExecOnMode = false;
+
+ //given resumeFrom, might we execute?
+ System.out.println("checking if we should execute given that resumeFrom=" + resumeFrom);
+ if ( resumeFrom == null ) {
+ shouldExecOnFrom = true;
+ } else {
+ if ( isAfter(address,resumeFrom) || isDescendantOf(resumeFrom,address) ) {
+ shouldExecOnFrom = true;
+ } else {
+ shouldExecOnFrom = false;
+ }
+ }
+
+ System.out.println("checking if we should execute given that resumeTo=" + resumeTo);
+ //given resumeTo, might we execute?
+ if ( resumeTo == null ) {
+ shouldExecOnTo = true;
+ } else {
+ if ( !isAfter(address,resumeTo ) ) {
+ shouldExecOnTo = true;
+ } else {
+ shouldExecOnTo = false;
+ }
+ }
+
+ System.out.println("checking if we should execute given that resumeMode=" + resumeMode);
+ //given resumeMode, might we execute?
+ if ( resumeMode == null ) {
+ shouldExecOnMode = true;
+ } else if ( resumeMode.equals("descend") ) {
+ if ( resumeFrom == null ) {
+ shouldExecOnMode = true;
+ } else if ( isDescendantOf(address,resumeFrom ) ) {
+ shouldExecOnMode = true;
+ } else {
+ shouldExecOnMode = false;
+ }
+ }
+
+ System.out.println("check that all three are true");
+ boolean execute = ( shouldExecOnFrom && shouldExecOnTo && shouldExecOnMode );
+
+
+ if ( execute ) {
+*/
+ callee.setAntfile(getProject().getProperty("ant.file"));
+ callee.setInheritAll(inheritAll);
+ callee.setInheritRefs(inheritRefs);
+ callee.execute();
+// }
+ }
+
+ /**
+ * Create a new Property to pass to the invoked target(s).
+ * @return a Property
object.
+ */
+ public Property createParam() {
+ if (callee == null) {
+ init();
+ }
+ return callee.createProperty();
+ }
+
+ /**
+ * Reference element identifying a data type to carry
+ * over to the invoked target.
+ * @param r the specified Ant.Reference
.
+ * @since Ant 1.5
+ */
+ public void addReference(Ant.Reference r) {
+ if (callee == null) {
+ init();
+ }
+ callee.addReference(r);
+ }
+
+ /**
+ * Set of properties to pass to the new project.
+ * @param ps the PropertySet
to pass.
+ * @since Ant 1.6
+ */
+ public void addPropertyset(PropertySet ps) {
+ if (callee == null) {
+ init();
+ }
+ callee.addPropertyset(ps);
+ }
+
+ /**
+ * setter for address
+ */
+ public void setAddress(String address) {
+ this.address=address;
+ }
+
+ /**
+ * getter for address
+ */
+ public String getAddress() {
+ return address;
+ }
+
+
+ /**
+ * Set target to execute.
+ * @param target the name of the target to execute.
+ */
+ public void setTarget(String target) {
+ if (callee == null) {
+ init();
+ }
+ callee.setTarget(target);
+ targetSet = true;
+ }
+
+ /**
+ * Add a target to the list of targets to invoke.
+ * @param t Ant.TargetElement
representing the target.
+ * @since Ant 1.6.3
+ */
+ public void addConfiguredTarget(Ant.TargetElement t) {
+ if (callee == null) {
+ init();
+ }
+ callee.addConfiguredTarget(t);
+ targetSet = true;
+ }
+
+ /**
+ * @see Task#handleOutput(String)
+ *
+ * @since Ant 1.5
+ */
+ public void handleOutput(String output) {
+ if (callee != null) {
+ callee.handleOutput(output);
+ } else {
+ super.handleOutput(output);
+ }
+ }
+
+ /**
+ * @see Task#handleInput(byte[], int, int)
+ *
+ * @since Ant 1.6
+ */
+ public int handleInput(byte[] buffer, int offset, int length)
+ throws IOException {
+ if (callee != null) {
+ return callee.handleInput(buffer, offset, length);
+ } else {
+ return super.handleInput(buffer, offset, length);
+ }
+ }
+
+ /**
+ * @see Task#handleFlush(String)
+ *
+ * @since Ant 1.5.2
+ */
+ public void handleFlush(String output) {
+ if (callee != null) {
+ callee.handleFlush(output);
+ } else {
+ super.handleFlush(output);
+ }
+ }
+
+ /**
+ * @see Task#handleErrorOutput(String)
+ *
+ * @since Ant 1.5
+ */
+ public void handleErrorOutput(String output) {
+ if (callee != null) {
+ callee.handleErrorOutput(output);
+ } else {
+ super.handleErrorOutput(output);
+ }
+ }
+
+ /**
+ * @see Task#handleErrorFlush(String)
+ *
+ * @since Ant 1.5.2
+ */
+ public void handleErrorFlush(String output) {
+ if (callee != null) {
+ callee.handleErrorFlush(output);
+ } else {
+ super.handleErrorFlush(output);
+ }
+ }
+
+
+
+
+
+ /* --- node address relations --- */
+ public boolean isAfter(String x, String y) {
+
+ System.out.println( "x: " + x );
+ System.out.println( "y: " + y );
+
+ if ( x.equals("") || y.equals("") ) {
+ throw new BuildException("Error - x or y not specified !!");
+ }
+
+ //check that both are in the form int.int.int
+
+ //break into chambers
+ String[] xs = x.split("\\.");
+ String[] ys = y.split("\\.");
+
+ //figure out n
+ int n = ys.length;
+
+ //step through, making sure x values are higher than or equal to y values
+ for ( int i=0; i<Svn>
+By Cédric Chabanois et al.
+
+
+Description
+
+With the help of the underlying svnClientAdapter, <svn> task uses JavaHL (a
+native JNI interface to the subversion api) if it
+can find the corresponding library (e.g. svnjavahl.dll on windows).
+Otherwise it uses svn command line interface.Parameters
+
+
+
+
+
+
+ Attribute
+ Description
+ Required
+
+
+ username
+ username that will be used for all nested svn commands.
+ No
+
+
+ password
+ password that will be used for all nested svn commands.
+ No
+
+
+javahl
+ Set to “false” to use command line client interface instead of JNI JavaHL binding.
+ No (Defaults to true)
+ Svn commands specified as nested elements
+
+
+
+
+ add
+ createRepository
+ import
+ move
+ status
+
+
+ cat
+ delete
+ keywordsset
+ propdel
+ switch
+
+
+ checkout
+ diff
+ keywordsadd
+ propget
+ update
+
+
+ commit
+ export
+ keywordsremove
+ propset
+
+
+
+ copy
+ ignore
+ mkdir
+ revert
+
+ add
+<add>
elements.
+
+
+
+ Attribute
+ Description
+ Required
+
+
+ file
+ file to add to the repository
+ No
+
+
+ dir
+ directory to add to the repository
+ No
+
+
+recurse
+ Set to "false" to operate on a single directory only
+ (applies only when
+ dir
attribute is set). Default is
+ "true"
+ No
+
+
+
+ Filesets are used to select sets of files to add to the repository.
+ Note that directories needed to add selected files will be added to the
+ repository even if they are not selected by the fileset.
+cat
+
+
+
+
+
+ Attribute
+ Description
+ Required
+
+
+ destFile
+ Name of the destination file
+ No
+
(default is the name of the file on the url)
+
+ url
+ Url of the file in repository
+ Yes
+
+
+revision
+ revision to get.
+
Possible values are :
- a date with the
+ following format : MM/DD/YYYY HH:MM AM_PM
- a revision number
-
+ HEAD, BASE, COMMITED or PREV
Default is "HEAD"
+ No
+ checkout
+
+
+
+
+ Attribute
+ Description
+ Required
+
+
+ url
+ url to checkout from
+ Yes
+
+
+ recurse
+ Set to "false" to operate on single directory only.
+ Default is "true"
+
+ No
+
+
+ destPath
+ destination directory
+ Yes
+
+
+revision
+ revision to checkout.
+
Possible values are :
- a date with
+ the following format : MM/DD/YYYY HH:MM AM_PM
- a revision
+ number
- HEAD, BASE, COMMITED or PREV
Default is "HEAD"
+ No
+
+
+
+ Filesets are used to select sets of files to add to the repository.
+ Note that directories needed to add selected files will be added to the
+ repository even if they are not selected by the fileset.
+
+<checkout
+url="${urlRepos}"
+destPath="workingcopy"
+/>
+</svn>
+commit
+
+
+
+
+ Attribute
+ Description
+ Required
+
+
+ file
+ file to commit
+ No
+
+
+ recurse
+ Set to "false" to operate on single directory only.
+ Default is "true"
+
Apply only when dir attribute is
+ set.
+ No
+
+
+ dir
+ directory to commit
+ No
+
+
+message
+ commit message
+ Yes
+
+
+
+ Filesets are used to select sets of files to commit.
+ copy
+
+source and destination can each be either a working copy (WC) path or URL:
+
+
+
+
+
+
+
+
+
+ Attribute
+ Description
+ Required
+
+
+ srcPath
+ source path
+ One of the two
+
+
+ srcUrl
+ source url
+
+
+ testPath
+ destination path
+ One of the two
+
+
+ destUrl
+ destination url
+
+
+ message
+ commit message
+ when destUrl is set
+
+
+revision
+ revision to copy from (when srcUrl is set)
+
Possible values
+ are :
- a date with the following format : MM/DD/YYYY HH:MM
+ AM_PM
- a revision number
- HEAD, BASE, COMMITED or
+ PREV
Default is "HEAD"
+ no
+ createRepository
+
+
+
+
+ Attribute
+ Description
+ Required
+
+
+path
+ Path where to create the new repository
+ Yes
+
+<svn
+javahl="false">
<createRepository
+path="repository"/>
</svn>
+delete
+
The command will not remove targets that are, or contain,
+unversioned or modified items; use the force attribute to override
+this behaviour.
+
If run on an url, the item is deleted from the repository via an immediate commit.
+
+
+
+
+ Attribute
+ Description
+ Required
+
+
+ file
+ file to delete
+ No
+
+
+ url
+ url to delete
+ No
+
+
+ dir
+ directory to delete
+ No
+
+
+ message
+ commit message
+ when url attribute is set
+
+
+force
+ default is "false"
+ No
+
+
+
+ Filesets are used to select sets of files to delete..
+ diff
+
+
+
+
+ Attribute
+ Description
+ Required
+
+
+ oldPath
+ If oldUrl is not set, defaults to the path '.'
+ No
+
+
+ oldUrl
+
+ No
+
+
+ oldTargetRevision
+ defaults to BASE or, if oldUrl is set, to HEAD
+ No
+
+
+ newPath
+ defaults to oldPath if oldUrl is not set
+ No
+
+
+ newUrl
+
+ No
+
+
+ newTargetRevision
+ defaults to the current working version or, if newUrl is set, to HEAD
+ No
+
+
+ outFile
+ Default is 'patch'
+ No
+
+
+recurse
+ Set to "false" to operate on single directory only.
+ Default is "true"
+
+ No
+
+<svn
+javahl="${javahl}">
<diff
+oldPath="workingcopy/diffTest/file.txt"
+outFile="workingcopy/diffTest/patch.txt"/>
+
</svn>
+export
+
+
+srcurl
,
+ at revision revision
if it is given, otherwise at HEAD, into destPath
.
+ srcPath
into destPath
. all local changes will be preserved,
+ but files not under revision control will not be copied.
Attribute | +Description | +Required | +
srcUrl | +source url to export from | +One of the two | +
srcPath | +source path to export from | +|
destPath | +destination path | +Yes | +
revision | +revision of the source url to export from. Defaults is
+ "HEAD" Possible values are : - a date with the + following format : MM/DD/YYYY HH:MM AM_PM - a revision number - + HEAD, BASE, COMMITED or PREV + |
+ No | +
Add a given file or a pattern to the ignored files list (modifies +svn:ignore property)
+Attribute | +Description | +Required | +
file | +file to ignore | +One of the two | +
dir | +directory on which we will update svn:ignore property | +|
pattern | +pattern to add to svn:ignore on the directory Only when dir + is set + |
+ Yes | +
recurse | +Set to "true" to add the pattern recursively to
+ directories. Default is "false" Only when dir is set + |
+ No | +
Example :
+<ignore
+dir="workingcopy/ignoreTest/dir1"
+pattern="*.ignore"
+recurse="true"/>
+
Commit an unversioned file or tree into the repository.
+Recursively commit a copy of path
to url
.
+If newEntry
is not set, copy top-level contents of path
intourl
directly.
+Otherwise, create newEntry
underneath url
and begin copy there.
+
Attribute | +Description | +Required | +
path | +source path to export from | +Yes | +
url | +source url to import to | +Yes | +
newEntry | ++ | No | +
message | +commit message | +Yes | +
recurse | +Set to "false" to operate on single directory only. + Default is "true" + | +False | +
Keywordsset controls which keywords will be substituted on the +given files. Valid keywords are: +
Attribute | +Description | +Required | +
file | +File for which keywords will be substituted | +Either file, dir or filesets | +
dir | +All files in this directory will have their keywords substituted (recursively) | +Either file, dir or filesets | +
keywords | +The keywords to substitute on the given files | +No | +
HeadURL/URL Author, LastChangedBy Date, + LastChangedDate Rev, LastChangedRevision Id + |
+ Set to “true“ the keyword to substitute it on the + given file. + | +No | +
Parameters specified as nested elements : +
Keywordsadd add some keywords to be substituted on the given
+files. Present keywords are not modified.
+The attributes are the same than for keywordsset command.
Keywordsadd remove some keywords to be substituted on the given
+files. Other present keywords are not modified.
+The attributes are the same than for keywordsset command.
Create a new directory under revision control.
+If target is a working copy path the directory is scheduled for addition in the
+working copy. If target is an url the directory is created in
+the repository via an immediate commit.
+In both cases all the intermediate directories must already exist.
+
Attribute | +Description | +Required | +
path | +path to create | +One of the two | +
url | +url to create | +|
message | +commit message | +Yes | +
Move/rename something in working copy or repository.
+cource and destination can both be working copy (WC) paths or
+URLs:
WC -> WC: move and
+schedule for addition (with history)
URL ->
+URL: complete server-side rename.
+
Attribute | +Description | +Required | +
srcPath | +source path | +One of the two | +
srcUrl | +source url | +|
destPath | +destination path | +One of the two | +
destUrl | +destination url | +|
message | +commit message | +Yes | +
Remove a property from files or dirs.
+Attribute | +Description | +Required | +
path | +path of the file or directory on which to delete the property | +Yes | +
name | +name of the property to delete | +Yes | +
recurse | +if set, property will be removed recursively | +No | +
Get a property from a file or a directory.
+Attribute | +Description | +Required | +
path | +path of the file or directory on which to get the property | +Yes | +
name | +name of the property to get | +Yes | +
property | +the name of the property to set with the value of the svn property | +One of the two | +
file | +file that will contain the value of the property | +
+Example :
+<propget
+path="workingcopy/propTest/file.png"
+name="svn:mime-type"
+property="propTest.mimeType"/>
+
Set a property on files or dirs.
+Attribute | +Description | +Required | +
path | +path of the file or directory on which to set the property | +Yes | +
name | +name of the property to set | +Yes | +
value | +the value of the property | +One of the two | +
file | +the file that will be used as a value | +|
recurse | +if set, property will be set recursively | +No | +
+Note:svn recognizes the following special versioned properties but +will store any arbitrary properties set: +
Restore pristine working copy file (undo most local edits).
+Attribute | +Description | +Required | +
file | +file to revert | +No | +
dir | +directory to revert | +No | +
recurse | +Set to "false" to operate on a single directory only
+ (applies only when dir attribute is set). Default is
+ "false" |
+ No | +
revision | +revision. Defaults is "HEAD" Possible values are + : - a date with the following format : MM/DD/YYYY HH:MM AM_PM - + a revision number - HEAD, BASE, COMMITED or PREV |
+ No | +
Parameters specified as nested elements : +
Get the status of working copy files and directories.
+Attribute | +Description | +Required | +
path | +path of the file or directory | +Yes | +
textStatusProperty | +Name of the property to set to the status of the item | +No | +
propStatusProperty | +Name of the property to set to the status of the item + properties | +No | +
revisionProperty | +Name of the property to set to the revision of the item (or “” + if unversioned) | +No | +
lastChangedRevisionProperty | +Name of the property to set to the last changed revision of the + item (or “” if unversioned) | +No | +
lastCommitAuthorProperty | +Name of the property to set to the last commit author (or “” + if unversioned) | +No | +
urlProperty | +Name of the property to set to the url of the item | +No | +
+The value of TextStatusProperty can be : +
+Example :
+<status
+path="workingcopy/statusTest/added.txt"
+
+textStatusProperty="testStatus.textStatus"
+propStatusProperty="testStatus.propStatus"
+lastChangedRevisionProperty="testStatus.lastCommitRevision"
+revisionProperty="testStatus.revision"
+lastCommitAuthorProperty="testStatus.lastCommitAuthor"
+
Update the working copy to mirror a new URL within the repository. +This behaviour is similar to 'svn update', and is the way to move a +working copy to a branch or tag within the same repository.
+Attribute | +Description | +Required | +
path | +The working copy to switch to the given url | +Yes | +
url | +The url to switch to | +Yes | +
recurse | +Set to "false" to operate on a single directory only. + Default is "true" | +No | +
revision | +revision. Defaults is "HEAD" Possible values are + : - a date with the following format : MM/DD/YYYY HH:MM AM_PM - + a revision number - HEAD, BASE, COMMITED or PREV |
+ No | +
+Example :
+
<svn>
+
<switch
+path="workingcopy/switchTest"
+url="${urlRepos}/switchTestBranch"/>
+
</svn>
+
Bring changes from the repository into the working copy.
If no
+revision given, bring working copy up-to-date with HEAD rev.
+Else synchronize working copy to revision.
Attribute | +Description | +Required | +
file | +file to update | +No | +
dir | +directory to update | +No | +
recurse | +Set to "false" to operate on a single directory only
+ (applies only when dir attribute is set). Default is
+ "true" |
+ No | +
revision | +revision. Defaults is "HEAD" Possible values are + : - a date with the following format : MM/DD/YYYY HH:MM AM_PM - + a revision number - HEAD, BASE, COMMITED or PREV |
+ No | +
+
+