Sunday 23 October 2011

Search & Replace JDBC Data source in XSLT using ANT

Hey everybody, today I come across a problem while deploying my code using ANT script.Each of my composite has its own deployment plan by which all the endpoint reference and jca properties getting changed to new environment.. but in the XSLT I’ve used couple of query database XPATH function and it use datasource as one of its input parameter.But I didn’t find any option in deployment plan to change the datasource as per my new environment.What if, we have a helper ant script that will search all the xsl files in a directory recursively and work in conjunction with main ant build script, definitely would be good. To get started I created a simple java class who will do the search and replacement job of all xslt files,

package com.shrik.utility;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import java.util.Collection;
import java.util.Iterator;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class SearchAndReplaceXSLT {
    public static void main(String[] args) throws Exception {
        Properties properties=new Properties();
        properties.load(new FileInputStream("trx.properties"));
       
        File root = new File(properties.getProperty("FileRoot"));
       
        System.out.println(properties.getProperty("FileRoot"));
        String[] extensions = { properties.getProperty("FileExt") };
        boolean recursive = true;

        Collection files = FileUtils.listFiles(root, extensions, recursive);

        for (Iterator iterator = files.iterator(); iterator.hasNext(); ) {
            File file = (File)iterator.next();
            System.out.println("File = " + file.getAbsolutePath());
            SearchAndReplace(file,properties.getProperty("SearchStr"),properties.getProperty("ReplaceStr"));
        }
    }

   private static void SearchAndReplace(File file, String searchStr,
                                         String replaceStr) throws IOException {
        StringBuffer sb=new StringBuffer();
        Pattern pattern=Pattern.compile(searchStr);
        Matcher matcher=pattern.matcher(FileUtils.readFileToString(file));
        while(matcher.find()){
            matcher.appendReplacement(sb, replaceStr);
           
        }
        matcher.appendTail(sb);
        System.out.println(sb.toString());
        FileUtils.writeStringToFile(file,sb.toString() );
    }
}

and here is the corresponding trx.properties file,

FileRoot=C:/shrik/Oracle/SOAWork/composites/DeploymentFramework/test/trx
FileExt=xsl
SearchStr=DS_DEV_YYY&
ReplaceStr=DS_DEV_ZZZ&
build.dir=build
lib.dir=lib
main-class="com.shrik.utility.SearchAndReplaceXSLT"

Do fill up all the values based on your environment and root code repository directory.Just give a test run and check whether its doing your job or not.

Then create a jar file pointing your main class in manifest file.Here we have a dependency on org.apache.commons.io.FileUtils class so I created a folder lib and put the commons-io-1.3.2.jar file under that, here is my directory structure,

image

Under the build folder I created another directory jar , and under that I placed SearchAndReplaceXSLT.jar file.I created a trx folder where I copied all the xsl files, datasource need to be replaced.Now we need to refer the jar file from a ant script and for that I created build.xml file which contains,

<project name="SearchAndReplaceXSLT" basedir="." default="run">

<property file="trx.properties"/> 
    <property name="jar.dir"     value="${build.dir}/jar"/>
    <property name="classes.dir" value="${build.dir}/classes"/>
     <path id="classpath">
        <fileset dir="${lib.dir}" includes="**/*.jar"/>
    </path>
   
    <target name="run" >
        <java fork="true" classname="${main-class}">
            <classpath>
                <path refid="classpath"/>
                <path location="${jar.dir}/${ant.project.name}.jar"/>
            </classpath>
        </java>
    </target>

</project>

Now just run ant and it will do the job .

So next part is how will I call this ant file from main build.xml in deployment script?

In main build.properties file I created a new property trx.amendment=true . Based on this value it will call the child script as below,

<target name="deployAll">
        <if>
          <equals arg1="${trx.amendment}" arg2="true"/>
          <then>
             <ant antfile="${env.CURRENT_FOLDER}/trx.xml" inheritAll="false" target="run"/>
          </then>
      </if>     
       
         <if>
          <equals arg1="${mds.enabled}" arg2="true"/>
          <then>
             <antcall target="deployMDS" inheritall="true"/>
          </then>
      </if>     
      <foreach list="${applications}" param="application" target="deployApplication" inheritall="true" inheritrefs="false"/>
    </target>

So with this you can easily change any data source name in sequence or database query function of your XSLT.

No comments: