Hi,

I have a tricky situation which I cannot see how to implement using the vanilla library, so I've written (the basics) of a new class. I'd be very interested on any thoughts on the problem and my proposed solution.

The problem is basically combining contexts from separate libraries. In my project, there is a core framework set of classes which may be extended by plug-in jar files. The core framework is responsible for initiating the marshalling of a data stream, but at some point in the hierarchy this may (and indeed does) switch to marshalling classes from one of the plug-in libraries. Obviously, as this plug-in is compiled separately from the main classes (along with any bindings it needs) the initial context knows nothing about these classes.

My current solution is to create a CompositeBindingFactory class (code below), which combines various IBindingFactory instances into a single instance that may be used to marshal all the data. This appears to work fine in my (limited) testing so far. I don't currently use unmarshalling, and have not tested that side of things, but I see no reason in principal why this would not work. It also requires the addition of getMarshallers() and getUnmarshallers() methods to the IBindingFactory interface and generated definitions.

It is, however, a bit messy, and extremely dependent on the current implementation of the marshalling classes. Also, it requires that the root object to be marshalled is in the first binding factory loaded (otherwise the lookup on index will fail). This is not ideal, but is not a show stopper for me.

Loading a factory is as simple as:

IBindingFactory bfact = BindingDirectory.getFactory(AnyMappedClass.class);
   CompositeBindingFactory.getInstance().addFactory(bfact);

where AnyMappedClass has a mapping in the required daactory. It would be better if it were possible to specify the factory name in the binding definition and then load it directly by that name, but I'm not sure how hard that would be.

Using it is also simple, just:

   CompositeBindingFactory cbfact = CompositeBindingFactory.getInstance();
   IMarshallingContext ictx = cbfact.createMarshallingContext();
   ictx.marshalDocument(...);

The class itself is pretty straight forward, and probably not the best implementation, but I thought I'd see what you guys thought before I went any further.

Cheers,

Bill
--


public class CompositeBindingFactory implements IBindingFactory {

   private static CompositeBindingFactory m_inst;
   private String m_distrib;
   private int m_version;
   private List m_uris;
   private List m_prefixes;
   private List m_classes;
   private List m_marshallers;
   private List m_unmarshallers;
   private List m_globalUris;
   private List m_globalNames;
   private List m_idNames;

   public CompositeBindingFactory() {
       // create arrays = global uris and names are null terminated
       m_uris = new ArrayList();
       m_prefixes = new ArrayList();
       m_classes = new ArrayList();
       m_marshallers = new ArrayList();
       m_unmarshallers = new ArrayList();
       m_globalUris = new ArrayList();
       m_globalUris.add(null);
       m_globalNames = new ArrayList();
       m_globalNames.add(null);
       m_idNames = null;       // not sure what this does???
   }

public IMarshallingContext createMarshallingContext() throws JiBXException {
       return new MarshallingContext(
           getMappedClasses(),
           getMarshallers(),
           getNamespaces(),
           this);
   }

public IUnmarshallingContext createUnmarshallingContext() throws JiBXException {
       if (m_unmarshallers.size() == 0) {
throw new UnsupportedOperationException("binding is output only - cannot create unmarshaller");
       }
       return new UnmarshallingContext(
           getUnmarshallers().length,  // is this the correct size?
           getUnmarshallers(),
           getElementNamespaces(),
           getNamespaces(),
           null,                       //  m_idNames
           this);
   }

   public String getCompilerDistribution() {
       return m_distrib;
   }

   public int getCompilerVersion() {
       return m_version;
   }

   public String[] getNamespaces() {
       return m_uris.size() == 0
           ? null
           : (String[])m_uris.toArray(new String[m_uris.size()]);
   }

   public String[] getPrefixes() {
       return m_prefixes.size() == 0
           ? null
           : (String[])m_prefixes.toArray(new String[m_prefixes.size()]);
   }

   public String[] getMappedClasses() {
       return m_classes.size() == 0
           ? null
           : (String[])m_classes.toArray(new String[m_classes.size()]);
   }

   public String[] getMarshallers() {
       return m_marshallers.size() == 0
           ? null
: (String[])m_marshallers.toArray(new String[m_marshallers.size()]);
   }

   public String[] getUnmarshallers() {
       return m_unmarshallers.size() == 0
           ? null
: (String[])m_unmarshallers.toArray(new String[m_unmarshallers.size()]);
   }

   public String[] getElementNamespaces() {
return (String[])m_globalUris.toArray(new String[m_globalUris.size()]);
   }

   public String[] getElementNames() {
return (String[])m_globalNames.toArray(new String[m_globalNames.size()]);
   }

   public int getTypeIndex(String arg0) {
       // TODO - needs correct implementation - not used here
       return -1;
   }

   public void addFactory(IBindingFactory factory) throws JiBXException {
       if (m_distrib == null) {
           m_distrib = factory.getCompilerDistribution();
       } else if (!m_distrib.equals(factory.getCompilerDistribution())) {
throw new JiBXException("all added factories must have the same compiler distribution");
       }
       if (m_version == 0) {
           m_version = factory.getCompilerVersion();
       } else if (m_version != factory.getCompilerVersion()) {
throw new JiBXException("all added factories must have the same compiler version");
       }
       if (factory.getNamespaces() != null) {
           m_uris.addAll(Arrays.asList(factory.getNamespaces()));
       }
       if (factory.getPrefixes() != null) {
           m_prefixes.addAll(Arrays.asList(factory.getPrefixes()));
       }
       if (factory.getMappedClasses() != null) {
           m_classes.addAll(Arrays.asList(factory.getMappedClasses()));
       }
       if (factory.getMarshallers() != null) {
           m_marshallers.addAll(Arrays.asList(factory.getMarshallers()));
       }
       if (factory.getUnmarshallers() != null) {
m_unmarshallers.addAll(Arrays.asList(factory.getUnmarshallers()));
       }
       if (factory.getElementNamespaces().length > 1) {
           m_globalUris.remove(m_globalUris.size() - 1);
m_globalUris.addAll(Arrays.asList(factory.getElementNamespaces()));
       }
       if (factory.getElementNames().length > 1) {
           m_globalNames.remove(m_globalNames.size() - 1);
           m_globalNames.addAll(Arrays.asList(factory.getElementNames()));
       }
   }
public static CompositeBindingFactory getInstance() {
       if (m_inst == null) {
           m_inst = new CompositeBindingFactory();
       }
       return m_inst;
   }

}



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
jibx-devs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jibx-devs

Reply via email to