How to get each substring in a file by Ant - ant

I have a file contains following lines of strings separated by "|",
C:\Temp\demo\AAA.dat | C:\test\input\AAA.dat
C:\Temp\build\BBB.bat | C:\test\java\BBB.bat
C:\Temp\test\CCC.xml | C:\Apps\ftp\CCC.xml
after I read each line, I hope to extract each string separated by "|",
ie, after i get 1st line,
I need to get both C:\Temp\demo\AAA.dat and C:\test\input\AAA.dat;
Pls help how to use ant to do it???
I use following code I can only get each line :
<loadfile property="filelist" srcfile="C:\Temp\file1.txt"/>
<target name="test" depends="chkInput" description="test">
<for param = "line" list="${filelist}" delimiter="${line.separator}">
<sequential>
<echo>#{line}</echo>
</sequential>
</for>
</target>
Not each substring separated by "|", pls help how to get each substring separated by "|"?

Once you have the line, you can use <propertyregex> to separate the two pieces.
<for param = "line" list="${filelist}" delimiter="${line.separator}">
<sequential>
<echo>#{line}</echo>
<var name="first.part" unset="true"/>
<var name="second.part" unset="true"/>
<propertyregex
property="first.part"
input="#{line}"
regex="^([^\s]*)"
select="\1"/>
<propertyregex
property="second.part"
input="#{line}"
regex="\|\s*([^\s]*).*$"
select="\1"/>
</sequential>
</for>
Note you have to use either the <var/> task to unset the property (or otherwise, you're not changing the property, or the new task to declare that property is local to the <sequential/> entity.

Related

Ant - String contains within an array of String

I am basically trying to do the following thing in Ant (v1.9.4):
I have a list of fixed string like {a,b,c,d} --> First how should I declare this in Ant?
Then I have an input parameter such as ${mystring} and I want to check if the variable value is in my list. Which means in this example, if the variable value is equals to a or b or c or d.
If so return true else false (or 0 and 1 something like that).
Is there a simple way to do that?
Thanks,
Thiago
Use ant property task to declare your stringlist.
Use ant contains condition to check whether list contains a specific item.
Something like :
<project>
<!-- your stringlist -->
<property name="csvprop" value="foo,bar,foobar"/>
<!-- fail if 'foobaz' is missing -->
<fail message="foobaz not in List => [${csvprop}]">
<condition>
<not>
<contains string="${csvprop}" substring="foobaz"/>
</not>
</condition>
</fail>
</project>
Or wrap it in a macrodef for resuse :
<project>
<!-- your stringlist -->
<property name="csvprop" value="foo,bar,foobar"/>
<!-- create macrodef -->
<macrodef name="listcontains">
<attribute name="list"/>
<attribute name="item"/>
<sequential>
<fail message="#{item} not in List => [#{list}]">
<condition>
<not>
<contains string="${csvprop}" substring="foobaz"/>
</not>
</condition>
</fail>
</sequential>
</macrodef>
<!-- use macrodef -->
<listcontains item="foobaz" list="${csvprop}"/>
</project>
-- EDIT --
From ant manual condition :
If the condition holds true, the property value is set to true by default; otherwise, the property is not set. You can set the value to something other than the default by specifying the value attribute.
So simply use a condition to create a property that is either true or not set, f.e. combined with the new if/unless feature introduced with Ant 1.9.1 :
<project
xmlns:if="ant:if"
xmlns:unless="ant:unless"
>
<!-- your stringlist -->
<property name="csvprop" value="foo,bar,foobar"/>
<!-- create macrodef -->
<macrodef name="listcontains">
<attribute name="list"/>
<attribute name="item"/>
<sequential>
<condition property="itemfound">
<contains string="${csvprop}" substring="foobaz"/>
</condition>
<!-- echo as example only instead of
your real stuff -->
<echo if:true="${itemfound}">Item #{item} found => OK !!</echo>
<echo unless:true="${itemfound}">Warning => Item #{item} not found !!</echo>
</sequential>
</macrodef>
<!-- use macrodef -->
<listcontains item="foobaz" list="${csvprop}"/>
</project>
output :
[echo] Warning => Item foobaz not found !!
Note that you need the namespace declarations to activate the if/unless feature.

Bug in ant macrodef

I have a bug in the following ant macrodef definition:
<macrodef name="xxx" description="does xxx">
<attribute name="attr1" default=""/>
<sequential>
<echo message="doing yyy"/>
<echo message="#{attr1}" file="${builddir}/zzz.xml"/>
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask"/>
<xmltask report="true" source="${builddir}/zzz.xml">
<call path="spuds" target="process-spuds">
<param name="spud-kicker" path="#count"/>
</call>
</xmltask>
</sequential>
</macrodef>
When it tries to call the target of the call inside the xmltask, i get a null pointer exception.
What am I doing wrong?
The file zzz.xml contains (supposedly) well formed xml. It contains a top level tag called "spuds" with an attribute named count. I want to invoke the spud-kicker ant target on the spuds tag and pass the value of the count attribute to that task.

How to to pass configurable file mapping lists to ant macros?

I'm trying to refactor an Ant buildfile with many similar targets into a buildfile that uses macros. This roughly is what it looks like:
<macrodef name="build-text">
<argument name="lang" />
<element name="file-list"/>
<sequential>
<property name="lang" value="#{lang}" />
<xslt style="my_stylesheet.xsl" destdir="build" basedir="src">
<!-- lots of params here -->
<file-list />
</xslt>
</sequential>
</macrodef>
<target name="buildTextDE">
<build-text lang="DE">
<file-list>
<mapper>
<mapper type="glob" from="Text1_${lang}.html" to="Text1_${lang}.fo"/>
<mapper type="glob" from="Text2_${lang}.html" to="Text2_${lang}.fo"/>
</mapper>
</file-list>
</build-text>
</target>
There is another task called buildTextEN that is nearly identical except for the lang attribute. In some cases, the file list differs however. Now how would I like to simplify the buildfile further by defining a "global" mapping list that contains the file lists for German and English, each file with the placeholder for the language. I would like to reference this global mapping where no special case is needed. How would I do that?

Multiple ANT properties (from file) into the one property

I use task to run a target for all values from the list, taken from one property.
<foreach list="val1,val2" delimiter="," target="my.target" param="param_name"/>
Now, I want to put those values to the separate properties file as there is a lot of them.
So the question is: how can I read multiple (don't know how many) properties (lines in file in fact) from the file into one property?
The property file should look like this:
val1
val2
anothervalue
foobar
And the output should be:
"val1,val2,anothervalue,foobar"
be put in one property.
You can achieve this using LineTokenizer filter with loadfile. For example:
<target name="t">
<loadfile property="data_range" srcFile="ls.txt">
<filterchain> <!-- this filter outputs lines delimited by "," -->
<tokenfilter delimoutput=","/>
</filterchain>
</loadfile>
<foreach list="${data_range}" param="line" delimiter="," target="print" />
</target>
<target name="print">
<echo>line [${line}]</echo> <!-- you can do anything here -->
</target>

How do I retrieve a value from a variable in a for loop?

I have a for loop like the following:
<property name="audi" value="germany" />
<property name="toyota" value="japan" />
<for list="audi,toyota" param="car">
<sequential>
<echo>#{#{car}}</echo>
</sequential>
</for>
As you can see, I'm trying to echo the value "germany" then "japan", but it doesn't - it displays #{#{car}}
Any suggestions on how to do it?
Found it...
#{#{car}}
needs to be:
${#{car}}

Resources