Question

Java compilation is working fine in ANT and in Gradle. I'm just trying to find way to write the code in Gradle for xml file generation, what ANT is doing (please see below).

Folder structure:

src/java -- containing java src code
src/xml  -- contains folders:
            patterns    -- contains one xxx.properties file and bunch of .xml and .template files
            schema      -- contains a .xsd file
            stylesheet  -- contains 3 .xsl files

Contents of the pattern.properties file are:

# xml header information and root element for the document
pattern.xml.header=<?xml version="1.0"?>\
<patternFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Patterns.xsd">

# Patterns in order to load.
pattern.filelist=\
GlobalPoints-Dashboard.xml,\
IVCompatibility.xml,\
IVCompatibilityAgent.xml,\
IVCompatibilityProduct.xml,\
TVServicesClassSearch.xml,\
TVServicesSearchMartindaleIndexNom.xml

# end element for the file
pattern.xml.trailer=</patternFile>

ANT code which is generating the final Patterns.xml file that I need is:
pattern.src.dir = src/xml/patterns
pattern.schema.dir = src/xml/schema
pattern.xml.filename = Patterns.xml
pattern.xsd.filename = Patterns.xsd
pattern.src.xsd = src/xml/schema/Patterns.xsd
pattern.output.dir = temp
pattern.output.file = temp/Patterns.xml
pattern.properties = pattern.properties

    <!-- transform the template patterns -->
    <target name="templates" >
        <xslt basedir="src/xml/patterns"
               destdir="src/xml/patterns"
              extension=".xml"
               force="true"
               style="src/xml/stylesheets/SearchTemplate.xsl"
              includes="FOX-Tool-Active-Ingredient.template,
                      FOX-Tool-Product.template,
                        FOX-Tool-Product-Material.template">
       </xslt>
    </target>

  <!-- create the pattern definition file by concatenating all parts -->
  <target name="build-xml" depends="init,templates">
    <loadproperties srcFile="${pattern.src.dir}/${pattern.properties}" />
     <!-- make sure all files exist -->
    <resourcecount property="fileCount">
      <fileset dir="${pattern.src.dir}" includes="${pattern.filelist}" />
    </resourcecount>
    <fail message="Files are missing.">
      <condition>
        <not>
          <resourcecount count="${fileCount}">
            <filelist dir="${pattern.src.dir}" files="${pattern.filelist}"/>
          </resourcecount>
        </not>
      </condition>
    </fail>

     <concat destfile="${pattern.output.file}">${pattern.xml.header}</concat>
     <concat append="yes" destfile="${pattern.output.file}">
       <filelist dir="${pattern.src.dir}" files="${pattern.filelist}"/>
     </concat>
     <concat append="yes" destfile="${pattern.output.file}">${pattern.xml.trailer}</concat>

     <!-- copy the schema to the output directory for validation -->
    <copy file="${pattern.src.xsd}"
          todir="${pattern.output.dir}"
          overwrite="yes"/>

     <!-- validate that the combined file matches the schema  -->
    <schemavalidate file="${pattern.output.file}">
       <schema file="${pattern.src.xsd}"
              namespace="http://www.w3.org/2001/XMLSchema-instance"/>
     </schemavalidate>
  </target>

Using the following Gradle code, I can perform the first piece what "templates" target is doing in ANT.

// Perform XSL transformations in work directory as similar to ANT "templates" target
def performXslt() {
   ant {
      xslt(
         basedir: "${pattern.src.dir}",
         destdir: "${pattern.src.dir}",
         extension: ".xml",
         force: "true",
         style: "src/xml/stylesheets/SearchTemplate.xsl",
         includes: "*.template"
      )
   }
}

I can call the above task as a dependsOn or doFirst of another Gradle custom task that I'll write. For this second task which would be equivalent to "build-xml" target in ANT, I'm trying to check with you all - what would be an efficient way to code it.

As I see "build-xml" target in ANT, all it's doing is calling "template" target first and then reading the pattern.properties file which has 3 variables, 1) header string. 2) List of .xml files and 3) trail/footnote string and all its' doing is concatenating the values of those variable/string of 1(string) + (contents of all .xml files contents as mentioned in 2nd variable) + 3(string) into a final Patterns.xml file. Finally, it's copying another .xsd file in the same output folder and running some schema validation using that on the final Patterns.xml file.

Can someone help me writing the above "build-xml" ANT target login in Gradle as "buildXML" task, so that I don't end up writing a 2 page script.
Thanks.

Was it helpful?

Solution

Final solution: (with a small tweak that instead of using src/xml/patterns, I created a tmp/template location to do everything)..

   //---
   // 1. Transform the template patterns
   copy {
      into "${buildDir}/tmp/template"
      from "src"
      include "xml/**"
   }
   ant {
      xslt(
         basedir: "${buildDir}/tmp/template/xml/patterns",
         destdir: "${buildDir}/tmp/template/xml/patterns",
         extension: ".xml",
         force: "true",
         style: "${buildDir}/tmp/template/xml/stylesheets/SearchTemplate.xsl",
         includes: "*.template"
      )
   }

   // 2. Create the pattern definition file by concatenating all parts
   def outFile = new File ( "${buildDir}/tmp/template", "Patterns.xml" )
   def props = new Properties()
   new File("${buildDir}/tmp/template/xml/patterns/_patternlist.properties").withInputStream {
     stream -> props.load(stream)
   }
   outFile.text = props["pattern.xml.header"].toString()
   props["pattern.filelist"].split(',').each {
      String s1 = "${buildDir}/tmp/template/xml/patterns/" + it
      String s = new File (s1).text
      outFile.append(s)
   }
   outFile.append(props["pattern.xml.trailer"].toString())

   // 3. Copy .xsd file
   copy {
      into "${buildDir}/tmp/template"
      from "src/xml/schema"
      include "Patterns.xsd"
   }

   // 4. Validate schema
   ant {
      schemavalidate( file: "${buildDir}/tmp/template/Patterns.xml" ) {
          schema( file: "${buildDir}/tmp/template/xml/schema/Patterns.xsd",
                  namespace: "http://www.w3.org/2001/XMLSchema-instance" )
      }
   }

OTHER TIPS

OK. I got to this point that I'm now able to read the multiline values of those variables using the following:

def props = new Properties()
new File("pattern.properties").withInputStream {
  stream -> props.load(stream)
}
// accessing the property from Properties object using Groovy's map notation
println "pattern.xml.header=" + props["pattern.xml.header"]
println "pattern.filelist=" + props["pattern.filelist"]
println "pattern.xml.trailer=" + props["pattern.xml.trailer"]

This outputs as:

-bash-3.2$ /production/gradle/gradle-1.6/bin/gradle -b build.gradle

pattern.xml.header=<?xml version="1.0"?><patternFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Patterns.xsd">
pattern.filelist=1.xml,2-a.xml,3-iii.xml,4_dddd.xml,File6.xml
pattern.xml.trailer=</patternFile>

PS: The above output of pattern.properties file had different content than what I mentioned in the post above(I was playing with the code on my local machine and didn't wanted to use the real contents).. but the code would work for any pattern.properties file.

Now, all I need to do is the last file creation part, which would be pretty easy.. i.e. use foreach loop around and write the contents of each file (using 2nd parameter) and concatenate param1+param2(each file contents)+param3 and there you go.

BTW, I'll post the final solution when I have.. still, if you know a more efficient way, please advise.

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