Generic Object Model Factory
There is an alternative way to implement object model factories by implementing the
GenericObjectModelFactory
interface which extends the ObjectModelFactory interface. Here is its definition.
package org.jboss.xml.binding; public interface GenericObjectModelFactory extends ObjectModelFactory { Object newChild(java.lang.Object parent, org.jboss.xml.binding.ContentNavigator navigator, java.lang.String namespaceURI, java.lang.String localName, org.xml.sax.Attributes attrs); void addChild(java.lang.Object parent, java.lang.Object child, org.jboss.xml.binding.ContentNavigator navigator, java.lang.String namespaceURI, java.lang.String localName); void setValue(java.lang.Object o, org.jboss.xml.binding.ContentNavigator navigator, java.lang.String namespaceURI, java.lang.String localName, java.lang.String value); }
Arguments to
newChild
,
addChild
and
setValue
methods that in (direct)
ObjectModelFactory
implementation were of concrete Java types but not
java.lang.Object
are of
java.lang.Object
type in
GenericObjectModelFactory
. Implementations of
GenericObjectModelfactory
are not introspected to find
newChild
,
addChild
and
setValue
methods with arguments of concrete Java types. Instead, the three generic methods are used for all Java types and XML elements they represent.
Code example
Here is an implementation of
GenericObjectModelFactory
for book.
public class BookGenericObjectModelFactory implements GenericObjectModelFactory { public Object newRoot(Object root, ContentNavigator navigator, String namespaceURI, String localName, Attributes attrs) { final Book book; if(root == null) { root = book = new Book(); } else { book = (Book) root; } if(attrs.getLength() > 0) { for(int i = 0; i < attrs.getLength(); ++i) { if(attrs.getLocalName(i).equals("isbn")) { book.setIsbn(attrs.getValue(i)); } } } return root; } public Object newChild(Object parent, ContentNavigator navigator, String namespaceURI, String localName, Attributes attrs) { Object child = null; if(parent instanceof Book) { if("character".equals(localName)) { child = new BookCharacter(); } } return child; } public void addChild(Object parent, Object child, ContentNavigator navigator, String namespaceURI, String localName) { if(parent instanceof Book) { final Book book = (Book)parent; if(child instanceof BookCharacter) { book.addCharacter((BookCharacter)child); } } } public void setValue(Object o, ContentNavigator navigator, String namespaceURI, String localName, String value) { if(o instanceof Book) { final Book book = (Book)o; if("title".equals(localName)) { book.setTitle(value); } else if("author".equals(localName)) { book.setAuthor(value); } } else if(o instanceof BookCharacter) { BookCharacter character = (BookCharacter)o; if("name".equals(localName)) { character.setName(value); } else if("friend-of".equals(localName)) { character.setFriendOf(value); } else if("since".equals(localName)) { character.setSince(value); } else if("qualification".equals(localName)) { character.setQualification(value); } } } }
Unmarshalling client
Unmarshalling client code is the same as in the example for
ObjectModelFactory
except for one line which creates an object model factory.
// get the XML stream InputStream is = new FileInputStream("resources/xml/book/" + xmlSource); // create unmarshaller Unmarshaller unmarshaller = new Unmarshaller(); // create an instance of ObjectModelFactory ObjectModelFactory factory = new BookGenericObjectModelFactory(); // let the object model factory to create an instance of Book and populate it with data from XML Book book = (Book)unmarshaller.unmarshal(is, factory, null); // close the XML stream is.close();
Comments