Platform Engineering

Data Mapping with Groovy - Part 1

Posted by Admin on 14 November 2013

tech, mule, groovy

ESB services involve working with a variety of different data formats and structures e.g. XML, JSON, CSV, spread sheets, key-value structures. Transformations between XML and other data structures are quite common when it comes to developing an ESB layer. Mule ESB provides a wide range of choices when it comes to scripting and data transformation. There’s enough choice to satisfy the proclivities of any developer.

Scripting languages have become popular in recent times because of their first-class support for data structures such as arrays and maps which become a natural complement for markup languages such as XML and JSON. On the JVM, one popular scripting choice is Groovy.

Groovy Primer

The language syntax is mostly similar to Java and it supports calling any existing Java code/libraries. However Groovy’s dynamic typing and optional semi-colons and parentheses make Groovy code more succinct.

For example, compare this simple Java:

  import java.util.List;
  import java.util.ArrayList;
   
  List mylist = new ArrayList<String>();
  myList.add("Hello");
  myList.add("World");
   
  System.out.println(list);
view rawbasic.java hosted with ❤ by GitHub

With the corresponding Groovy

  // no type declarations needed
  // optional semicolins
  // literal string syntax
  def myList = ['Hello', 'World']
   
  // easy STDOUT printing
  // optional method parentheses
  println myList
view rawbasic.groovy hosted with ❤ by GitHub

Groovy also has very clean and powerful syntax for building complex nested data structures (common in data mapping tasks).

  // list literal syntax (java.util.List under the hood)
  def aList = [1,2,[4,5,6]]
   
  // map literal syntax (java.util.Map)
  def aMap = [
  'name' : 'Tom Smith',
  'dob' : [
  'year':1980,
  'month':3,
  'day': 20
  ]
  ]
view rawliterals.groovy hosted with ❤ by GitHub

For more information on the Groovy language, see the Groovy project home page, this Groovy Syntax Cheat Sheet or this Language Tutorial.

Groovy Builders

Construction of complex hierarchical data structures in Groovy and similar languages uses the ‘builder’ concept. Builders use closures and meta-programming to let developers create the kinds of data structure found in XML, JSON, UI widget hierarchies etc. For example, a basic mapping using a MarkupBuilder:

  def xml = new groovy.xml.MarkupBuilder()
  xml.courses(year:"2013") {
  courseName("Software Engineering")
  courseName("Mechanical Engineering")
  courseName("Electronics Engineering")
  }
   
  /* OUTPUT
   
  <courses year='2013'>
  <courseName>Software Engineering</courseName>
  <courseName>Mechanical Engineering</courseName>
  <courseName>Electronics Engineering</courseName>
  </courses>
   
  */
view rawmarkup.groovy hosted with ❤ by GitHub

And a more complex mapping, with namespaces, using a StreamingMarkupBuilder:

  def comment = "<![CDATA[<!-- address is new to this release -->]]>"
  def builder = new groovy.xml.StreamingMarkupBuilder()
  builder.encoding = "UTF-8"
   
  // MAPPING
  def person = {
  // use mkp object which provides features like setting the namespace
  mkp.xmlDeclaration()
  mkp.declareNamespace('xsi':'http://www.w3.org/2001/XMLSchema-instance')
  mkp.declareNamespace('ca':'http://org.org.org/xsd')
   
  //start with the XML root node closure
  ca.getEnrolledCoursesResponse {
   
  //nested mapping
  student{
  identifier("96678963")
  }
  courseEnrolment {
  status("ACTIVE")
  phoneNumberProvided("true")
  //use mkp object to set the CDATA comment
  mkp.yieldUnescaped(comment)
  }
  }
  }
   
  // WRITING
  def writer = new StringWriter()
  writer << builder.bind(person)
  println writer.toString()
   
  /* OUTPUT
   
  <?xml version="1.0" encoding="UTF-8"?>
  <ca:getEnrolledCoursesResponse xmlns:ca='http://org.org.org/xsd' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <student>
  <identifier>96678963</identifier>
  </student>
  <courseEnrolment>
  <status>ACTIVE</status>
  <phoneNumberProvided>true</phoneNumberProvided>
  <![CDATA[<!-- address is new to this release -->]]>
  </courseEnrolment>
  </ca:getEnrolledCoursesResponse>
   
  */

Hopefully this post has given you a taste of Groovy and how it can be used for creating data structures and writing data mappings. In Part 2 we’ll cover some approaches and helper code to tidy up Groovy data mapping scripts and make your mappings as clear and concise as possible.