1 package pl.psnc.dl.ege.validator.xml;
2
3 import java.io.FileNotFoundException;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.io.PipedInputStream;
8 import java.io.PipedOutputStream;
9
10 import javax.xml.parsers.ParserConfigurationException;
11 import javax.xml.parsers.SAXParser;
12 import javax.xml.parsers.SAXParserFactory;
13
14 import org.apache.log4j.Logger;
15 import org.jdom.DocType;
16 import org.jdom.Document;
17 import org.jdom.JDOMException;
18 import org.jdom.input.SAXBuilder;
19 import org.jdom.output.XMLOutputter;
20 import org.xml.sax.ErrorHandler;
21 import org.xml.sax.InputSource;
22 import org.xml.sax.SAXException;
23 import org.xml.sax.SAXParseException;
24 import org.xml.sax.XMLReader;
25
26 import pl.psnc.dl.ege.ExceptionListener;
27 import pl.psnc.dl.ege.validator.StandardErrorHandler;
28
29
30
31
32
33
34
35
36
37 public class DTDValidator
38 implements XmlValidator
39 {
40
41 private static final Logger LOGGER = Logger.getLogger(DTDValidator.class);
42
43
44
45
46 private final String mainDTD;
47
48
49
50
51 private final String root;
52
53
54
55
56
57
58
59
60 public DTDValidator(String systemId, String root)
61 {
62 if (systemId == null || root == null) {
63 throw new IllegalArgumentException();
64 }
65 this.root = root;
66 this.mainDTD = systemId;
67 }
68
69
70
71
72
73
74
75
76 public void validateXml(InputStream inputData, ErrorHandler errorHandler)
77 throws SAXException, FileNotFoundException, IOException, Exception
78 {
79 PipedOutputStream os = new PipedOutputStream();
80 PipedInputStream is = new PipedInputStream(os);
81 ExceptionListenerImpl el = new ExceptionListenerImpl();
82 DoctypeFilter filter = new DoctypeFilter(inputData, os, el, errorHandler);
83 filter.start();
84 SAXParserFactory factory = SAXParserFactory.newInstance();
85 factory.setValidating(true);
86 factory.setNamespaceAware(true);
87 try {
88 SAXParser parser = factory.newSAXParser();
89 XMLReader reader = parser.getXMLReader();
90 reader.setErrorHandler(errorHandler);
91 reader.parse(new InputSource(is));
92 }
93 catch (ParserConfigurationException ex) {
94 throw new SAXException(ex.getMessage());
95 }catch (SAXParseException ex){
96 filter.join();
97 Exception exe = el.throwException();
98 if(exe != null){
99 throw exe;
100 }
101 }
102 }
103
104
105
106
107
108 private class DoctypeFilter
109 extends Thread
110 {
111
112 private final InputStream inputStream;
113
114 private final OutputStream outputStream;
115
116 private final ExceptionListener el;
117
118 private final ErrorHandler eh;
119
120 public DoctypeFilter(InputStream is, OutputStream os,
121 ExceptionListener el, ErrorHandler eh)
122 {
123 super();
124 inputStream = is;
125 outputStream = os;
126 this.el = el;
127 this.eh = eh;
128 }
129
130
131 @Override
132 public void run()
133 {
134 try {
135 SAXBuilder sb = new SAXBuilder();
136 Document doc = sb.build(inputStream);
137 if (doc.getDocType() == null) {
138 doc.setDocType(new DocType(root, mainDTD));
139 }
140 XMLOutputter outp = new XMLOutputter();
141 outp.output(doc, outputStream);
142 outputStream.flush();
143 }
144 catch(FileNotFoundException ex){
145 el.catchException(ex);
146 }
147 catch (JDOMException ex) {
148 el.catchException(ex);
149 }
150 catch (IOException ex) {
151 LOGGER.error(ex.getMessage(), ex);
152 el.catchException(ex);
153 }
154 finally {
155 if (outputStream != null) {
156 try {
157 outputStream.close();
158 }
159 catch (IOException ex) {
160 LOGGER.error(ex.getMessage());
161 }
162 }
163 }
164
165 }
166
167 }
168
169 }