Question

Need your advice on string replacement using ant propertyregex function.

I actually need to manipulate classpath file content by replacing certain section of the folder to the new folder and and remove some folder paths.

The actual content of the class path looks like:

/usr/home/folder1/com/codahale/metrics/metrics-core/3.0.2/metrics-core-3.0.2.jar:/usr/home/folder1/javax/ws/rs/javax.ws.rs-api/2.0-m10/javax.ws.rs-api-2.0-m10.jar:/etc/lib/:/usr/java/lib

which should eventually look like

/var/home/newfolder/metrics-core-3.0.2.jar:/var/home/newfolder/javax.ws.rs-api-2.0-m10.jar:/etc/lib/:/usr/java/lib

Basically, whichever string contains /usr/home/folder1, the new folder name should be prefixed to the jar file. The classpath contains 500 different groupId, artifactId with /usr/home/folder1 as the base

I am trying to replace the string in the classpath property from /usr/home/folder1/ to /var/home/newfolder/ as below. Not sure if something is wrong here, but this totally doesn't work..

<target name="classpath-generate">
        <propertyregex property="compileclasspath" input="${compileclasspath}" regexp="/usr/home/folder1/" replace="/var/home/newfolder/" defaultValue="${compileclasspath}"/>
</target>

Also, need some help on how to extract just the jar filename and prefix the new foldername.

Highly appreciate your input on this !!

Was it helpful?

Solution

No need for extra libraries like antcontrib or regular expressions.
Use ant api via script task with builtin JavaScript engine (since JDK 1.6.0_06) like that :

<project>

<property name="compileclasspath" value="/usr/home/folder1/com/codahale/metrics/metrics-core/3.0.2/metrics-core-3.0.2.jar:/usr/home:/usr/home/folder1/com/codahale/metrics/metrics-core/bla.jar"/>
<property name="replacefrom" value="/usr/home/folder1/com/codahale/metrics/metrics-core"/>
<property name="replaceto" value="/var/home/newfolder"/>

 <echo>
 $${compileclasspath} initial : 
 ${compileclasspath}
 </echo>

 <script language="javascript">
  //set newProperty
  project.setProperty('foobar', project.getProperty('compileclasspath').replace(project.getProperty('replacefrom'), project.getProperty('replaceto')));

  // overwrite existing property
  project.setProperty('compileclasspath', project.getProperty('compileclasspath').replace(project.getProperty('replacefrom'), project.getProperty('replaceto')));
 </script>


 <echo>
 $${compileclasspath} changed :
 ${compileclasspath}
 new Property $${foobar} :
 ${foobar}
 </echo>

</project>

output :

[echo]  ${compileclasspath} initial : 
[echo]  /usr/home/folder1/com/codahale/metrics/metrics-core/3.0.2/metrics-core-3.0.2.jar:/usr/home:/usr/home/folder1/com/codahale/metrics/metrics-core/bla.jar
[echo]  
[echo]  ${compileclasspath} changed :
[echo]  /var/home/newfolder/3.0.2/metrics-core-3.0.2.jar:/usr/home:/var/home/newfolder/bla.jar
[echo]  new Property ${foobar} :
[echo]  /var/home/newfolder/3.0.2/metrics-core-3.0.2.jar:/usr/home:/var/home/newfolder/bla.jar
[echo]  

To extract the jar names you might use something like :

<project>

<property name="compileclasspath" value="/usr/home/folder1/com/codahale/metrics/metrics-core/3.0.2/metrics-core-3.0.2.jar:/usr/home:/usr/home/folder1/com/codahale/metrics/metrics-core/bla.jar"/>

 <script language="javascript">
 <![CDATA[
 var cpitems = project.getProperty('compileclasspath').split(':');
 var jars = "";
 for (i=0; i < cpitems.length; i++) {
  if(cpitems[i].split('/')[(cpitems[i].split('/')).length -1].endsWith('.jar'))
  {
   jars += cpitems[i].split('/')[(cpitems[i].split('/')).length -1] + ','
  }
 }
 project.setProperty('cpjars', jars.substring(0, jars.length - 1));
 ]]>
 </script>

 <echo>$${cpjars} => ${cpjars}</echo>

</project>

output :

[echo] ${cpjars} => metrics-core-3.0.2.jar,bla.jar

OTHER TIPS

Below is an Ant script that uses Ant's built-in file name mapping functionality:

build.xml

<project name="ant-classpath-mapper" default="run">
    <property 
        name="original-classpath" 
        value="/usr/home/folder1/com/codahale/metrics/metrics-core/3.0.2/metrics-core-3.0.2.jar:/usr/home/folder1/javax/ws/rs/javax.ws.rs-api/2.0-m10/javax.ws.rs-api-2.0-m10.jar:/etc/lib/:/usr/java/lib"
    />

    <target name="run">
        <pathconvert property="modified-classpath">
            <path>
                <pathelement path="${original-classpath}"/>
            </path>
            <firstmatchmapper>
                <regexpmapper 
                    from="/usr/home/folder1/.*?([^/]+\.jar)$" 
                    to="/var/home/newfolder/\1" 
                />
                <identitymapper/>
            </firstmatchmapper>
        </pathconvert>

        <echo>${modified-classpath}</echo>
    </target>
</project>

Output

run:
     [echo] /var/home/newfolder/metrics-core-3.0.2.jar:/var/home/newfolder/javax.ws.rs-api-2.0-m10.jar:/etc/lib:/usr/java/lib

The <regexpmapper> matches the paths that start with "/usr/home/folder1".

The <regexpmapper> won't match paths such as "/etc/lib/" and "/usr/java/lib". The <firstmatchmapper> ensures that these paths will get matched by the following <identitymapper>.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top