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<something>” then place the returned value in a new child element of the document. Obviously the method getClass() will match this criteria and it is handled specially; its added as a comment, not an element.
[java]
/**
*
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.
*
*
*
*
*
*
*
*
* @author Michael Cutler ([email protected])
* @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 ) { }
}
}
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 );
}
[/java]
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.
[java]
package com.company.value;
/**
* @author Michael Cutler ([email protected])
* @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;
}
}
[/java]
Fed into my digestObject() method the resulting Document would look something like:
[xml]
[/xml]
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…
Leave a Reply