1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.xml.validation;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.List;
24 import javax.xml.parsers.ParserConfigurationException;
25 import javax.xml.parsers.SAXParser;
26 import javax.xml.parsers.SAXParserFactory;
27 import javax.xml.transform.Source;
28 import javax.xml.transform.Transformer;
29 import javax.xml.transform.TransformerException;
30 import javax.xml.transform.TransformerFactory;
31 import javax.xml.transform.dom.DOMSource;
32 import javax.xml.transform.sax.SAXSource;
33 import javax.xml.transform.stream.StreamResult;
34 import javax.xml.transform.stream.StreamSource;
35
36 import org.springframework.core.io.Resource;
37 import org.springframework.xml.sax.SaxUtils;
38
39 import org.xml.sax.InputSource;
40 import org.xml.sax.SAXException;
41 import org.xml.sax.SAXParseException;
42 import org.xml.sax.helpers.DefaultHandler;
43
44
45
46
47
48
49
50
51 @Deprecated
52 abstract class Jaxp10ValidatorFactory {
53
54 private static final String SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
55
56 private static final String SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
57
58 static XmlValidator createValidator(Resource[] schemaResources, String schemaLanguage) throws IOException {
59 InputSource[] inputSources = new InputSource[schemaResources.length];
60 for (int i = 0; i < schemaResources.length; i++) {
61 inputSources[i] = SaxUtils.createInputSource(schemaResources[i]);
62 }
63 return new Jaxp10Validator(inputSources, schemaLanguage);
64 }
65
66 private static class Jaxp10Validator implements XmlValidator {
67
68 private SAXParserFactory parserFactory;
69
70 private TransformerFactory transformerFactory;
71
72 private InputSource[] schemaInputSources;
73
74 private String schemaLanguage;
75
76 private Jaxp10Validator(InputSource[] schemaInputSources, String schemaLanguage) {
77 this.schemaInputSources = schemaInputSources;
78 this.schemaLanguage = schemaLanguage;
79 transformerFactory = TransformerFactory.newInstance();
80 parserFactory = SAXParserFactory.newInstance();
81 parserFactory.setNamespaceAware(true);
82 parserFactory.setValidating(true);
83 }
84
85 public SAXParseException[] validate(Source source, ValidationErrorHandler errorHandler)
86 throws IOException {
87 return validate(source);
88 }
89
90 public SAXParseException[] validate(Source source) throws IOException {
91 SAXParser parser = createSAXParser();
92 DefaultValidationErrorHandler errorHandler = new DefaultValidationErrorHandler();
93 try {
94 if (source instanceof SAXSource) {
95 validateSAXSource((SAXSource) source, parser, errorHandler);
96 }
97 else if (source instanceof StreamSource) {
98 validateStreamSource((StreamSource) source, parser, errorHandler);
99 }
100 else if (source instanceof DOMSource) {
101 validateDOMSource((DOMSource) source, parser, errorHandler);
102 }
103 else {
104 throw new IllegalArgumentException("Source [" + source.getClass().getName() +
105 "] is neither SAXSource, DOMSource, nor StreamSource");
106 }
107 return errorHandler.getErrors();
108 }
109 catch (SAXException ex) {
110 throw new XmlValidationException("Could not validate source: " + ex.getMessage(), ex);
111 }
112 }
113
114 private void validateDOMSource(DOMSource domSource, SAXParser parser, DefaultValidationErrorHandler errorHandler)
115 throws IOException, SAXException {
116 try {
117
118
119 Transformer transformer = transformerFactory.newTransformer();
120 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
121 transformer.transform(domSource, new StreamResult(outputStream));
122 ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
123 validateStreamSource(new StreamSource(inputStream), parser, errorHandler);
124 }
125 catch (TransformerException ex) {
126 throw new XmlValidationException("Could not validate DOM source: " + ex.getMessage(), ex);
127 }
128
129 }
130
131 private void validateStreamSource(StreamSource streamSource,
132 SAXParser parser,
133 DefaultValidationErrorHandler errorHandler) throws SAXException, IOException {
134 if (streamSource.getInputStream() != null) {
135 parser.parse(streamSource.getInputStream(), errorHandler);
136 }
137 else if (streamSource.getReader() != null) {
138 parser.parse(new InputSource(streamSource.getReader()), errorHandler);
139 }
140 else {
141 throw new IllegalArgumentException("StreamSource contains neither InputStream nor Reader");
142 }
143 }
144
145 private void validateSAXSource(SAXSource source, SAXParser parser, DefaultValidationErrorHandler errorHandler)
146 throws SAXException, IOException {
147 parser.parse(source.getInputSource(), errorHandler);
148 }
149
150 private SAXParser createSAXParser() {
151 try {
152 SAXParser parser = parserFactory.newSAXParser();
153 parser.setProperty(SCHEMA_LANGUAGE, schemaLanguage);
154 parser.setProperty(SCHEMA_SOURCE, schemaInputSources);
155 return parser;
156 }
157 catch (ParserConfigurationException ex) {
158 throw new XmlValidationException("Could not create SAXParser: " + ex.getMessage(), ex);
159 }
160 catch (SAXException ex) {
161 throw new XmlValidationException("Could not create SAXParser: " + ex.getMessage(), ex);
162 }
163 }
164 }
165
166
167 private static class DefaultValidationErrorHandler extends DefaultHandler {
168
169 private List<SAXParseException> errors = new ArrayList<SAXParseException>();
170
171 private SAXParseException[] getErrors() {
172 return errors.toArray(new SAXParseException[errors.size()]);
173 }
174
175 @Override
176 public void warning(SAXParseException ex) throws SAXException {
177 }
178
179 @Override
180 public void error(SAXParseException ex) throws SAXException {
181 errors.add(ex);
182 }
183
184 @Override
185 public void fatalError(SAXParseException ex) throws SAXException {
186 errors.add(ex);
187 }
188 }
189 }