Featured Whitepapers
Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Navigate data with the Mapper framework

Build your own data mapping system with an interlingual approach

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 2 of 5

  1. Every Entity implementation creates a bidirectional map between the data entity it represents and a MapperRecord -- mandated by the Entity interface. It should know how to marshal (or translate) data from its data source into a MapperRecord, as well as write a MapperRecord's contents to its respective data store.
  2. The rules (or grammar) for mapping between the data entity and the MapperRecord object are placed in an XML file that the entity parses at runtime.
  3. Every Entity implementation has a two-parameter constructor: the name of the map to use and the operation to perform (Entity.READ or Entity.WRITE). All other object variables should be accessible via getter and setter methods. (I will clarify later why this rule is necessary):

    protected String fileName;
    //Constructor that creates a file entity
    public FileEntity(String entityAlias, int operation) {
       this.fileMapName = entityAlias;
       this.operation = operation;
    }
    public void setFileName(String fName) { //Sets filename
       this.fileName = fName;
    }
    public String getFileName() { //Gets filename
       return this.fileName;
    }
    


Once all the framework's entities can successfully create and store MapperRecords based on XML metadata, you can effortlessly create execution paths to map data from one to another:

Entity readEntity = new FileEntity("from_map",Entity.READ);
readEntity.setFileName("/tmp/from.txt");
Entity writeEntity = new TableEntity("table_map",Entity.WRITE);
//Open entities for reading and writing
readEntity.open();
writeEntity.open();
//For each read record, write record to write entity
MapperRecord record;
while ((record = (MapperRecord)readEntity.readRecord()) != null) {
   if (record.isEmpty()) {
      continue;
   }
   writeEntity.writeRecord(record);
}
//Close entities
writeEntity.close();
readEntity.close();


The classic case

I originally designed this framework to reliably parse and create transaction-laden text files for exchange with business affiliates. Creating a custom Perl script for each affiliate's incoming (and outgoing) file formats is an arduous task for any development team, without even considering the testing and maintenance nightmares. As an alternative to Perl scripting, this reusable and extendable application pattern reduces the time spent on the development lifecycle's latter stages.

So let's start with the classic example of reading records from a text file and writing them to a database to show how well the design works. Creating the two entities, FileEntity and TableEntity, which implement the Entity interface, is fairly simple.

Parse and create any data file

The FileEntity class parses an XML file, like the following, to load different file formats into memory (using Apache's Xerces SAX parser):

<!-- FileEntityList.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<filemaps>
  <map name="from_map" delimiter="," > <!-- comma-delimited file 
format -->
    <field name="id" />
    <field name="amount" />
    <field name="date" />
  </map>
  <map name="to_map" delimiter="|" > <!-- pipe-delimited file format 
-->
    <field name="date" />
    <field name="amount" />
    <field name="id" />
  </map>
  <map name="fixed_map"> <!--fixed-length file format -->
      <field name="id" start="1" end="2" />
      <field name="amount" start="3" end="32" />
      <field name="date" start="33" end="62" />
  </map>
</filemaps>


The from_map map describes a comma-delimited file format while the fixed_map map describes a fixed-length file format. Armed with the my_map file format, the READ operation, and a filename, FileEntity's readRecord() method can marshal the file's comma-delimited records into a MapperRecord keyed by the field names in the XML file:

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources