1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package junitx.ddtunit.data.processing.parser;
39
40 import java.io.File;
41 import java.io.IOException;
42 import java.io.InputStream;
43
44 import javax.xml.parsers.ParserConfigurationException;
45 import javax.xml.parsers.SAXParserFactory;
46
47 import junitx.ddtunit.DDTException;
48
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.xml.sax.InputSource;
52 import org.xml.sax.Locator;
53 import org.xml.sax.SAXException;
54 import org.xml.sax.SAXNotRecognizedException;
55 import org.xml.sax.SAXParseException;
56 import org.xml.sax.XMLReader;
57 import org.xml.sax.helpers.DefaultHandler;
58 import org.xml.sax.helpers.LocatorImpl;
59
60
61
62
63 public final class SAXValidator extends ErrorHandler {
64 private static final String XML_XERCES_NONAMESPACE_SCHEMA_LOCATION_URI = "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation";
65
66 private static final String XML_XERCES_SCHEMA_FULL_CHECK_URI = "http://apache.org/xml/features/validation/schema-full-checking";
67
68 private static final String XML_XERCES_VALIDATE_URI = "http://apache.org/xml/features/validation/schema";
69
70
71
72
73 public final static String XSD_RESOURCE_PATH = "/junitx/ddtunit/data/processing/parser/ddtunit.xsd";
74
75 private Logger log = LoggerFactory.getLogger(SAXValidator.class);
76
77 private XMLReader producer;
78
79 private DefaultHandler consumer;
80
81 private static final String XML_VALIDATE_URI = "http://xml.org/sax/features/validation";
82
83 private static final String XML_NAMESPACE_URI = "http://xml.org/sax/features/namespaces";
84
85 private static final String XML_NAMESPACE_PREFIX_URI = "http://xml.org/sax/features/namespace-prefixes";
86
87 private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
88
89 private static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
90
91 private static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
92
93 private static final String LF = System.getProperty("line.separator");
94
95 public SAXValidator() {
96 log.debug("DDTParser - constructor START");
97 try {
98
99
100
101 SAXParserFactory factory = SAXParserFactory.newInstance();
102 factory.setNamespaceAware(true);
103 factory.setValidating(true);
104 this.producer = factory.newSAXParser().getXMLReader();
105
106 this.producer.setFeature(XML_NAMESPACE_PREFIX_URI, false);
107 this.producer.setFeature(XML_NAMESPACE_URI, true);
108
109 this.producer.setFeature(XML_VALIDATE_URI, true);
110 this.producer.setFeature(XML_XERCES_VALIDATE_URI, true);
111 this.producer.setFeature(XML_XERCES_SCHEMA_FULL_CHECK_URI, true);
112 this.producer.setProperty(
113 XML_XERCES_NONAMESPACE_SCHEMA_LOCATION_URI, ParserImpl.XSD_URL);
114 this.producer.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
115 this.producer.setProperty(JAXP_SCHEMA_SOURCE, ParserImpl.XSD_URL);
116 } catch (SAXNotRecognizedException e) {
117 throw DDTException
118 .create(
119 new StringBuffer(
120 "XML ParserImpl does not support schema validation as of JAXP 1.2"),
121 e);
122 } catch (ParserConfigurationException e) {
123 throw DDTException.create(new StringBuffer(
124 "Error configuring parser."), e);
125 } catch (SAXException e) {
126 throw DDTException.create(new StringBuffer(
127 "Error configuring parser."), e);
128 }
129
130 this.producer.setErrorHandler(new ErrorHandler());
131 this.producer.setEntityResolver(new EntityResolver());
132 log.debug("DDTParser - constructor END");
133
134 }
135
136 public void validate(String resourceName) {
137 this.consumer = new DefaultHandler();
138 Locator locator = new LocatorImpl();
139 this.consumer.setDocumentLocator(locator);
140 this.producer.setContentHandler(consumer);
141 this.producer.setEntityResolver(new EntityResolver());
142 try {
143
144
145 InputSource iSource = null;
146 InputStream in = this.getClass().getResourceAsStream(resourceName);
147
148 if (in == null) {
149 File inFile = new File(resourceName);
150
151 if (inFile.exists()) {
152 iSource = new InputSource(resourceName);
153 iSource.setSystemId(inFile.toURL().toExternalForm());
154 this.producer.parse(iSource);
155 } else {
156 StringBuffer sb = new StringBuffer();
157 sb.append("Could not find provided testdata resource: ")
158 .append(resourceName);
159 throw DDTException.create(sb, null);
160 }
161 } else {
162 iSource = new InputSource(in);
163 iSource.setSystemId(this.getClass().getResource(resourceName)
164 .toExternalForm());
165 this.producer.parse(iSource);
166 }
167 } catch (IOException e) {
168 log.error("Error on behalf of xml test resource.", e);
169 throw DDTException.create(new StringBuffer(
170 "Error on behalf of xml test resource."), e);
171 } catch (SAXException e) {
172 StringBuffer sb = new StringBuffer(
173 "Error during parsing of xml testresource");
174 if (SAXParseException.class.isInstance(e)) {
175 sb.append(LF).append("Resource \'").append(resourceName)
176 .append("\' line/column ").append(
177 ((SAXParseException) e).getLineNumber()).append("/")
178 .append(((SAXParseException) e).getColumnNumber());
179 }
180 log.error(sb.toString(), e);
181 throw DDTException.create(sb, e);
182 } finally {
183 log.debug("parse(" + resourceName + ")-END");
184 }
185 }
186 }