Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

...

After finishing the Castor-3066 task two issues were created in Spring SPR JIRA (Applied):
https://jira.springsource.org/browse/SPR-8295
https://jira.springsource.org/browse/SPR-8296

Task Castor-3070 ended with creating task in SPR JIRA (Applied):
https://jira.springsource.org/browse/SPR-8309

For task Castor-3069 another issue has been created (Applied):
https://jira.springsource.org/browse/SPR-8341

The task Castor-3078 has been resolved with SPR issue (Rejected):
https://jira.springsource.org/browse/SPR-8423

Task CASTOR-3099 got his own Spring JIRA issue (Applied):
https://jira.springsource.org/browse/SPR-8453

...

I had prepared the current Castor release (1.3.2) and created a Jira issue in other to contribute it into Spring ERB (Resolved - SpringOXM 3.1 will use Castor 1.3.2):
https://issuetracker.springsource.com/browse/EBR-747

...

In first approche a custom CastorMarshallerListener interface is introduced to, whtich is then used by two addapter classes:

Code Block
javajava
titleCastorMarshallerListener.java
java
public interface CastorMarshallerListener {

	void beforeMarshall(Object target);

	void afterMarshall(Object target);

	void beforeUnmarshall(Object target, Object parent);

	void afterUnmarshall(Object target, Object parent);
}
Code Block
javajava
titleCastorMarshaller inner classes
java
private static class MarshallListenerWrapper implements MarshalListener {

	private CastorMarshallerListener castorMarshallerListener;

	public MarshallListenerWrapper(CastorMarshallerListener castorMarshallerListener) {
		Assert.notNull(castorMarshallerListener, "Parameter 'castorMarshallerListener' can not be null.");

		this.castorMarshallerListener = castorMarshallerListener;
	}

	@Override
	public boolean preMarshal(Object object) {

		castorMarshallerListener.beforeMarshall(object);

		// true means that object will be always marshalled
		return true;
	}

	@Override
	public void postMarshal(Object object) {

		castorMarshallerListener.afterMarshall(object);
	}
}

private static class UnmarshallListenerWrapper implements UnmarshalListener {

	private CastorMarshallerListener castorMarshallerListener;

	public UnmarshallListenerWrapper(CastorMarshallerListener castorMarshallerListener) {
		Assert.notNull(castorMarshallerListener, "Parameter 'castorMarshallerListener' can not be null.");

		this.castorMarshallerListener = castorMarshallerListener;
	}

	@Override
	public void attributesProcessed(Object target, Object parent) {
		// empty method
	}

	@Override
	public void fieldAdded(String fieldName, Object parent, Object child) {
		// empty method
	}

	@Override
	public void initialized(Object target, Object parent) {

		castorMarshallerListener.beforeUnmarshall(target, parent);
	}

	@Override
	public void unmarshalled(Object target, Object parent) {

		castorMarshallerListener.afterUnmarshall(target, parent);
	}
}

The second possibility is to add those listeners to org.springframework.oxm for all marshallers.

Code Block
javajava
titleMarshallerListener.java
java
public interface MarshallerListener {

	void beforeMarshall(Object target);

	void afterMarshall(Object target);
}

Code Block
javajava
titleUnmarshallerListener.java
java
public interface UnmarshallerListener {

	void beforeUnmarshall(Object target, Object parent);

	void afterUnmarshall(Object target, Object parent);
}

...

Currently the Spring OXM XSD looks like this:

Code Block
xmlxml
borderStylesolid
titlespring-oxm-3.1.xsd
xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/oxm" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
			xmlns:beans="http://www.springframework.org/schema/beans"
			xmlns:tool="http://www.springframework.org/schema/tool"
			targetNamespace="http://www.springframework.org/schema/oxm" elementFormDefault="qualified"
			attributeFormDefault="unqualified">

	<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/>
	<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd"/>

	<xsd:annotation>
		<xsd:documentation>
			Defines the elements used in Spring's Object/XML Mapping integration.
		</xsd:documentation>
	</xsd:annotation>

	<xsd:element name="jaxb2-marshaller">
		<xsd:complexType>
			<xsd:annotation>
				<xsd:documentation source="java:org.springframework.oxm.jaxb.Jaxb2Marshaller">
					Defines a JAXB2 Marshaller.
				</xsd:documentation>
				<xsd:appinfo>
					<tool:annotation>
						<tool:exports type="org.springframework.oxm.jaxb.Jaxb2Marshaller"/>
					</tool:annotation>
				</xsd:appinfo>
			</xsd:annotation>
			<xsd:complexContent>
				<xsd:extension base="beans:identifiedType">
					<xsd:sequence>
						<xsd:element name="class-to-be-bound" minOccurs="0" maxOccurs="unbounded">
							<xsd:complexType>
								<xsd:attribute name="name" type="classType" use="required"/>
							</xsd:complexType>
						</xsd:element>
					</xsd:sequence>
					<xsd:attribute name="contextPath" type="xsd:string">
						<xsd:annotation>
							<xsd:documentation>The JAXB Context path</xsd:documentation>
						</xsd:annotation>
					</xsd:attribute>
				</xsd:extension>
			</xsd:complexContent>
		</xsd:complexType>
	</xsd:element>

	<xsd:element name="jibx-marshaller">
		<xsd:complexType>
			<xsd:annotation>
				<xsd:documentation source="java:org.springframework.oxm.jibx.JibxMarshaller">
					Defines a JiBX Marshaller.
				</xsd:documentation>
				<xsd:appinfo>
					<tool:annotation>
						<tool:exports type="org.springframework.oxm.jibx.JibxMarshaller"/>
					</tool:annotation>
				</xsd:appinfo>
			</xsd:annotation>
			<xsd:complexContent>
				<xsd:extension base="beans:identifiedType">
					<xsd:attribute name="target-class" type="classType" use="required"/>
					<xsd:attribute name="bindingName" type="xsd:string">
						<xsd:annotation>
							<xsd:documentation>The binding name used by this marshaller.</xsd:documentation>
						</xsd:annotation>
					</xsd:attribute>
				</xsd:extension>
			</xsd:complexContent>
		</xsd:complexType>
	</xsd:element>

	<xsd:element name="xmlbeans-marshaller">
		<xsd:complexType>
			<xsd:annotation>
				<xsd:documentation source="java:org.springframework.oxm.xmlbeans.XmlBeansMarshaller">
					Defines a XMLBeans Marshaller.
				</xsd:documentation>
				<xsd:appinfo>
					<tool:annotation>
						<tool:exports type="org.springframework.oxm.xmlbeans.XmlBeansMarshaller"/>
					</tool:annotation>
				</xsd:appinfo>
			</xsd:annotation>
			<xsd:complexContent>
				<xsd:extension base="beans:identifiedType">
					<xsd:attribute name="options" type="xsd:string">
						<xsd:annotation>
							<xsd:documentation source="java:org.apache.xmlbeans.XmlOptions">
								The bean name of the XmlOptions that is to be used for this marshaller. Typically a
								XmlOptionsFactoryBean definition.
							</xsd:documentation>
							<xsd:appinfo>
								<tool:annotation kind="ref">
									<tool:expected-type type="org.apache.xmlbeans.XmlOptions"/>
								</tool:annotation>
							</xsd:appinfo>
						</xsd:annotation>
					</xsd:attribute>
				</xsd:extension>
			</xsd:complexContent>
		</xsd:complexType>
	</xsd:element>

	<xsd:simpleType name="classType">
		<xsd:annotation>
			<xsd:documentation source="java:java.lang.Class">A class supported by a marshaller.</xsd:documentation>
			<xsd:appinfo>
				<tool:annotation kind="direct">
					<tool:expected-type type="java.lang.Class"/>
					<tool:assignable-to restriction="class-only" />
				</tool:annotation>
			</xsd:appinfo>
		</xsd:annotation>
		<xsd:union memberTypes="xsd:string"/>
	</xsd:simpleType>

</xsd:schema>

Which allows to configure marshaller in simpler manner.
Examples:

Code Block
xmlxml
borderStylesolid
titleJAXB
xml
<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>
Code Block
xmlxml
borderStylesolid
titleJiBX
xml
<oxm:jibx-marshaller id="marshaller" target-class="org.springframework.ws.samples.airline.schema.Flight"/>
Code Block
xmlxml
borderStylesolid
titleXmlBeans
xml
<oxm:xmlbeans-marshaller id="marshaller"/>

...

The proposal for Castor is to create a element definition that will allow to define a marshaller as below:

Code Block
xmlxml
borderStylesolid
titleCastor
xml
<oxm:castor-marshaller id="marshaller"
encoding="UTF-16"
target-class="org.springframework.ws.samples.airline.schema.Flight"
target-package="org.springframework.ws.samples.airline.schema"
mapping-location="classpath:mapping.xml"/>

...

In other to support the proposed changes a CastorMarshallerBeanDefinitionParser has been introduced, it main role is parsing the castor-marshaller defintion:

Code Block
javajava
borderStylesolid
titleCastorMarshallerBeanDefinitionParser.java
java
public class CastorMarshallerBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser {

	private static final String CASTOR_MARSHALLER_CLASS_NAME = "org.springframework.oxm.castor.CastorMarshaller";

	@Override
	protected String getBeanClassName(Element element) {
		return CASTOR_MARSHALLER_CLASS_NAME;
	}
}

...

Changes were made in unmarshalXmlEventReader and unmarshalXmlStreamReader:

Code Block
javajava
titleCastorMarshaller.java
java
	@Override
	protected final Object unmarshalXmlEventReader(XMLEventReader eventReader) {
		try {
			return createUnmarshaller().unmarshal(eventReader);
		}
		catch (XMLException ex) {
			throw convertCastorException(ex, false);
		}
	}

	@Override
	protected final Object unmarshalXmlStreamReader(XMLStreamReader streamReader) {
		try {
			return createUnmarshaller().unmarshal(streamReader);
		}
		catch (XMLException ex) {
			throw convertCastorException(ex, false);
		}
	}

...

The idea is to extend previously defined element with additional attributes.
For example:

Code Block
xmlxml
borderStylesolid
titleCastor-Marshaller additional attributes
xml
	<xsd:attribute name="validating" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the marshaller should validate
				documents.</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="whitespace-preserve" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the unmarshaller should preserve
				whitespaces.</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="ignore-extra-attributes" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the unmarshaller should ignore
				additional attributes that do not much any field.
			</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="ignore-extra-elements" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the unmarshaller should ignore
				additional elements that do not much any field.
			</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="suppress-namespaces" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the marshaller should write namespaces
				in output xml.
			</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="suppress-xsi-type" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the marshaller should write xsi:type
				attribute in output xml.
			</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="marshal-as-document" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the output xml should be marshalled
				into document.</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="root-element" type="xsd:string">
		<xsd:annotation>
			<xsd:documentation>The name of the root element.
			</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="marshal-extended-type" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the output xml should contain
				'xsi:type' attribute.</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="schema-location" type="xsd:string">
		<xsd:annotation>
			<xsd:documentation>The path to schema file used for
				'xsi:schemaLocation'.</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="no-namespace-schema-location" type="xsd:string">
		<xsd:annotation>
			<xsd:documentation>The path to schema file used for
				'xsi:noNamespaceSchemaLocation'.</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="use-xsi-type-at-root" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the output xml should contain
				'xsi:type' attribute for root element.</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="reuse-objects" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the unmarshaller should reuse objects.
			</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="clear-collections" type="xsd:boolean">
		<xsd:annotation>
			<xsd:documentation>Whether the unmarshaller should clear
				collections.</xsd:documentation>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="processing-instructions-ref"
				   type="xsd:string">
		<xsd:annotation>
			<xsd:documentation>The processing instruction used by
				unmarshaller.</xsd:documentation>
			<xsd:appinfo>
				<tool:annotation kind="ref">
					<tool:expected-type type="java.util.Map"/>
				</tool:annotation>
			</xsd:appinfo>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="namespace-to-package-mapping-ref"
				   type="xsd:string">
		<xsd:annotation>
			<xsd:documentation>Map containing namespace to package
				mapping.
			</xsd:documentation>
			<xsd:appinfo>
				<tool:annotation kind="ref">
					<tool:expected-type type="java.util.Map"/>
				</tool:annotation>
			</xsd:appinfo>
		</xsd:annotation>
	</xsd:attribute>
	<xsd:attribute name="object-ref" type="xsd:string">
		<xsd:annotation>
			<xsd:documentation>The expected object instance.
			</xsd:documentation>
			<xsd:appinfo>
				<tool:annotation kind="ref">
					<tool:expected-type type="java.lang.Object"/>
				</tool:annotation>
			</xsd:appinfo>
		</xsd:annotation>
	</xsd:attribute>


...