Version 2

    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();