Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: Navigate data with the Mapper framework

Navigate data with the Mapper framework

Tutorial Details:

Navigate data with the Mapper framework
Navigate data with the Mapper framework
By: By Snehal Patel
Build your own data mapping system with an interlingual approach
ost developers, at some point, have written software to move (and/or manipulate) data from two different data sources. Usually, the software that tackles this job is custom code specific to the data entities involved and the data itself. Fueling the fire, good data mapping software is typically very expensive for organizations with tight IT budgets, especially in today's market. The Mapper framework offers a simple and inexpensive (free) way for you to read from one data entity and write to another with minimal coding and maintenance.
In this article, I first explain the system's overall design and then demonstrate how the framework operates by mapping between a file and a database table. Using this example as a template, you'll be able to add other entities as your own specific requirements dictate and map data between them as easily as editing a few XML lines.
The framework
In Chapter 8.2 of the online book Survey of the State of the Art in Human Language Technology , Martin Kay explains that one algorithm for Machine Translation (MT), which translates text from one natural language (like English) to another, works by parsing the source text into a standard semantic form using the source language's grammar rules. It then applies the target language's grammar rules to the standard form to yield the desired translation. Of course, this is an oversimplification of how MT actually works, but this straightforward process, called the interlingual approach in MT, is the basis for the Mapper framework.
In contrast to the interlingual approach, another algorithm called the transfer approach attempts to translate texts by having a separate translation module from the source language to the target language. Given n languages in a system, n(n-1) translation mechanisms must translate each language to every other language. However, a solution similar to the interlingual approach significantly reduces the complexity of translating the languages, requiring only 2n translation mechanisms. The Mapper framework applies the interlingual approach to mapping data entities in a system, thereby making the system maintainable and easily extendable. The following figure illustrates this approach.
The Mapper framework's interlingual approach
The framework's semantic representation of data, for simplicity's sake, is a HashMap called MapperRecord (of course, you can use XML as an alternative representation). In addition, the Entity interface represents each data entity:
public class MapperRecord extends java.util.HashMap {
}
public interface Entity {
public static int READ = 0;
public static int WRITE = 1;
public void open() throws MapperException; //Open the entity for reading or writing
public void close() throws MapperException; //Close all reading and writing
resources
public MapperRecord readRecord() throws MapperException; //Read/translate
record from
//Data entity into a MapperRecord
public void writeRecord(MapperRecord record) throws MapperException; //Write
MapperRecord to the data entity
}
You should apply the following rules to smoothly map between arbitrary data entities:
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.
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.
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 ):



















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:
//Constructor that creates a file entity
public FileEntity(String entityAlias, int operation) {
this.fileAlias = entityAlias;
this.operation = operation;
}
//Sets filename
public void setFileName(String fName) {
this.fileName = fName;
}
//Reads record from buffered reader and returns a MapperRecord
public MapperRecord readRecord() throws MapperException {
//. . .
return (MapperRecord)transformLine(record);
//. . .
}
//Transforms record to MapperRecord based on xml specs
private MapperRecord transformLine(String record) {
MapperRecord rec = new MapperRecord(); //Create empty mapper record
HashMap map = (HashMap)mapList.get(fileMapName); //Get map
ArrayList fieldList = (ArrayList)map.get(FIELD_LIST); //Get field list
//If delimiter specified, then tokenize and place data in mapper record
if (map.get(DELIMITER) != null) {
StringTokenizer st = new StringTokenizer(record,(String)map.get(DELIMITER));
for (Iterator fieldIterator = fieldList.iterator();
fieldIterator.hasNext() && st.hasMoreElements(); ) {
HashMap field = (HashMap)fieldIterator.next();
rec.put(field.get(FIELD_NAME),(String)st.nextToken());
}
}
//Have to parse record based on fixed lengths specified for each field
else {
for (Iterator i = fieldList.iterator(); i.hasNext(); ) {
HashMap field = (HashMap)i.next();
int start = (new Integer((String)field.get(START))).intValue();
int end = (new Integer((String)field.get(END))).intValue();
String str;
try {
str = ((String)record.substring(start-1,end));
} catch (StringIndexOutOfBoundsException e) { //Reached end of record
try { //Get remaining data
str = ((String)record.substring(start-1));
} catch (StringIndexOutOfBoundsException ex) {
str = record;
}
}
rec.put(field.get(FIELD_NAME),str);
}
}
return rec;
}
If you create a Perl script for each file format your system handles, you should consider using this entity as an alternative to flat-file parsing. By placing the file format descriptions in an XML file, you can parse just about any file format -- comma delimited, pipe delimited, fixed length, and so on -- without writing any code (assuming the code in readRecord() can handle it). You'll save yourself from writing tedious custom code and you'll have the data records in a standard format to use with other business objects. Further, since the FileEntity object is a bidirectional map, it can also write data records in delimited or fixed-length format. The code for writeRecord() isn't shown above, but the code is just as straightforward; see this article's source code .
Read from and write to any table
The TableEntity also uses XML data mapping rules to place MapperRecords into a table called T_STAGING_TABLE , based on the field names keyed in the MapperRecord object and the column names supplied:



driver="oracle.jdbc.driver.OracleDriver"
connect-string="jdbc:oracle:thin:user/pass@localhost


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Navigate data with the Mapper framework

View Tutorial:
Navigate data with the Mapper framework

Related Tutorials:

Mapping XML to Java, Part 2 - JavaWorld October 2000
Mapping XML to Java, Part 2 - JavaWorld October 2000
 
Connect the enterprise with the JCA, Part 2
Connect the enterprise with the JCA, Part 2
 
Navigate data with the Mapper framework
Navigate data with the Mapper framework
 
Transform data into Web applications with Cocoon
Transform data into Web applications with Cocoon
 
Big designs for small devices
Big designs for small devices
 
Navigate through virtual worlds using Java 3D
Navigate through virtual worlds using Java 3D
 
Very interesting article
Very interesting article
 
Related Values Processing Framework (RVPF)
Related Values Processing Framework (RVPF) Overview The Related Values Processing Framework is being developed to help the integration of Process Control Data Historian Systems. This is done by providing support for the conversion, computation and di
 
Framework for Java Database Connectivity
What is Framework for Java Database Connectivity? The Framework for Java Database Connectivity (JDBC) was implemented to demonstrate the ease with which a JavaTM application may be designed to access a source code repository using a relational query lang
 
Introduction to Jena
Introduction to Jena Use RDF models in your Java applications with the Jena Semantic Web Framework RDF is increasingly recognized as an excellent choice for representing and processing semi-structured data. In this article, Web Developer Philip McCart
 
Ease Swing development with the TableModel Free framework
This article introduces the TableModel Free (TMF) framework which eliminates the need to use TableModels with Swing JTables. The TMF framework allows for more configurable JTables by moving all of table-specific data outside of the compiled code and into
 
datasift (Data validation + transformation framework)
What is DataSift? DataSift is a powerful java data validation and transformation framework, aimed at enterprise software development, which provides developers with an extensible architecture they can fully adapt to their software needs. Almost every fea
 
Welcome to the Apache Struts Tutorial
This is the complete Struts Tutorial. Explains ActionForm Action Class Validation Framework.
 
Struts and Tiles aid component-based development
In the Java world, Struts is one of the best-known and most talked about open source embodiments of MVC.
 
Jakarta Struts Interview Questions
Jakarta Struts Interview Questions Jakarta Struts Interview Questions Q: What is Jakarta Struts Framework? A: Jakarta Struts is open source implementation of MVC (Model-View-Controller) pattern for the development of web based applications.
 
Buy KANOTIX BUG HUNTER 09-2004-A Live CDs in India from us. KANOTIX BUG HUNTER 09-2004-A Live is available with us.
Buy KANOTIX BUG HUNTER 09-2004-A Live CDs in India from us. KANOTIX BUG HUNTER 09-2004-A Live is available with us. KANOTIX BUG HUNTER 09-2004-A Live Linux Now Available KANOTIX BUG HUNTER 09-2004-A Live CD's Kanotix is a Linux Live CD based on
 
Client Side Address Validation in Struts
Client Side Address Validation in Struts Client Side Address Validation in Struts In this lesson we will create JSP page for entering the address and use the functionality provided by Validator Framework to validate the user data on the browser.
 
Beginner to advance guide to the Apache Struts
Beginner to advance guide to the Apache Struts The Complete Apache Struts Tutorial This complete reference of Jakarta Struts shows you how to develop Struts applications using ant and deploy on the JBoss Application Server. Ant script is provided
 
DB Solo - Database development and management tool
DB Solo is a powerful database development and management tool for developers and DBAs. DB Solo has an intuitive user interface that allows you to explore and manage your database objects as well as execute your own ad-hoc queries.
 
Enhance your end-user MDI experience with JExplose
Enhance your end-user MDI experience with *JExplose* ! Extremely simple to integrate with your existing Swing MDI products.
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.