modified unmarshalling transformer to support payloads consistently with xslt transformer INT-311

This commit is contained in:
Jonas Partner
2008-08-19 12:33:46 +00:00
parent 94746fb6a4
commit 6c76f5b3bd
16 changed files with 241 additions and 70 deletions

View File

@@ -26,6 +26,7 @@ import org.springframework.integration.xml.result.DomResultFactory;
import org.springframework.integration.xml.result.StringResultFactory;
import org.springframework.integration.xml.transformer.XmlPayloadMarshallingTransformer;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
@@ -45,10 +46,15 @@ public class XmlMarshallingTransformerParser extends
ParserContext parserContext, BeanDefinitionBuilder builder) {
String resultFactory = element.getAttribute("result-factory");
String marshaller = element.getAttribute("marshaller");
String resultTransformer = element.getAttribute("result-transformer");
Assert.hasText(marshaller, "the 'marshaller' attribute is required");
Assert.hasText(resultFactory,
"the 'result-factory' attribute is required");
builder.addConstructorArgReference(marshaller);
if(StringUtils.hasText(resultTransformer)){
builder.addConstructorArgReference(resultTransformer);
}
if (resultFactory.equals("DOMResult")) {
try {

View File

@@ -41,6 +41,8 @@ public class XsltPayloadTransformerParser extends AbstractPayloadTransformerPars
protected void parsePayloadTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String xslResource = element.getAttribute("xsl-resource");
String xslTemplates = element.getAttribute("xsl-templates");
String resultTransformer = element.getAttribute("result-transformer");
boolean bothHaveText = StringUtils.hasText(xslResource) && StringUtils.hasText(xslTemplates);
boolean oneHasText = StringUtils.hasText(xslResource) || StringUtils.hasText(xslTemplates);
Assert.state(!bothHaveText && oneHasText,
@@ -61,6 +63,10 @@ public class XsltPayloadTransformerParser extends AbstractPayloadTransformerPars
if (StringUtils.hasText(resultFactory)) {
builder.addPropertyReference("resultFactory", resultFactory);
}
if(StringUtils.hasText(resultTransformer)){
builder.addConstructorArgReference(resultTransformer);
}
}
}

View File

@@ -36,6 +36,7 @@
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="result-transformer" type="xsd:string" use="optional" />
</xsd:complexType>
</xsd:element>
@@ -69,6 +70,7 @@
use="optional" />
<xsd:attribute name="result-factory" type="xsd:string"
use="optional" />
<xsd:attribute name="result-transformer" type="xsd:string" use="optional" />
</xsd:complexType>
</xsd:element>

View File

@@ -22,11 +22,10 @@ import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import org.springframework.integration.message.MessagingException;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.springframework.integration.message.MessagingException;
/**
* {@link SourceFactory} implementation which supports creation of a
* {@link DOMSource} from a {@link Document} or {@link String} payload.
@@ -38,7 +37,6 @@ public class DomSourceFactory implements SourceFactory {
private final DocumentBuilderFactory docBuilderFactory;
public DomSourceFactory() {
this.docBuilderFactory = DocumentBuilderFactory.newInstance();
}
@@ -49,14 +47,19 @@ public class DomSourceFactory implements SourceFactory {
public Source createSource(Object payload) {
if (Document.class.isAssignableFrom(payload.getClass())) {
return createDomSourceForDocument((Document) payload);
Source source = null;
if (payload instanceof Document) {
source = createDomSourceForDocument((Document) payload);
}
else if (payload instanceof String) {
return createDomSourceForString((String) payload);
source = createDomSourceForString((String) payload);
}
if(source == null){
throw new MessagingException("Failed to create Source for payload type ["
+ payload.getClass().getName() + "]");
}
return source;
}
protected DOMSource createDomSourceForDocument(Document document) {
@@ -66,11 +69,11 @@ public class DomSourceFactory implements SourceFactory {
protected DOMSource createDomSourceForString(String s) {
try {
Document doc = docBuilderFactory.newDocumentBuilder().parse(new InputSource(new StringReader(s)));
Document doc = docBuilderFactory.newDocumentBuilder().parse(
new InputSource(new StringReader(s)));
DOMSource source = new DOMSource(doc.getDocumentElement());
return source;
}
catch (Exception e) {
} catch (Exception e) {
throw new MessagingException("Exception creating DOMSource", e);
}
}

View File

@@ -26,6 +26,11 @@ import javax.xml.transform.Source;
*/
public interface SourceFactory {
/**
* Create appropriate {@link Source} instance for payload
* @param payload
* @return
*/
Source createSource(Object payload);
}

View File

@@ -26,9 +26,11 @@ import org.springframework.xml.transform.StringSource;
import org.w3c.dom.Document;
/**
* {@link SourceFactory} implementation which supports creation of a
* {@link StringSource} from either a {@link Document} or {@link String} payload
*
* @author Jonas Partner
*
*
*/
public class StringSourceFactory implements SourceFactory {
@@ -43,14 +45,20 @@ public class StringSourceFactory implements SourceFactory {
}
public Source createSource(Object payload) {
if (Document.class.isAssignableFrom(payload.getClass())) {
return createStringSourceForDocument((Document) payload);
Source source = null;
if (payload instanceof Document) {
source = createStringSourceForDocument((Document) payload);
} else if (payload instanceof String) {
return new StringSource((String) payload);
source = new StringSource((String) payload);
}
throw new MessagingException(
"Failed to create Source for payload type ["
+ payload.getClass().getName() + "]");
if (source == null) {
throw new MessagingException(
"Failed to create Source for payload type ["
+ payload.getClass().getName() + "]");
}
return source;
}
protected StringSource createStringSourceForDocument(Document doc) {

View File

@@ -35,19 +35,27 @@ import org.springframework.util.Assert;
* @author Mark Fisher
* @author Jonas Partner
*/
public class XmlPayloadMarshallingTransformer implements PayloadTransformer<Object, Object> {
public class XmlPayloadMarshallingTransformer implements
PayloadTransformer<Object, Object> {
private final Marshaller marshaller;
private ResultFactory resultFactory = new DomResultFactory();
private volatile ResultFactory resultFactory;
private final ResultTransformer resultTransformer;
public XmlPayloadMarshallingTransformer(Marshaller marshaller) throws ParserConfigurationException {
public XmlPayloadMarshallingTransformer(Marshaller marshaller,
ResultTransformer resultTransformer) throws ParserConfigurationException {
Assert.notNull(marshaller, "a marshaller is required");
this.marshaller = marshaller;
this.resultTransformer = resultTransformer;
resultFactory = new DomResultFactory();
}
public XmlPayloadMarshallingTransformer(Marshaller marshaller)
throws ParserConfigurationException {
this(marshaller, null);
}
public void setResultFactory(ResultFactory resultFactory) {
Assert.notNull(resultFactory, "ResultFactory must not be null");
@@ -58,18 +66,22 @@ public class XmlPayloadMarshallingTransformer implements PayloadTransformer<Obje
Object transformedPayload = null;
Result result = this.resultFactory.createResult(payload);
if (result == null) {
throw new MessagingException("Unable to marshal payload, ResultFactory returned null.");
throw new MessagingException(
"Unable to marshal payload, ResultFactory returned null.");
}
try {
this.marshaller.marshal(payload, result);
transformedPayload = result;
}
catch (IOException e) {
} catch (IOException e) {
throw new MessagingException("Failed to marshal payload", e);
}
if (transformedPayload == null) {
throw new MessagingException("Failed to transform payload");
}
if(resultTransformer != null){
transformedPayload = resultTransformer.transformResult(result);
}
return transformedPayload;
}

View File

@@ -19,43 +19,52 @@ package org.springframework.integration.xml.transformer;
import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import org.springframework.integration.message.MessagingException;
import org.springframework.integration.transformer.PayloadTransformer;
import org.springframework.integration.xml.source.DomSourceFactory;
import org.springframework.integration.xml.source.SourceFactory;
import org.springframework.oxm.Unmarshaller;
import org.springframework.util.Assert;
import org.springframework.xml.transform.StringSource;
import org.w3c.dom.Document;
/**
* An implementation of {@link PayloadTransformer} that delegates to an OXM
* {@link Unmarshaller}. Expects the payload to be of type {@link Source} or to
* have an instance of {@link SourceFactory} that can convert to a
* {@link Source}.
* {@link Unmarshaller}. Expects the payload to be of type {@link Document},
* {@link String}, {@link Source} or to have an instance of
* {@link SourceFactory} that can convert to a {@link Source}. If
* alwaysUseSourceFactory is set to true then the {@link SourceFactory} will
* be used to create the {@link Source} regardless of payload type
*
*
* @author Jonas Partner
*/
public class XmlPayloadUnmarshallingTransformer implements PayloadTransformer<Object, Object> {
public class XmlPayloadUnmarshallingTransformer implements
PayloadTransformer<Object, Object> {
private volatile boolean alwaysUseSourceFactory = false;
private final Unmarshaller unmarshaller;
private SourceFactory sourceFactory = new DomSourceFactory();
private volatile SourceFactory sourceFactory = new DomSourceFactory();
public XmlPayloadUnmarshallingTransformer(Unmarshaller unmarshaller) {
this.unmarshaller = unmarshaller;
}
public void setSourceFactory(SourceFactory sourceFactory) {
this.sourceFactory = sourceFactory;
}
public Object transform(Object payload) {
Source source = null;
if (Source.class.isAssignableFrom(payload.getClass())) {
if (alwaysUseSourceFactory) {
source = sourceFactory.createSource(payload);
} else if (payload instanceof String) {
source = new StringSource((String) payload);
} else if (payload instanceof Document) {
source = new DOMSource((Document) payload);
} else if (payload instanceof Source) {
source = (Source) payload;
}
else if (this.sourceFactory != null) {
} else {
source = this.sourceFactory.createSource(payload);
}
@@ -66,10 +75,26 @@ public class XmlPayloadUnmarshallingTransformer implements PayloadTransformer<Ob
try {
return this.unmarshaller.unmarshal(source);
}
catch (IOException e) {
} catch (IOException e) {
throw new MessagingException("Failed to unamrshal payload", e);
}
}
/**
* If true always delegate to the {@link SourceFactory}
* @param alwaysUseSourceFactory
*/
public void setAlwaysUseSourceFactory(boolean alwaysUseSourceFactory) {
this.alwaysUseSourceFactory = alwaysUseSourceFactory;
}
/**
*
* @param sourceFactory
*/
public void setSourceFactory(SourceFactory sourceFactory) {
Assert.notNull(sourceFactory, "SourceFactory can not be null");
this.sourceFactory = sourceFactory;
}
}

View File

@@ -33,6 +33,7 @@ import org.springframework.integration.xml.result.DomResultFactory;
import org.springframework.integration.xml.result.ResultFactory;
import org.springframework.integration.xml.source.DomSourceFactory;
import org.springframework.integration.xml.source.SourceFactory;
import org.springframework.util.Assert;
import org.springframework.xml.transform.StringResult;
import org.springframework.xml.transform.StringSource;
import org.w3c.dom.Document;
@@ -66,37 +67,37 @@ public class XsltPayloadTransformer implements
private final Templates templates;
private SourceFactory sourceFactory = new DomSourceFactory();
private final ResultTransformer resultTransformer;
private ResultFactory resultFactory = new DomResultFactory();
private volatile SourceFactory sourceFactory = new DomSourceFactory();
private boolean alwaysUseSourceResultFactories = false;
private volatile ResultFactory resultFactory = new DomResultFactory();
private ResultTransformer resultTransformer;
private volatile boolean alwaysUseSourceResultFactories = false;
public XsltPayloadTransformer(Templates templates)
throws ParserConfigurationException {
this(templates, null);
}
public XsltPayloadTransformer(Templates templates,
ResultTransformer resultTransformer)
throws ParserConfigurationException {
this.templates = templates;
resultFactory = new DomResultFactory();
this.resultTransformer = resultTransformer;
}
public XsltPayloadTransformer(Resource xslResource) throws Exception {
this(TransformerFactory.newInstance().newTemplates(
new StreamSource(xslResource.getInputStream())));
new StreamSource(xslResource.getInputStream())),null);
}
public void setSourceFactory(SourceFactory sourceFactory) {
this.sourceFactory = sourceFactory;
}
public void setResultFactory(ResultFactory resultFactory) {
this.resultFactory = resultFactory;
}
public void setAlwaysUseSourceResultFactories(
boolean alwaysUserSourceResultFactories) {
this.alwaysUseSourceResultFactories = alwaysUserSourceResultFactories;
public XsltPayloadTransformer(Resource xslResource, ResultTransformer resultTransformer) throws Exception {
this(TransformerFactory.newInstance().newTemplates(
new StreamSource(xslResource.getInputStream())),resultTransformer);
}
public Object transform(Object payload) throws TransformerException {
Object transformedPayload;
@@ -104,9 +105,9 @@ public class XsltPayloadTransformer implements
transformedPayload = transformUsingFactories(payload);
} else if (payload instanceof String) {
transformedPayload = transformString((String) payload);
} else if (Document.class.isAssignableFrom(payload.getClass())) {
} else if (payload instanceof Document) {
transformedPayload = transformDocument((Document) payload);
} else if (Source.class.isAssignableFrom(payload.getClass())) {
} else if (payload instanceof Source) {
transformedPayload = transformSource((Source) payload, payload);
} else {
// fall back to trying factories
@@ -116,6 +117,35 @@ public class XsltPayloadTransformer implements
}
/**
*
* @param sourceFactory
*/
public void setSourceFactory(SourceFactory sourceFactory) {
Assert.notNull(sourceFactory, "SourceFactory can not be null");
this.sourceFactory = sourceFactory;
}
/**
*
* @param resultFactory
*/
public void setResultFactory(ResultFactory resultFactory) {
Assert.notNull(sourceFactory, "ResultFactory can not be null");
this.resultFactory = resultFactory;
}
/**
* Forces use of {@link ResultFactory} and {@link SourceFactory} even for
* directly supported payloads such as {@link String} and {@link Document}
*
* @param alwaysUserSourceResultFactories
*/
public void setAlwaysUseSourceResultFactories(
boolean alwaysUserSourceResultFactories) {
this.alwaysUseSourceResultFactories = alwaysUserSourceResultFactories;
}
protected Object transformUsingFactories(Object payload)
throws TransformerException {
Source source = sourceFactory.createSource(payload);
@@ -126,11 +156,12 @@ public class XsltPayloadTransformer implements
throws TransformerException {
Result result = resultFactory.createResult(payload);
this.templates.newTransformer().transform(source, result);
if (resultTransformer != null) {
return resultTransformer.transformResult(result);
} else {
return result;
}
return result;
}
protected String transformString(String stringPayload)
@@ -154,8 +185,4 @@ public class XsltPayloadTransformer implements
return (Document) domResult.getNode();
}
public void setResultTransformer(ResultTransformer resultTransformer) {
this.resultTransformer = resultTransformer;
}
}