1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.qedeq.kernel.xml.parser;
16
17 import java.io.File;
18 import java.io.FileInputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.MissingResourceException;
22
23 import javax.xml.parsers.ParserConfigurationException;
24 import javax.xml.parsers.SAXParser;
25 import javax.xml.parsers.SAXParserFactory;
26
27 import org.qedeq.base.trace.Trace;
28 import org.qedeq.kernel.se.common.ModuleService;
29 import org.qedeq.kernel.se.common.SourceFileException;
30 import org.qedeq.kernel.se.common.SourceFileExceptionList;
31 import org.qedeq.kernel.xml.common.XmlSyntaxException;
32 import org.qedeq.kernel.xml.handler.common.SaxDefaultHandler;
33 import org.qedeq.kernel.xml.handler.common.SimpleHandler;
34 import org.xml.sax.InputSource;
35 import org.xml.sax.SAXException;
36 import org.xml.sax.SAXNotRecognizedException;
37 import org.xml.sax.XMLReader;
38
39
40
41
42
43
44
45 public final class SaxParser {
46
47
48 private static final Class CLASS = SaxParser.class;
49
50
51 private static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
52
53
54 private static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
55
56
57 private static final String SCHEMA_VALIDATION_FEATURE_ID
58 = "http://apache.org/xml/features/validation/schema";
59
60
61
62 protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID
63 = "http://apache.org/xml/features/validation/schema-full-checking";
64
65
66 private SaxDefaultHandler handler;
67
68
69 private XMLReader reader;
70
71
72 private final SimpleHandler deflt;
73
74
75 private SourceFileExceptionList exceptionList;
76
77
78 private ModuleService plugin;
79
80
81
82
83
84
85
86
87
88 public SaxParser(final ModuleService plugin, final SaxDefaultHandler handler)
89 throws ParserConfigurationException, SAXException {
90 super();
91
92 this.handler = handler;
93 this.deflt = new SimpleHandler();
94 this.plugin = plugin;
95
96 final String factoryImpl = System.getProperty("javax.xml.parsers.SAXParserFactory");
97 if (factoryImpl == null) {
98 System.setProperty("javax.xml.parsers.SAXParserFactory",
99 "org.apache.xerces.jaxp.SAXParserFactoryImpl");
100 }
101 SAXParserFactory factory = SAXParserFactory.newInstance();
102 factory.setNamespaceAware(true);
103 factory.setValidating(true);
104
105 factory.setFeature(NAMESPACES_FEATURE_ID, true);
106 factory.setFeature(VALIDATION_FEATURE_ID, true);
107
108 try {
109 factory.setFeature(SCHEMA_VALIDATION_FEATURE_ID, true);
110 } catch (SAXNotRecognizedException e) {
111 Trace.trace(CLASS, this, "constructor", e);
112
113 }
114 try {
115 factory.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, true);
116 } catch (SAXNotRecognizedException e) {
117 Trace.trace(CLASS, this, "constructor", e);
118
119 }
120
121 final SAXParser parser = factory.newSAXParser();
122 if (!parser.isNamespaceAware()) {
123 throw new ParserConfigurationException(
124 "Current XML parser doesn't support namespaces.");
125 }
126 if (!parser.isValidating()) {
127 throw new ParserConfigurationException(
128 "Current XML parser doesn't support schema validation.");
129 }
130
131 reader = parser.getXMLReader();
132 reader.setEntityResolver(new SaxEntityResolver(handler));
133
134
135 reader.setFeature(NAMESPACES_FEATURE_ID, true);
136 reader.setFeature(VALIDATION_FEATURE_ID, true);
137 try {
138 reader.setFeature(SCHEMA_VALIDATION_FEATURE_ID, true);
139 } catch (SAXNotRecognizedException e) {
140 Trace.trace(CLASS, this, "constructor", e);
141
142 }
143 try {
144 reader.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, true);
145 } catch (SAXNotRecognizedException e) {
146 Trace.trace(CLASS, this, "constructor", e);
147
148 }
149
150 }
151
152
153
154
155
156
157
158
159
160
161 private void parse(final File in, final boolean validateOnly, final String original)
162 throws SourceFileExceptionList {
163 final String method = "parse(URL, boolean, InputStream)";
164 InputStream stream = null;
165 exceptionList = new SourceFileExceptionList();
166 try {
167 stream = new FileInputStream(in);
168 final InputSource input = new InputSource(stream);
169 reader.setErrorHandler(new SaxErrorHandler(plugin, original, exceptionList));
170 handler.setUrl(original);
171 deflt.setUrl(original);
172 if (validateOnly) {
173 try {
174 reader.setContentHandler(deflt);
175 reader.parse(input);
176 } catch (MissingResourceException ex) {
177 throw new SAXException("For " + ex.getClassName() + " we searched for value"
178 + " of " + ex.getKey(), ex);
179 }
180 } else {
181 handler.setExceptionList(exceptionList);
182 reader.setContentHandler(handler);
183 reader.parse(input);
184 }
185 } catch (SAXException e) {
186 if (exceptionList.size() <= 0) {
187
188 final XmlSyntaxException xml = XmlSyntaxException.createBySAXException(e);
189 exceptionList.add(new SourceFileException(plugin, xml, handler.createSourceArea(), null));
190 }
191 throw exceptionList;
192 } catch (IOException e) {
193 final XmlSyntaxException xml = XmlSyntaxException.createByIOException(e);
194 exceptionList.add(new SourceFileException(plugin, xml, handler.createSourceArea(), null));
195 throw exceptionList;
196 } finally {
197 if (stream != null) {
198 try {
199 stream.close();
200 } catch (Exception e) {
201 Trace.trace(CLASS, this, method, e);
202 }
203 }
204 }
205 if (exceptionList.size() > 0) {
206 throw exceptionList;
207 }
208 }
209
210
211
212
213
214
215
216
217
218 public final void parse(final String fileName, final String original)
219 throws SourceFileExceptionList {
220 final File file = new File(fileName);
221 parse(file.getAbsoluteFile(), original);
222 }
223
224
225
226
227
228
229
230
231
232 public final void parse(final File file, final String original) throws SourceFileExceptionList {
233 String org = original;
234 if (org == null) {
235 org = "" + file;
236 }
237 parse(file, true, org);
238 parse(file, false, org);
239 }
240
241
242
243
244
245
246 public SourceFileExceptionList getExceptionList() {
247 return exceptionList;
248 }
249
250
251
252
253
254
255 public String getEncoding() {
256 return deflt.getEncoding();
257 }
258
259 }