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