Skip to content

Commit 59c69ed

Browse files
committed
Allow XML components injection
**Cherry-pick to 5.0.x & 4.3.x** * Polishing after rebase * Copyright to 2019 * Rebase and update according upstream deps
1 parent 0d13128 commit 59c69ed

17 files changed

+345
-174
lines changed

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ subprojects { subproject ->
139139
springSecurityVersion = '5.1.2.RELEASE'
140140
springRetryVersion = '1.2.2.RELEASE'
141141
springVersion = project.hasProperty('springVersion') ? project.springVersion : '5.1.4.RELEASE'
142-
springWsVersion = '3.0.4.RELEASE'
142+
springWsVersion = '3.0.5.RELEASE'
143143
tomcatVersion = "9.0.12"
144144
xstreamVersion = '1.4.11.1'
145145
}

spring-integration-xml/src/main/java/org/springframework/integration/xml/DefaultXmlPayloadConverter.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,6 +33,8 @@
3333
import org.xml.sax.InputSource;
3434

3535
import org.springframework.messaging.MessagingException;
36+
import org.springframework.util.Assert;
37+
import org.springframework.xml.DocumentBuilderFactoryUtils;
3638

3739
/**
3840
* Default implementation of {@link XmlPayloadConverter}. Supports
@@ -48,11 +50,12 @@ public class DefaultXmlPayloadConverter implements XmlPayloadConverter {
4850

4951

5052
public DefaultXmlPayloadConverter() {
51-
this.documentBuilderFactory = DocumentBuilderFactory.newInstance();
53+
this(DocumentBuilderFactoryUtils.newInstance());
5254
this.documentBuilderFactory.setNamespaceAware(true);
5355
}
5456

5557
public DefaultXmlPayloadConverter(DocumentBuilderFactory documentBuilderFactory) {
58+
Assert.notNull(documentBuilderFactory, "'documentBuilderFactory' must not be null.");
5659
this.documentBuilderFactory = documentBuilderFactory;
5760
}
5861

@@ -115,7 +118,7 @@ protected Document nodeToDocument(Node node) {
115118

116119
@Override
117120
public Node convertToNode(Object object) {
118-
Node node = null;
121+
Node node;
119122
if (object instanceof Node) {
120123
node = (Node) object;
121124
}
@@ -130,7 +133,6 @@ else if (object instanceof DOMSource) {
130133

131134
@Override
132135
public Source convertToSource(Object object) {
133-
Source source = null;
134136
if (object instanceof Source) {
135137
return (Source) object;
136138
}

spring-integration-xml/src/main/java/org/springframework/integration/xml/config/XPathHeaderEnricherParser.java

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@
3434
*
3535
* @author Mark Fisher
3636
* @author Artem Bilan
37+
*
3738
* @since 2.0
3839
*/
3940
public class XPathHeaderEnricherParser extends AbstractTransformerParser {
@@ -45,15 +46,16 @@ protected final String getTransformerClassName() {
4546

4647
@Override
4748
protected void parseTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
48-
ManagedMap<String, Object> headers = new ManagedMap<String, Object>();
49-
this.processHeaders(element, headers, parserContext);
49+
ManagedMap<String, Object> headers = new ManagedMap<>();
50+
processHeaders(element, headers, parserContext);
5051
builder.addConstructorArgValue(headers);
5152
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "default-overwrite");
5253
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "should-skip-nulls");
5354
}
5455

5556
protected void processHeaders(Element element, ManagedMap<String, Object> headers, ParserContext parserContext) {
5657
Object source = parserContext.extractSource(element);
58+
String converter = element.getAttribute("converter");
5759
NodeList childNodes = element.getChildNodes();
5860
for (int i = 0; i < childNodes.getLength(); i++) {
5961
Node node = childNodes.item(i);
@@ -62,21 +64,26 @@ protected void processHeaders(Element element, ManagedMap<String, Object> header
6264
String elementName = node.getLocalName();
6365
if ("header".equals(elementName)) {
6466
BeanDefinitionBuilder builder =
65-
BeanDefinitionBuilder.genericBeanDefinition(XPathExpressionEvaluatingHeaderValueMessageProcessor.class);
67+
BeanDefinitionBuilder.genericBeanDefinition(
68+
XPathExpressionEvaluatingHeaderValueMessageProcessor.class);
6669
String expressionString = headerElement.getAttribute("xpath-expression");
6770
String expressionRef = headerElement.getAttribute("xpath-expression-ref");
6871
boolean isExpressionString = StringUtils.hasText(expressionString);
6972
boolean isExpressionRef = StringUtils.hasText(expressionRef);
70-
if (!(isExpressionString ^ isExpressionRef)) {
73+
if (isExpressionString == isExpressionRef) {
7174
parserContext.getReaderContext().error(
72-
"Exactly one of the 'xpath-expression' or 'xpath-expression-ref' attributes is required.", source);
75+
"Exactly one of the 'xpath-expression' " +
76+
"or 'xpath-expression-ref' attributes is required.", source);
7377
}
7478
if (isExpressionString) {
7579
builder.addConstructorArgValue(expressionString);
7680
}
7781
else {
7882
builder.addConstructorArgReference(expressionRef);
7983
}
84+
if (StringUtils.hasText(converter)) {
85+
builder.addConstructorArgReference(converter);
86+
}
8087
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, headerElement, "evaluation-type");
8188
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, headerElement, "overwrite");
8289
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, headerElement, "header-type");

spring-integration-xml/src/main/java/org/springframework/integration/xml/result/DomResultFactory.java

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2010 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,23 +23,26 @@
2323
import javax.xml.transform.dom.DOMResult;
2424

2525
import org.springframework.messaging.MessagingException;
26+
import org.springframework.util.Assert;
27+
import org.springframework.xml.DocumentBuilderFactoryUtils;
2628

2729
/**
2830
* @author Jonas Partner
31+
* @author Artem Bilan
2932
*/
3033
public class DomResultFactory implements ResultFactory {
3134

3235
private final DocumentBuilderFactory documentBuilderFactory;
3336

3437

35-
public DomResultFactory(DocumentBuilderFactory documentBuilderFactory) {
36-
this.documentBuilderFactory = documentBuilderFactory;
38+
public DomResultFactory() {
39+
this(DocumentBuilderFactoryUtils.newInstance());
40+
this.documentBuilderFactory.setNamespaceAware(true);
3741
}
3842

39-
public DomResultFactory() {
40-
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
41-
factory.setNamespaceAware(true);
42-
this.documentBuilderFactory = factory;
43+
public DomResultFactory(DocumentBuilderFactory documentBuilderFactory) {
44+
Assert.notNull(documentBuilderFactory, "'documentBuilderFactory' must not be null.");
45+
this.documentBuilderFactory = documentBuilderFactory;
4346
}
4447

4548

spring-integration-xml/src/main/java/org/springframework/integration/xml/selector/XmlValidatingMessageSelector.java

+26-24
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
* @author Oleg Zhurakousky
4242
* @author Gary Russell
4343
* @author Liujiong
44+
* @author Artem Bilan
45+
*
4446
* @since 2.0
4547
*/
4648
public class XmlValidatingMessageSelector implements MessageSelector {
@@ -63,44 +65,42 @@ public String getUrl() {
6365

6466
}
6567

66-
private final Log logger = LogFactory.getLog(this.getClass());
68+
private final Log logger = LogFactory.getLog(getClass());
6769

6870
private final XmlValidator xmlValidator;
6971

70-
private volatile boolean throwExceptionOnRejection;
72+
private boolean throwExceptionOnRejection;
7173

72-
private volatile XmlPayloadConverter converter = new DefaultXmlPayloadConverter();
73-
74-
75-
public XmlValidatingMessageSelector(XmlValidator xmlValidator) {
76-
Assert.notNull(xmlValidator, "XmlValidator must not be null");
77-
this.xmlValidator = xmlValidator;
78-
}
74+
private XmlPayloadConverter converter = new DefaultXmlPayloadConverter();
7975

8076

8177
/**
8278
* Creates a selector with a default {@link XmlValidator}. The validator will be initialized with
8379
* the provided 'schema' location {@link Resource} and 'schemaType'. The valid options for schema
8480
* type are {@link XmlValidatorFactory#SCHEMA_W3C_XML} or {@link XmlValidatorFactory#SCHEMA_RELAX_NG}.
8581
* If no 'schemaType' is provided it will default to {@link XmlValidatorFactory#SCHEMA_W3C_XML};
86-
*
8782
* @param schema The schema.
88-
* @param schemaTypeArg The schema type.
89-
*
83+
* @param schemaType The schema type.
9084
* @throws IOException if the XmlValidatorFactory fails to create a validator
9185
*/
92-
public XmlValidatingMessageSelector(Resource schema, SchemaType schemaTypeArg) throws IOException {
93-
SchemaType schemaType = schemaTypeArg;
94-
Assert.notNull(schema, "You must provide XML schema location to perform validation");
95-
if (schemaType == null) {
96-
schemaType = SchemaType.XML_SCHEMA;
97-
}
98-
this.xmlValidator = XmlValidatorFactory.createValidator(schema, schemaType.getUrl());
86+
public XmlValidatingMessageSelector(Resource schema, SchemaType schemaType) throws IOException {
87+
this(XmlValidatorFactory.createValidator(schema,
88+
schemaType == null
89+
? SchemaType.XML_SCHEMA.getUrl()
90+
: schemaType.getUrl()));
91+
}
92+
93+
public XmlValidatingMessageSelector(XmlValidator xmlValidator) {
94+
Assert.notNull(xmlValidator, "XmlValidator must not be null");
95+
this.xmlValidator = xmlValidator;
9996
}
10097

98+
10199
public XmlValidatingMessageSelector(Resource schema, String schemaType) throws IOException {
102-
this(schema, StringUtils.isEmpty(schemaType) ? null :
103-
SchemaType.valueOf(schemaType.toUpperCase().replaceFirst("-", "_")));
100+
this(schema,
101+
StringUtils.isEmpty(schemaType)
102+
? null
103+
: SchemaType.valueOf(schemaType.toUpperCase().replaceFirst("-", "_")));
104104
}
105105

106106

@@ -131,10 +131,12 @@ public boolean accept(Message<?> message) {
131131
if (!validationSuccess) {
132132
if (this.throwExceptionOnRejection) {
133133
throw new MessageRejectedException(message, "Message was rejected due to XML Validation errors",
134-
new AggregatedXmlMessageValidationException(
135-
Arrays.<Throwable>asList(validationExceptions)));
134+
new AggregatedXmlMessageValidationException(Arrays.asList(validationExceptions)));
135+
}
136+
else if (this.logger.isInfoEnabled()) {
137+
this.logger.info("Message was rejected due to XML Validation errors",
138+
new AggregatedXmlMessageValidationException(Arrays.asList(validationExceptions)));
136139
}
137-
this.logger.debug("Message was rejected due to XML Validation errors");
138140
}
139141
return validationSuccess;
140142
}

spring-integration-xml/src/main/java/org/springframework/integration/xml/source/DomSourceFactory.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,26 +29,29 @@
2929
import org.xml.sax.InputSource;
3030

3131
import org.springframework.messaging.MessagingException;
32+
import org.springframework.util.Assert;
33+
import org.springframework.xml.DocumentBuilderFactoryUtils;
3234

3335
/**
3436
* {@link SourceFactory} implementation which supports creation of a {@link DOMSource}
3537
* from a {@link Document}, {@link File} or {@link String} payload.
3638
*
3739
* @author Jonas Partner
3840
* @author Mark Fisher
41+
* @author Artem Bilan
3942
*/
4043
public class DomSourceFactory implements SourceFactory {
4144

4245
private final DocumentBuilderFactory documentBuilderFactory;
4346

4447

4548
public DomSourceFactory() {
46-
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
47-
factory.setNamespaceAware(true);
48-
this.documentBuilderFactory = factory;
49+
this(DocumentBuilderFactoryUtils.newInstance());
50+
this.documentBuilderFactory.setNamespaceAware(true);
4951
}
5052

5153
public DomSourceFactory(DocumentBuilderFactory documentBuilderFactory) {
54+
Assert.notNull(documentBuilderFactory, "'documentBuilderFactory' must not be null.");
5255
this.documentBuilderFactory = documentBuilderFactory;
5356
}
5457

@@ -87,7 +90,7 @@ private DOMSource createDomSourceForString(String s) {
8790

8891
private DOMSource createDomSourceForFile(File file) {
8992
try {
90-
Document document = this.getNewDocumentBuilder().parse(file);
93+
Document document = getNewDocumentBuilder().parse(file);
9194
return new DOMSource(document.getDocumentElement());
9295
}
9396
catch (Exception e) {

spring-integration-xml/src/main/java/org/springframework/integration/xml/source/StringSourceFactory.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,27 +27,31 @@
2727
import org.w3c.dom.Document;
2828

2929
import org.springframework.messaging.MessagingException;
30+
import org.springframework.util.Assert;
3031
import org.springframework.util.FileCopyUtils;
3132
import org.springframework.xml.transform.StringResult;
3233
import org.springframework.xml.transform.StringSource;
34+
import org.springframework.xml.transform.TransformerFactoryUtils;
3335

3436
/**
3537
* {@link SourceFactory} implementation which supports creation of a {@link StringSource}
3638
* from a {@link Document}, {@link File} or {@link String} payload
3739
*
3840
* @author Jonas Partner
3941
* @author Mark Fisher
42+
* @author Artem Bilan
4043
*/
4144
public class StringSourceFactory implements SourceFactory {
4245

4346
private final TransformerFactory transformerFactory;
4447

4548

4649
public StringSourceFactory() {
47-
this(TransformerFactory.newInstance());
50+
this(TransformerFactoryUtils.newInstance());
4851
}
4952

5053
public StringSourceFactory(TransformerFactory transformerFactory) {
54+
Assert.notNull(transformerFactory, "'transformerFactory' must not be null.");
5155
this.transformerFactory = transformerFactory;
5256
}
5357

0 commit comments

Comments
 (0)