Java Object Digester
I was working on a web-based application recently and wanted a lazy way to get data from a simple 'value object' out to the front end without having any hard-coded field names; I came up with this. Basically, this method will take any Object, iterate through its methods looking for any of the format "get
/**
* Converts a 'value object' into a Document.
* This method is expecting a simple value object, it will iterate through a list of * the objects methods looking for "get*" methods. The remainder of the method name * is considered the 'field name' ie. getName() - "Name".
* The generated document will contain a root element based on the name of the given * object. Each of its non-null fields will then follow as child elements.
* For example, class com.company.value.User which contains methods getName, getEmail and * getPhoneNumber.
*
* <user>
* <name>Michael</name>
* <email>name@address.com</email>
* <phonenumber>555-3454</phonenumber>
* </user>
*
* @author Michael Cutler (m@cotdp.com)
* @param obj the value object to digest into a Document
* @return A document containing the values of all the fields in the object
* @throws ParserConfigurationException thrown if the XML documentbuilder fails
*/
public static Document digestObject(Object obj) throws ParserConfigurationException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();
Node rootElement = document.createElement(getClassName(obj));
document.appendChild(rootElement);
Method methods[] = obj.getClass().getMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (method.getName().startsWith("get")) {
String fieldName = method.getName().substring(3);
try {
Object result = method.invoke(obj, null);
if (result != null) {
if (fieldName.equals("Class")) {
Node child = document.createComment(result.toString() + " ");
rootElement.appendChild(child);
} else {
Node child = document.createElement(fieldName);
Node text = document.createTextNode(result.toString());
child.appendChild(text);
rootElement.appendChild(child);
}
}
} catch (Exception e) {
// Silent catch - could log error if needed
}
}
}
return document;
}
/**
* This method is package/no-package safe, lastIndexOf('.') will return -1 if
* not found, since we add 1 to skip the '.' character anyway there is no problem
* if '.' isn't found.
*
* @return a string representing the name of the class (without package name)
*/
private static String getClassName(Object obj) {
String name = obj.getClass().getName();
return name.substring(name.lastIndexOf('.') + 1);
}
For example, if your application stores information about a user - their name, email address & phone number - it may use a simple User value object shown below to represent that information.
package com.company.value;
/**
* @author Michael Cutler (m@cotdp.com)
* @version 1.0
*/
public class User {
private String name;
private String email;
private String phoneNumber;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
Fed into my digestObject()
method the resulting Document would look something like:
<user>
<name>Michael Cutler</name>
<email>name@address.com</email>
<phonenumber>555-3454</phonenumber>
</user>
With your data now in XML you can easily apply XSL transforms on it to render a HTML view or form, use XPath or Schema validation against it to validate the structure of the document and its data or, output it to another system like Velocity for example... Any comments / questions please post them here, Thanks...
Related Posts
Hadoop: Processing ZIP files in Map/Reduce
Updated ZipFileInputFormat framework for processing thousands of ZIP files in Hadoop with failure tolerance and comprehensive examples
Consuming Twitter streams from Java
Build a Java utility class to consume Twitter Streaming API data for offline analysis in Hadoop with automatic file segmentation
Reading ZIP files from Hadoop Map/Reduce
Custom utility classes to extract and parse ZIP file contents in Hadoop MapReduce jobs using ZipFileInputFormat and ZipFileRecordReader