ant string manipulation : extracting characters from a string - java

I have an ant property which has value of the type 1.0.0.123
I want to extract the value after the last dot, in this case that would be '123'.
Which ant task should i use and how?

With native ant task
If not wanting to use external libs nor scripting, I found in an answer to a similar question the best option (credit him for this answer). Here you'll be using a ReplaceRegex:
<loadresource property="index">
<propertyresource name="build.number"/>
<filterchain>
<tokenfilter>
<filetokenizer/>
<replaceregex pattern=".*\.)" replace="" />
</tokenfilter>
</filterchain>
</loadresource>
(I have used the same variable names as you in your solution. Of course, this is still missing the increment part of your answer, but that was not in your question.)
This script loads in index the result of deleting the regex .*\.) from build.number, that is, if build.number = 1.0.0.123 then index = 123.
Example
build.xml:
<project name="ParseBuildNumber" default="parse" basedir=".">
<property name="build.number" value="1.0.0.123"/>
<target name="parse">
<loadresource property="index">
<propertyresource name="build.number"/>
<filterchain>
<tokenfilter>
<filetokenizer/>
<replaceregex pattern=".*\." replace="" />
</tokenfilter>
</filterchain>
</loadresource>
<echo message="build.number=${build.number}; index=${index}"/>
</target>
</project>
$ ant
Buildfile: /tmp/build.xml
parse:
[echo] build.number=1.0.0.123; index=123
BUILD SUCCESSFUL
Total time: 0 seconds

I suspect the easiest approach may be to use the ant-contrib PropertyRegex task.
Something like this - completely untested:
<propertyregex property="output"
input="input"
regexp=".*([^\.]*)"
select="\1" />

Ok i have found the answer myself and this is tested.
you just gotta use a bit of javascript.
<target name="get build ctr">
<script language="javascript">
<![CDATA[
// getting the value
buildnumber = myproj.getProperty("build.number");
index = buildnumber.lastIndexOf(".");
counter = buildnumber.substring(index+1);
myproj.setProperty("buildctr",counter);
]]>
</script>
</target>

<propertyregex property="xtractedvalue"
input="${foobar}"
regexp="(.*)\.(.*)$"
select="\2" />

Here's a solution using flaka without scripting =
<project xmlns:fl="antlib:it.haefelinger.flaka">
<property name="foobar" value="1.0.0.123"/>
<target name="main">
<!-- simple echo -->
<fl:echo>xtractedvalue => #{split('${foobar}','\.')[3]}</fl:echo>
<!-- create property for further processing.. -->
<fl:let>
xtractedvalue := split('${foobar}','\.')[3]
</fl:let>
<echo>$${xtractedvalue} => ${xtractedvalue}</echo>
</target>
</project>

I would also use the ant-contrib PropertyRegex task.
The following snippet only works if the input string follows the convention you used in your description and you can also use it to extract the other numbers by changing the value entered in the select tag.
<propertyregex property="output"
input="input"
regexp="(\d)\.(\d)\.(\d)\.(\d{3})"
select="\4" />
You can also use the issest task on the output string to print out an error message if the input string does not follow the convention, because the output property will not be set.

Related

Android Gradle: get return value from a static java method

I need to use a method from one of my java classes in build time, like you can do in ant like this:
<target name="getString" >
<property file="project.properties" /> <!-- Load the ${target} platform property -->
<script language="javascript" classpath="../ProjectName/bin/randomJar.jar:../otherProject/binrandomClass.jar:../otherProject2/bin/randomJar2.jar:/fff/adt-bundle-linux-x86_64/sdk/platforms/${target}/android.jar">
<![CDATA[
importClass(com.example.sdk.ExampleClass);
returnString = ExampleClass.thisIsTheMethod(null);
project.setProperty("blah", returnString);
]]>
</script>
</target>
I dont want to run a Main method like iv'e seen in other answers, just a static method and get the return string.
thank you.

Can we use parameters in oozie decision node?

I am trying to execute a decision control node in oozie 3.3.2 but getting javax.servlet.jsp.el.ELException
Encountered "{"
<decision name="decision-wf">
<switch>
<case to="another_wf">
${fs:fileSize(${OutputDir}/000000_0) gt 100 }
</case>
<default to="fail-wf"/>
</switch>
How should I pass the parameter in String format as the above mentioned FS method expects String input ?
From the document it appears,
You need to pass hardcoded i.e. enclosed in ' like in ${fs:fileSize('/usr/foo/myinputdir'/1000) gt 10 }
or
just the parameter name ${fs:fileSize(OutputDir/1000) gt 10 }
This OutputDir might be specified in the <config> sections of the workflow OR the .properties file OR passed at time of submitting the job using -D
Yes you can. In fact you can combine multiple parameters with the concat function (which, I think, would help with the original poster's question).
For example if ${location} and ${date} are two params defined in your config file:
<decision name="check-directory-exists">
<switch>
<case to="load-directory">
<!-- check if the directory at this location for this date exists -->
${fs:exists(concat(location, date))}
</case>
<!-- The directory doesn't exist, there is nothing to do -->
<default to="end" />
</switch>
</decision>
and if location and date need a '/' between them, you have to do this:
${fs:exists(concat(concat(location, "/"), date))}

How to check whether the input is not blank in Ant Input Task?

I have a ant script that requires user inputs. I would like to ensure the correct input type has been entered by the user and if not, prompt them to enter something that is correct.
<input message="secure-input:" addproperty="the.password" >
</input>
I have to check if the input is blank then i will prompt them to reenter.
Is it possible in ant input task?
Most of the conditional clauses allow you at best to fail the script if some condition is not met. I am imagining that you are gathering some inputs from the user, so failing if the user supplies an empty password might not be the best usability experience, since he would have to input everything all over again...
Furthermore, just testing for an empty string seems like a poor validation, what if the user submits a bunch of spaces?
My (admittedly hackish) suggestion is the following:
<target name="askPassword">
<local name="passwordToValidate"/>
<input message="secure-input:" addproperty="passwordToValidate"/>
<script language="javascript">
<![CDATA[
passwordToValidate = project.getProperty("passwordToValidate");
//You can add more validations here...
if(passwordToValidate.isEmpty()){
println("The password cannot be empty.");
project.executeTarget('askPassword');
}
]]>
</script>
<property name="the.password" value="${passwordToValidate}"/>
</target>
So the highlights:
Use the local task to set a local scope for the "passwordToValidate" property (remember that once you set a property on a ant script most tasks don't allow you to rewrite it, so the recursion would be problematic)
Test your input with a script (maybe add some more validations)
If the test fails, call the target again
If the test succeeds, assign the local scoped property to the global scoped one
My 2 cents.
You can use condition task to check if input is not empty but you can also use antcontrib to add if/else and show user appropriate message:
<if>
<not>
<length string="${the.password}" trim="true" when="greater" length="0" />
</not>
</if>
<then>
<echo>Your password is empty!</echo>
</then>
Take a look at Conditions - for condition task.

How to put a newline in ant property

This doesn't seem to work:
<property name="foo" value="\n bar \n"/>
I use the property value in the body of an e-mail message (which is sent as plain text):
<mail ...>
<message>some text${foo}</message>
and I get literal "\n" in the e-mail output.
These all work for me:
<property name="foo" value="bar${line.separator}bazz"/>
<property name="foo">bar
bazz2</property>
<property name="foo" value="bar
bazz"/>
You want ${line.separator}. See this post for an example. Also, the Ant echo task manual page has an example using ${line.separator}.
By using ${line.separator} you're simply using a Java system property. You can read up on the list of system properties here, and here is Ant's manual page on Properties.

Creating/filtering fileset from a list in a file or from a property with ant

Let us suppose I have a file called "list-of-files.txt" with this content:
file1.txt
file2.properties
file3.class
I would like to use this content in a ant :
<fileset filelist="list-of-files.txt" />
Is it possible?
Also, if I had this list of files in a property:
<property name="various.files" value="file1.txt,file2.properties,file3.class" />
is there a way to create a fileset with it? Something like:
<fileset files="${various.files}" />
Thank you in advance!
It sounds like PatternSets might be of help. Look at the includes and includesfile attributes and nested elements. You can also look at the FileSet documentation to see how they're used in that context.

Categories