package example22; import java.io.OutputStream; import java.io.Writer; import org.jibx.runtime.BindingDirectory; import org.jibx.runtime.IBindingFactory; import org.jibx.runtime.IMarshallable; import org.jibx.runtime.IUnmarshallingContext; import org.jibx.runtime.JiBXException; import org.jibx.runtime.impl.MarshallingContext; import org.jibx.runtime.impl.UnmarshallingContext; public class BindingSelector { /** URI of version selection attribute. */ private final String m_attributeUri; /** Name of version selection attribute. */ private final String m_attributeName; /** Array of version names. */ private final String[] m_versionTexts; /** Array of bindings corresponding to versions. */ private final String[] m_versionBindings; /** Basic unmarshalling context used to determine document version. */ private final UnmarshallingContext m_context; /** Stream for marshalling output. */ private OutputStream m_outputStream; /** Encoding for output stream. */ private String m_outputEncoding; /** Output writer for marshalling. */ private Writer m_outputWriter; /** Indentation for marshalling. */ private int m_outputIndent; /** * Constructor. * * @param uri version selection attribute URI (null if none) * @param name version selection attribute name * @param versions array of version texts (first is default) * @param bindings array of binding names corresponding to versions */ public BindingSelector(String uri, String name, String[] versions, String[] bindings) { m_attributeUri = uri; m_attributeName = name; m_versionTexts = versions; m_versionBindings = bindings; m_context = new UnmarshallingContext(); m_outputIndent = -1; } /** * Get initial unmarshalling context. This gives access to the unmarshalling * context used before the specific version is determined. The document * information must be set for this context before calling {@link * #unmarshalVersioned}. * * @return initial unmarshalling context */ public IUnmarshallingContext getContext() { return m_context; } /** * Set output stream and encoding. * * @param outs stream for document data output * @param enc document output encoding, or null for default */ void setOutput(OutputStream outs, String enc) { m_outputStream = outs; m_outputEncoding = enc; } /** * Set output writer. * * @param outw writer for document data output */ void setOutput(Writer outw) { m_outputWriter = outw; } /** * Set nesting indent spaces. * * @param indent number of spaces to indent per level, or disable * indentation if negative */ void setIndent(int indent) { m_outputIndent = indent; } /** * Marshal according to supplied version. * * @param obj root object to be marshalled * @param version identifier for version to be used in marshalling * @throws JiBXException if error in marshalling */ public void marshalVersioned(Object obj, String version) throws JiBXException { // look up version in defined list String match = (version == null) ? m_versionTexts[0] : version; for (int i = 0; i < m_versionTexts.length; i++) { if (match.equals(m_versionTexts[i])) { // version found, create marshaller for the associated binding IBindingFactory fact = BindingDirectory. getFactory(m_versionBindings[i], obj.getClass()); MarshallingContext context = (MarshallingContext)fact.createMarshallingContext(); // configure marshaller for writing document context.setIndent(m_outputIndent); if (m_outputWriter == null) { if (m_outputStream == null) { throw new JiBXException("Output not configured"); } else { context.setOutput(m_outputStream, m_outputEncoding); } } else { context.setOutput(m_outputWriter); } // output object as document context.startDocument(m_outputEncoding, null); ((IMarshallable)obj).marshal(context); context.endDocument(); return; } } // error if unknown version in document throw new JiBXException("Unrecognized document version " + version); } /** * Unmarshal according to document version. * * @param clas expected class mapped to root element of document (used only * to look up the binding) * @return root object unmarshalled from document * @throws JiBXException if error in unmarshalling */ public Object unmarshalVersioned(Class clas) throws JiBXException { // get the version attribute value (using first value as default) m_context.toStart(); String version = m_context.attributeText(m_attributeUri, m_attributeName, m_versionTexts[0]); // look up version in defined list for (int i = 0; i < m_versionTexts.length; i++) { if (version.equals(m_versionTexts[i])) { // version found, create unmarshaller for the associated binding IBindingFactory fact = BindingDirectory. getFactory(m_versionBindings[i], clas); UnmarshallingContext context = (UnmarshallingContext)fact.createUnmarshallingContext(); // return object unmarshalled using binding for document version context.setFromContext(m_context); return context.unmarshalElement(); } } // error if unknown version in document throw new JiBXException("Unrecognized document version " + version); } }