Skip to content

Commit ba2744a

Browse files
committed
SWS-242 - Allow for custom ErrorHandler in PayloadValidatingInterceptor
1 parent 04aab9f commit ba2744a

File tree

9 files changed

+161
-38
lines changed

9 files changed

+161
-38
lines changed

core/src/main/java/org/springframework/ws/server/endpoint/interceptor/AbstractValidatingInterceptor.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2011 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.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,6 +31,7 @@
3131
import org.springframework.ws.soap.SoapFault;
3232
import org.springframework.ws.soap.SoapMessage;
3333
import org.springframework.xml.transform.TransformerObjectSupport;
34+
import org.springframework.xml.validation.ValidationErrorHandler;
3435
import org.springframework.xml.validation.XmlValidator;
3536
import org.springframework.xml.validation.XmlValidatorFactory;
3637
import org.springframework.xml.xsd.XsdSchema;
@@ -65,6 +66,8 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
6566

6667
private XmlValidator validator;
6768

69+
private ValidationErrorHandler errorHandler;
70+
6871
public String getSchemaLanguage() {
6972
return schemaLanguage;
7073
}
@@ -131,6 +134,15 @@ public void setXsdSchemaCollection(XsdSchemaCollection schemaCollection) throws
131134
this.validator = schemaCollection.createValidator();
132135
}
133136

137+
/**
138+
* Sets the error handler to use for validation. If not set, a default error handler will be used.
139+
*
140+
* @param errorHandler the error handler.
141+
*/
142+
public void setErrorHandler(ValidationErrorHandler errorHandler) {
143+
this.errorHandler = errorHandler;
144+
}
145+
134146
/** Indicates whether the request should be validated against the schema. Default is <code>true</code>. */
135147
public void setValidateRequest(boolean validateRequest) {
136148
this.validateRequest = validateRequest;
@@ -171,7 +183,7 @@ public boolean handleRequest(MessageContext messageContext, Object endpoint)
171183
if (validateRequest) {
172184
Source requestSource = getValidationRequestSource(messageContext.getRequest());
173185
if (requestSource != null) {
174-
SAXParseException[] errors = validator.validate(requestSource);
186+
SAXParseException[] errors = validator.validate(requestSource, errorHandler);
175187
if (!ObjectUtils.isEmpty(errors)) {
176188
return handleRequestValidationErrors(messageContext, errors);
177189
}
@@ -213,7 +225,7 @@ public boolean handleResponse(MessageContext messageContext, Object endpoint) th
213225
if (validateResponse) {
214226
Source responseSource = getValidationResponseSource(messageContext.getResponse());
215227
if (responseSource != null) {
216-
SAXParseException[] errors = validator.validate(responseSource);
228+
SAXParseException[] errors = validator.validate(responseSource, errorHandler);
217229
if (!ObjectUtils.isEmpty(errors)) {
218230
return handleResponseValidationErrors(messageContext, errors);
219231
}
@@ -227,11 +239,11 @@ else if (logger.isDebugEnabled()) {
227239

228240
/**
229241
* Template method that is called when the response message contains validation errors. Default implementation logs
230-
* all errors, and returns <code>false</code>, i.e. do not cot continue to process the respone interceptor chain.
242+
* all errors, and returns <code>false</code>, i.e. do not cot continue to process the response interceptor chain.
231243
*
232244
* @param messageContext the message context
233245
* @param errors the validation errors
234-
* @return <code>true</code> to continue the reponse interceptor chain, <code>false</code> (the default) otherwise
246+
* @return <code>true</code> to continue the response interceptor chain, <code>false</code> (the default) otherwise
235247
*/
236248
protected boolean handleResponseValidationErrors(MessageContext messageContext, SAXParseException[] errors) {
237249
for (SAXParseException error : errors) {

core/src/test/java/org/springframework/ws/soap/server/endpoint/interceptor/PayloadValidatingInterceptorTest.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2011 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.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -44,11 +44,13 @@
4444
import org.springframework.ws.soap.soap12.Soap12Fault;
4545
import org.springframework.ws.transport.MockTransportInputStream;
4646
import org.springframework.ws.transport.TransportInputStream;
47+
import org.springframework.xml.validation.ValidationErrorHandler;
4748
import org.springframework.xml.xsd.SimpleXsdSchema;
4849

4950
import org.junit.Assert;
5051
import org.junit.Before;
5152
import org.junit.Test;
53+
import org.xml.sax.SAXException;
5254
import org.xml.sax.SAXParseException;
5355
import org.xml.sax.helpers.LocatorImpl;
5456

@@ -95,7 +97,7 @@ public void setUp() throws Exception {
9597

9698
@Test
9799
public void testHandleInvalidRequestSoap11() throws Exception {
98-
SoapMessage invalidMessage = (SoapMessage) soap11Factory.createWebServiceMessage();
100+
SoapMessage invalidMessage = soap11Factory.createWebServiceMessage();
99101
InputStream inputStream = getClass().getResourceAsStream(INVALID_MESSAGE);
100102
transformer.transform(new StreamSource(inputStream), invalidMessage.getPayloadResult());
101103
context = new DefaultMessageContext(invalidMessage, soap11Factory);
@@ -115,7 +117,7 @@ public void testHandleInvalidRequestSoap11() throws Exception {
115117

116118
@Test
117119
public void testHandleInvalidRequestSoap12() throws Exception {
118-
SoapMessage invalidMessage = (SoapMessage) soap12Factory.createWebServiceMessage();
120+
SoapMessage invalidMessage = soap12Factory.createWebServiceMessage();
119121
InputStream inputStream = getClass().getResourceAsStream(INVALID_MESSAGE);
120122
transformer.transform(new StreamSource(inputStream), invalidMessage.getPayloadResult());
121123
context = new DefaultMessageContext(invalidMessage, soap12Factory);
@@ -365,4 +367,31 @@ public void testMultipleNamespacesAxiom() throws Exception {
365367

366368
}
367369

370+
@Test
371+
public void customErrorHandler() throws Exception {
372+
ValidationErrorHandler errorHandler = new ValidationErrorHandler() {
373+
public SAXParseException[] getErrors() {
374+
return new SAXParseException[0];
375+
}
376+
377+
public void warning(SAXParseException exception) throws SAXException {
378+
}
379+
380+
public void error(SAXParseException exception) throws SAXException {
381+
}
382+
383+
public void fatalError(SAXParseException exception) throws SAXException {
384+
}
385+
};
386+
interceptor.setErrorHandler(errorHandler);
387+
SoapMessage invalidMessage = soap11Factory.createWebServiceMessage();
388+
InputStream inputStream = getClass().getResourceAsStream(INVALID_MESSAGE);
389+
transformer.transform(new StreamSource(inputStream), invalidMessage.getPayloadResult());
390+
context = new DefaultMessageContext(invalidMessage, soap11Factory);
391+
392+
boolean result = interceptor.handleRequest(context, null);
393+
Assert.assertTrue("Invalid response from interceptor", result);
394+
Assert.assertFalse("Context has response", context.hasResponse());
395+
}
396+
368397
}

xml/src/main/java/org/springframework/xml/validation/Jaxp10ValidatorFactory.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2011 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.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -46,7 +46,9 @@
4646
*
4747
* @author Arjen Poutsma
4848
* @since 1.0.0
49+
* @deprecated in favor of {@link Jaxp13ValidatorFactory}
4950
*/
51+
@Deprecated
5052
abstract class Jaxp10ValidatorFactory {
5153

5254
private static final String SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
@@ -80,9 +82,14 @@ private Jaxp10Validator(InputSource[] schemaInputSources, String schemaLanguage)
8082
parserFactory.setValidating(true);
8183
}
8284

85+
public SAXParseException[] validate(Source source, ValidationErrorHandler errorHandler)
86+
throws IOException {
87+
return validate(source);
88+
}
89+
8390
public SAXParseException[] validate(Source source) throws IOException {
8491
SAXParser parser = createSAXParser();
85-
ValidationErrorHandler errorHandler = new ValidationErrorHandler();
92+
DefaultValidationErrorHandler errorHandler = new DefaultValidationErrorHandler();
8693
try {
8794
if (source instanceof SAXSource) {
8895
validateSAXSource((SAXSource) source, parser, errorHandler);
@@ -104,7 +111,7 @@ else if (source instanceof DOMSource) {
104111
}
105112
}
106113

107-
private void validateDOMSource(DOMSource domSource, SAXParser parser, ValidationErrorHandler errorHandler)
114+
private void validateDOMSource(DOMSource domSource, SAXParser parser, DefaultValidationErrorHandler errorHandler)
108115
throws IOException, SAXException {
109116
try {
110117
// Sadly, JAXP 1.0 DOM doesn't implement DOM level 3, so we cannot use Document.normalizeDocument()
@@ -123,7 +130,7 @@ private void validateDOMSource(DOMSource domSource, SAXParser parser, Validation
123130

124131
private void validateStreamSource(StreamSource streamSource,
125132
SAXParser parser,
126-
ValidationErrorHandler errorHandler) throws SAXException, IOException {
133+
DefaultValidationErrorHandler errorHandler) throws SAXException, IOException {
127134
if (streamSource.getInputStream() != null) {
128135
parser.parse(streamSource.getInputStream(), errorHandler);
129136
}
@@ -135,7 +142,7 @@ else if (streamSource.getReader() != null) {
135142
}
136143
}
137144

138-
private void validateSAXSource(SAXSource source, SAXParser parser, ValidationErrorHandler errorHandler)
145+
private void validateSAXSource(SAXSource source, SAXParser parser, DefaultValidationErrorHandler errorHandler)
139146
throws SAXException, IOException {
140147
parser.parse(source.getInputSource(), errorHandler);
141148
}
@@ -157,7 +164,7 @@ private SAXParser createSAXParser() {
157164
}
158165

159166
/** <code>DefaultHandler</code> extension that stores errors and fatal errors in a list. */
160-
private static class ValidationErrorHandler extends DefaultHandler {
167+
private static class DefaultValidationErrorHandler extends DefaultHandler {
161168

162169
private List<SAXParseException> errors = new ArrayList<SAXParseException>();
163170

xml/src/main/java/org/springframework/xml/validation/Jaxp13ValidatorFactory.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2011 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.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -21,10 +21,10 @@
2121
import java.util.List;
2222
import javax.xml.transform.Source;
2323
import javax.xml.validation.Schema;
24+
import javax.xml.validation.Validator;
2425

2526
import org.springframework.core.io.Resource;
2627

27-
import org.xml.sax.ErrorHandler;
2828
import org.xml.sax.SAXException;
2929
import org.xml.sax.SAXParseException;
3030

@@ -55,8 +55,14 @@ public Jaxp13Validator(Schema schema) {
5555
}
5656

5757
public SAXParseException[] validate(Source source) throws IOException {
58-
javax.xml.validation.Validator validator = schema.newValidator();
59-
ValidationErrorHandler errorHandler = new ValidationErrorHandler();
58+
return validate(source, null);
59+
}
60+
61+
public SAXParseException[] validate(Source source, ValidationErrorHandler errorHandler) throws IOException {
62+
if (errorHandler == null) {
63+
errorHandler = new DefaultValidationErrorHandler();
64+
}
65+
Validator validator = schema.newValidator();
6066
validator.setErrorHandler(errorHandler);
6167
try {
6268
validator.validate(source);
@@ -69,11 +75,11 @@ public SAXParseException[] validate(Source source) throws IOException {
6975
}
7076

7177
/** <code>ErrorHandler</code> implementation that stores errors and fatal errors in a list. */
72-
private static class ValidationErrorHandler implements ErrorHandler {
78+
private static class DefaultValidationErrorHandler implements ValidationErrorHandler {
7379

7480
private List<SAXParseException> errors = new ArrayList<SAXParseException>();
7581

76-
private SAXParseException[] getErrors() {
82+
public SAXParseException[] getErrors() {
7783
return errors.toArray(new SAXParseException[errors.size()]);
7884
}
7985

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2005-2011 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.xml.validation;
18+
19+
import org.xml.sax.ErrorHandler;
20+
import org.xml.sax.SAXParseException;
21+
22+
/**
23+
* Subinterface of {@link ErrorHandler} that allows the registered errors to be retrieved.
24+
* @author Arjen Poutsma
25+
* @since 2.0.1
26+
*/
27+
public interface ValidationErrorHandler extends ErrorHandler {
28+
29+
/**
30+
* Returns the errors collected by this error handler.
31+
* @return the errors
32+
*/
33+
SAXParseException[] getErrors();
34+
}

xml/src/main/java/org/springframework/xml/validation/XmlValidator.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2006 the original author or authors.
2+
* Copyright 2005-2011 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.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,7 +27,7 @@
2727
* Instances of this class are designed to be thread safe.
2828
*
2929
* @author Arjen Poutsma
30-
* @see XmlValidatorFactory#createValidator(org.springframework.core.io.Resource,String)
30+
* @see XmlValidatorFactory#createValidator(org.springframework.core.io.Resource, String)
3131
* @since 1.0.0
3232
*/
3333
public interface XmlValidator {
@@ -43,4 +43,16 @@ public interface XmlValidator {
4343
*/
4444
SAXParseException[] validate(Source source) throws IOException;
4545

46+
/**
47+
* Validates the given {@link Source} and {@link ValidationErrorHandler}, and returns an array of {@link
48+
* SAXParseException}s as result. The array will be empty if no validation errors are found.
49+
*
50+
* @param source the input document
51+
* @param errorHandler the error handler to use. May be {@code null}, in which case a default will be used.
52+
* @return an array of <code>SAXParseException</code>s
53+
* @throws IOException if the <code>source</code> cannot be read
54+
* @throws XmlValidationException if the <code>source</code> cannot be validated
55+
*/
56+
SAXParseException[] validate(Source source, ValidationErrorHandler errorHandler) throws IOException;
57+
4658
}

xml/src/main/java/org/springframework/xml/validation/XmlValidatorFactory.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2011 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.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -91,12 +91,8 @@ public static XmlValidator createValidator(Resource[] schemaResources, String sc
9191
logger.trace("Creating JAXP 1.3 XmlValidator");
9292
return Jaxp13ValidatorFactory.createValidator(schemaResources, schemaLanguage);
9393
}
94-
else if (JaxpVersion.getJaxpVersion() >= JaxpVersion.JAXP_10) {
95-
logger.trace("Creating JAXP 1.0 XmlValidator");
96-
return Jaxp10ValidatorFactory.createValidator(schemaResources, schemaLanguage);
97-
}
9894
else {
99-
throw new IllegalStateException("Could not locate JAXP 1.0 or higher.");
95+
throw new IllegalStateException("Could not locate JAXP 1.3.");
10096
}
10197
}
10298

0 commit comments

Comments
 (0)