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 }