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