Generic Object Model Provider
An alternative way to implement object model providers is to implement GenericObjectModelProvider interface which extends ObjectModelProvider interface. Here is the definition of the GenericObjectModelProvider.
public interface GenericObjectModelProvider extends ObjectModelProvider { java.lang.Object getChildren(java.lang.Object o, java.lang.String namespaceURI, java.lang.String localName); java.lang.Object getElementValue(java.lang.Object o, java.lang.String namespaceURI, java.lang.String localName); java.lang.Object getAttributeValue(java.lang.Object o, java.lang.String namespaceURI, java.lang.String localName); }
Direct implementations of ObjectModelProvider interface can be thought of as "typed" providers in a sense that arguments of
getChildren
,
getElementValue
and
getAttributeValue
methods are supposed to be of concrete Java types (other than java.lang.Object) from the target class hierarchy. Contrary, in GenericObjectModelFactory these arguments are of type
java.lang.Object
. The framework won't introspect an implementation of GenericObjectModelProvider to find "typed" implementations of
getChildren
,
getElementValue
and
getAttributeValue
. Instead it will call the generic methods.
Code example
Here is an example of GenericObjectModelProvider implementation for the book.
public class BookGenericObjectModelProvider implements GenericObjectModelProvider { public Object getRoot(Object o, String namespaceURI, String localName) { return o; } public Object getChildren(Object o, String namespaceURI, String localName) { Object children = null; if(o instanceof Book) { Book book = (Book)o; if(localName.equals("character")) { children = book.getCharacters(); } else if(localName.equals("book")) { children = book; } } return children; } public Object getElementValue(Object o, String namespaceURI, String localName) { Object value = null; if(o instanceof Book) { Book book = (Book)o; if("title".equals(localName)) { value = book.getTitle(); } else if("author".equals(localName)) { value = book.getAuthor(); } } else if(o instanceof BookCharacter) { BookCharacter character = (BookCharacter)o; if("name".equals(localName)) { value = character.getName(); } else if("friend-of".equals(localName)) { value = character.getFriendOf(); } else if("since".equals(localName)) { value = character.getSince(); } else if("qualification".equals(localName)) { value = character.getQualification(); } } return value; } public Object getAttributeValue(Object o, String namespaceURI, String localName) { Object value = null; if(o instanceof Book) { Book book = (Book)o; if("isbn".equals(localName)) { value = book.getIsbn(); } } return value; } }
Marshalling client code
The only difference in the client code which uses GenericObjectModelProvider implementation instead of ObjectModelProvider implementation is the line which creates an instance of the provider. Here is an example for a DTD based marshalling.
// obtain an instance of Book to marshal Book book = createBook(); // get the output writter to write the XML content StringWriter xmlOutput = new StringWriter(); // get the DTD source InputStream is = getResource("xml/book/books.dtd"); Reader dtdReader = new InputStreamReader(is); // create an instance of DTD marshaller Marshaller marshaller = new DtdMarshaller(); // map publicId to systemId as it should appear in the resulting XML file marshaller.mapPublicIdToSystemId("-//DTD Books//EN", "resources/xml/book/books.dtd"); // create an instance of ObjectModelProvider with the book instance to be marshalled ObjectModelProvider provider = new BookGenericObjectModelProvider(); // marshal the book marshaller.marshal(dtdReader, provider, book, xmlOutput); // close DTD reader dtdReader.close();
Comments