1 package org.exolab.castor.xml.util;
2
3 import java.util.StringTokenizer;
4
5 import javax.xml.parsers.ParserConfigurationException;
6 import javax.xml.parsers.SAXParser;
7 import javax.xml.parsers.SAXParserFactory;
8
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
11 import org.castor.core.util.AbstractProperties;
12 import org.castor.core.util.Messages;
13 import org.castor.xml.XMLProperties;
14 import org.exolab.castor.xml.OutputFormat;
15 import org.exolab.castor.xml.Serializer;
16 import org.exolab.castor.xml.XMLSerializerFactory;
17 import org.xml.sax.Parser;
18 import org.xml.sax.SAXException;
19 import org.xml.sax.SAXNotRecognizedException;
20 import org.xml.sax.SAXNotSupportedException;
21 import org.xml.sax.XMLReader;
22
23
24
25
26
27
28
29
30
31 public class XMLParserUtils {
32
33
34
35
36 static final Log LOG = LogFactory.getFactory().getInstance(XMLParserUtils.class);
37
38
39
40
41 private static final String VALIDATION = "http://xml.org/sax/features/validation";
42
43
44
45
46 private static final String NAMESPACES = "http://xml.org/sax/features/namespaces";
47
48
49
50
51
52
53
54
55
56 public static void setFeaturesOnXmlReader(
57 final String parserFeatures,
58 final String parserFeaturesToDisable,
59 final boolean validation,
60 final boolean namespaces,
61 final XMLReader xmlReader) {
62 try {
63 xmlReader.setFeature(VALIDATION, validation);
64 xmlReader.setFeature(NAMESPACES, namespaces);
65 enableFeatures(parserFeatures, xmlReader);
66 disableFeatures(parserFeaturesToDisable, xmlReader);
67 } catch (SAXException except) {
68 LOG.error(Messages.format("conf.configurationError", except));
69 }
70 }
71
72
73
74
75
76
77
78
79 private static void enableFeatures(final String features, final XMLReader xmlReader)
80 throws SAXNotRecognizedException, SAXNotSupportedException {
81 StringTokenizer token;
82 if (features != null) {
83 token = new StringTokenizer(features, ", ");
84 while (token.hasMoreTokens()) {
85 xmlReader.setFeature(token.nextToken(), true);
86 }
87 }
88 }
89
90
91
92
93
94
95
96
97 private static void disableFeatures(final String features, final XMLReader xmlReader)
98 throws SAXNotRecognizedException, SAXNotSupportedException {
99 StringTokenizer token;
100 if (features != null) {
101 token = new StringTokenizer(features, ", ");
102 while (token.hasMoreTokens()) {
103 xmlReader.setFeature(token.nextToken(), false);
104 }
105 }
106 }
107
108
109
110
111
112
113
114
115 public static SAXParser getSAXParser(final boolean validation, final boolean namespaces) {
116 SAXParser saxParser = null;
117
118 SAXParserFactory factory = SAXParserFactory.newInstance();
119 factory.setNamespaceAware(namespaces);
120 factory.setValidating(validation);
121 try {
122 saxParser = factory.newSAXParser();
123 if (LOG.isDebugEnabled()) {
124 LOG.debug("Successfully instantiated a JAXP SAXParser instance.");
125 }
126 } catch (ParserConfigurationException pcx) {
127 LOG.error(Messages.format("conf.configurationError", pcx));
128 } catch (org.xml.sax.SAXException sx) {
129 LOG.error(Messages.format("conf.configurationError", sx));
130 }
131 return saxParser;
132 }
133
134
135
136
137
138
139 public static SAXParser getSAXParser(SAXParserFactory saxParserFactory) {
140 SAXParser saxParser = null;
141
142 try {
143 saxParser = saxParserFactory.newSAXParser();
144 if (LOG.isDebugEnabled()) {
145 LOG.debug("Successfully instantiated a JAXP SAXParser instance.");
146 }
147 } catch (ParserConfigurationException pcx) {
148 LOG.error(Messages.format("conf.configurationError", pcx));
149 } catch (org.xml.sax.SAXException sx) {
150 LOG.error(Messages.format("conf.configurationError", sx));
151 }
152 return saxParser;
153 }
154
155
156
157
158
159
160
161
162 public static SAXParserFactory getSAXParserFactory(final boolean validation, final boolean namespaces) {
163 SAXParserFactory factory = SAXParserFactory.newInstance();
164 factory.setNamespaceAware(namespaces);
165 factory.setValidating(validation);
166 return factory;
167 }
168
169
170
171
172
173
174
175
176 public static XMLReader instantiateXMLReader(final String className) {
177 XMLReader xmlReader;
178 try {
179 Class cls;
180 cls = Class.forName(className);
181 xmlReader = (XMLReader) cls.newInstance();
182 if (LOG.isDebugEnabled()) {
183 LOG.debug("Successfully instantiated " + className);
184 }
185 } catch (Exception except) {
186 throw new RuntimeException(Messages.format(
187 "conf.failedInstantiateParser", className, except));
188 }
189 return xmlReader;
190 }
191
192
193
194
195
196
197
198
199 public static Parser instantiateParser (final String className) {
200 Parser parser;
201 try {
202 Class cls;
203 cls = Class.forName(className);
204 parser = (Parser) cls.newInstance();
205 if (LOG.isDebugEnabled()) {
206 LOG.debug("Successfully instantiated " + className);
207 }
208 } catch (Exception except) {
209 throw new RuntimeException(Messages.format(
210 "conf.failedInstantiateParser", className, except));
211 }
212 return parser;
213 }
214
215 public static Parser getParser(final AbstractProperties properties, final String features) {
216 Parser parser = null;
217 Boolean validation = properties.getBoolean(XMLProperties.PARSER_VALIDATION);
218 Boolean namespaces = properties.getBoolean(XMLProperties.NAMESPACES);
219 String parserClassName = properties.getString(XMLProperties.PARSER);
220 if ((parserClassName == null) || (parserClassName.length() == 0)) {
221 SAXParser saxParser = XMLParserUtils.getSAXParser(
222 validation.booleanValue(), namespaces.booleanValue());
223 if (saxParser != null) {
224 try {
225 parser = saxParser.getParser();
226 } catch (SAXException e) {
227 LOG.error(Messages.format("conf.configurationError", e));
228 }
229 }
230 }
231
232 if (parser == null) {
233 if ((parserClassName == null)
234 || (parserClassName.length() == 0)
235 || (parserClassName.equalsIgnoreCase("xerces"))) {
236 parserClassName = "org.apache.xerces.parsers.SAXParser";
237 }
238
239
240 parser = XMLParserUtils.instantiateParser(parserClassName);
241
242 if (parser instanceof XMLReader) {
243 XMLReader xmlReader = (XMLReader) parser;
244 XMLParserUtils.setFeaturesOnXmlReader(
245 properties.getString(XMLProperties.PARSER_FEATURES, features),
246 properties.getString(XMLProperties.PARSER_FEATURES_DISABLED, ""),
247 validation.booleanValue(),
248 namespaces.booleanValue(),
249 xmlReader);
250 }
251 }
252 return parser;
253 }
254
255
256
257
258 public static Serializer getSerializer(final AbstractProperties properties) {
259 Serializer serializer = getSerializerFactory(
260 properties.getString(XMLProperties.SERIALIZER_FACTORY)).getSerializer();
261 serializer.setOutputFormat(getOutputFormat(properties));
262 return serializer;
263 }
264
265
266
267
268 public static OutputFormat getOutputFormat(final AbstractProperties properties) {
269
270 boolean indent = properties.getBoolean(XMLProperties.USE_INDENTATION, false);
271
272 String version = properties.getString(XMLProperties.XML_VERSION, "1.0");
273
274 OutputFormat format = getSerializerFactory(
275 properties.getString(XMLProperties.SERIALIZER_FACTORY)).getOutputFormat();
276 format.setMethod(OutputFormat.XML);
277 format.setVersion(version);
278 format.setIndenting(indent);
279
280
281
282 if (!indent) {
283 format.setPreserveSpace(true);
284 }
285
286 return format;
287 }
288
289
290
291
292
293
294 public static XMLSerializerFactory getSerializerFactory(final String serializerFactoryName) {
295 XMLSerializerFactory serializerFactory;
296
297 try {
298 serializerFactory = (XMLSerializerFactory)
299 Class.forName(serializerFactoryName).newInstance();
300 } catch (Exception except) {
301 throw new RuntimeException(
302 Messages.format("conf.failedInstantiateSerializerFactory",
303 serializerFactoryName, except));
304 }
305 return serializerFactory;
306 }
307
308
309 }
310