/projects/castor-1.3.3/xml/src/main/java/org/exolab/castor/xml/util/XMLParserUtils.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus · Java · 275 lines · 171 code · 30 blank · 74 comment · 24 complexity · 2a4fc58d023324261a86cf60afa7f41b MD5 · raw file

  1. package org.exolab.castor.xml.util;
  2. import java.util.StringTokenizer;
  3. import javax.xml.parsers.ParserConfigurationException;
  4. import javax.xml.parsers.SAXParser;
  5. import javax.xml.parsers.SAXParserFactory;
  6. import org.apache.commons.logging.Log;
  7. import org.apache.commons.logging.LogFactory;
  8. import org.castor.core.util.AbstractProperties;
  9. import org.castor.core.util.Messages;
  10. import org.castor.xml.XMLProperties;
  11. import org.exolab.castor.xml.OutputFormat;
  12. import org.exolab.castor.xml.Serializer;
  13. import org.exolab.castor.xml.XMLSerializerFactory;
  14. import org.xml.sax.Parser;
  15. import org.xml.sax.SAXException;
  16. import org.xml.sax.SAXNotRecognizedException;
  17. import org.xml.sax.SAXNotSupportedException;
  18. import org.xml.sax.XMLReader;
  19. /**
  20. * A couple of routines to manipulate XMLParser instances. Mostly extracted
  21. * from 'old' LocalConfiguration class.
  22. *
  23. * @author Joachim Grueneis, jgrueneis_at_gmail_dot_com
  24. * @version $Id$
  25. * @since 1.1.3
  26. */
  27. public class XMLParserUtils {
  28. /**
  29. * Logger to be used.
  30. */
  31. static final Log LOG = LogFactory.getFactory().getInstance(XMLParserUtils.class);
  32. /**
  33. * To set validation feature of XMLReader.
  34. */
  35. private static final String VALIDATION = "http://xml.org/sax/features/validation";
  36. /**
  37. * To set namespaces feature of XMLReader.
  38. */
  39. private static final String NAMESPACES = "http://xml.org/sax/features/namespaces";
  40. /**
  41. * Sets features on XML reader instance.
  42. * @param properties the Properties to read parser features from
  43. * @param defaultFeatures any default features to use
  44. * @param validation Whether to enable validation or not.
  45. * @param namespaces Whether to enable namespace support for not.
  46. * @param xmlReader The XMLReader instance to configure.
  47. */
  48. public static void setFeaturesOnXmlReader(
  49. final String parserFeatures,
  50. final String parserFeaturesToDisable,
  51. final boolean validation,
  52. final boolean namespaces,
  53. final XMLReader xmlReader) {
  54. try {
  55. xmlReader.setFeature(VALIDATION, validation);
  56. xmlReader.setFeature(NAMESPACES, namespaces);
  57. enableFeatures(parserFeatures, xmlReader);
  58. disableFeatures(parserFeaturesToDisable, xmlReader);
  59. } catch (SAXException except) {
  60. LOG.error(Messages.format("conf.configurationError", except));
  61. }
  62. }
  63. /**
  64. * Enables selected features on the XMLReader instance.
  65. * @param features Features to enable
  66. * @param xmlReader XMLReader instance to be configured.
  67. * @throws SAXNotRecognizedException If the feature is not recognized by the XMLReader.
  68. * @throws SAXNotSupportedException If the feature is not supported by the XMLReader.
  69. */
  70. private static void enableFeatures(final String features, final XMLReader xmlReader)
  71. throws SAXNotRecognizedException, SAXNotSupportedException {
  72. StringTokenizer token;
  73. if (features != null) {
  74. token = new StringTokenizer(features, ", ");
  75. while (token.hasMoreTokens()) {
  76. xmlReader.setFeature(token.nextToken(), true);
  77. }
  78. }
  79. }
  80. /**
  81. * Disables selected features on the XMLReader instance.
  82. * @param features Features to disable
  83. * @param xmlReader XMLReader instance to be configured.
  84. * @throws SAXNotRecognizedException If the feature is not recognized by the XMLReader.
  85. * @throws SAXNotSupportedException If the feature is not supported by the XMLReader.
  86. */
  87. private static void disableFeatures(final String features, final XMLReader xmlReader)
  88. throws SAXNotRecognizedException, SAXNotSupportedException {
  89. StringTokenizer token;
  90. if (features != null) {
  91. token = new StringTokenizer(features, ", ");
  92. while (token.hasMoreTokens()) {
  93. xmlReader.setFeature(token.nextToken(), false);
  94. }
  95. }
  96. }
  97. /**
  98. * To get a SAXParser instance which is then used to get either
  99. * parser or XMLReader.
  100. * @param validation validation flag to set into parser factory
  101. * @param namespaces namespace flag to set into parser factory
  102. * @return the SAXParser for further use
  103. */
  104. public static SAXParser getSAXParser(final boolean validation, final boolean namespaces) {
  105. SAXParser saxParser = null;
  106. SAXParserFactory factory = SAXParserFactory.newInstance();
  107. factory.setNamespaceAware(namespaces);
  108. factory.setValidating(validation);
  109. try {
  110. saxParser = factory.newSAXParser();
  111. if (LOG.isDebugEnabled()) {
  112. LOG.debug("Successfully instantiated a JAXP SAXParser instance.");
  113. }
  114. } catch (ParserConfigurationException pcx) {
  115. LOG.error(Messages.format("conf.configurationError", pcx));
  116. } catch (org.xml.sax.SAXException sx) {
  117. LOG.error(Messages.format("conf.configurationError", sx));
  118. }
  119. return saxParser;
  120. }
  121. /**
  122. * Instantiates an {@link XMLReader} instance directly, using {@link Class#forName(String)}
  123. * to obtain the {@link Class} instance, and uses {@link Class#newInstance()}
  124. * to create the actual instance.
  125. * @param className The class name of the {@link XMLReader} instance to be instantiated.
  126. * @return An {@link XMLReader} instance.
  127. */
  128. public static XMLReader instantiateXMLReader(final String className) {
  129. XMLReader xmlReader;
  130. try {
  131. Class cls;
  132. cls = Class.forName(className);
  133. xmlReader = (XMLReader) cls.newInstance();
  134. if (LOG.isDebugEnabled()) {
  135. LOG.debug("Successfully instantiated " + className);
  136. }
  137. } catch (Exception except) {
  138. throw new RuntimeException(Messages.format(
  139. "conf.failedInstantiateParser", className, except));
  140. }
  141. return xmlReader;
  142. }
  143. /**
  144. * Instantiates an {@link Parser} instance directly, using {@link Class#forName(String)}
  145. * to obtain the {@link Class} instance, and uses {@link Class#newInstance()}
  146. * to create the actual instance.
  147. * @param className The class name of the {@link Parser} instance to be instantiated.
  148. * @return An {@link Parser} instance.
  149. */
  150. public static Parser instantiateParser (final String className) {
  151. Parser parser;
  152. try {
  153. Class cls;
  154. cls = Class.forName(className);
  155. parser = (Parser) cls.newInstance();
  156. if (LOG.isDebugEnabled()) {
  157. LOG.debug("Successfully instantiated " + className);
  158. }
  159. } catch (Exception except) {
  160. throw new RuntimeException(Messages.format(
  161. "conf.failedInstantiateParser", className, except));
  162. }
  163. return parser;
  164. }
  165. public static Parser getParser(final AbstractProperties properties, final String features) {
  166. Parser parser = null;
  167. Boolean validation = properties.getBoolean(XMLProperties.PARSER_VALIDATION);
  168. Boolean namespaces = properties.getBoolean(XMLProperties.NAMESPACES);
  169. String parserClassName = properties.getString(XMLProperties.PARSER);
  170. if ((parserClassName == null) || (parserClassName.length() == 0)) {
  171. SAXParser saxParser = XMLParserUtils.getSAXParser(
  172. validation.booleanValue(), namespaces.booleanValue());
  173. if (saxParser != null) {
  174. try {
  175. parser = saxParser.getParser();
  176. } catch (SAXException e) {
  177. LOG.error(Messages.format("conf.configurationError", e));
  178. }
  179. }
  180. }
  181. if (parser == null) {
  182. if ((parserClassName == null)
  183. || (parserClassName.length() == 0)
  184. || (parserClassName.equalsIgnoreCase("xerces"))) {
  185. parserClassName = "org.apache.xerces.parsers.SAXParser";
  186. }
  187. // if a parser class was specified, we try to create it
  188. parser = XMLParserUtils.instantiateParser(parserClassName);
  189. if (parser instanceof XMLReader) {
  190. XMLReader xmlReader = (XMLReader) parser;
  191. XMLParserUtils.setFeaturesOnXmlReader(
  192. properties.getString(XMLProperties.PARSER_FEATURES, features),
  193. properties.getString(XMLProperties.PARSER_FEATURES_DISABLED, ""),
  194. validation.booleanValue(),
  195. namespaces.booleanValue(),
  196. xmlReader);
  197. }
  198. }
  199. return parser;
  200. }
  201. /**
  202. * @see org.castor.xml.InternalContext#getSerializer()
  203. */
  204. public static Serializer getSerializer(final AbstractProperties properties) {
  205. Serializer serializer = getSerializerFactory(
  206. properties.getString(XMLProperties.SERIALIZER_FACTORY)).getSerializer();
  207. serializer.setOutputFormat(getOutputFormat(properties));
  208. return serializer;
  209. }
  210. /**
  211. * @see org.castor.xml.InternalContext#getOutputFormat()
  212. */
  213. public static OutputFormat getOutputFormat(final AbstractProperties properties) {
  214. boolean indent = properties.getBoolean(XMLProperties.USE_INDENTATION, false);
  215. String version = properties.getString(XMLProperties.XML_VERSION, "1.0");
  216. OutputFormat format = getSerializerFactory(
  217. properties.getString(XMLProperties.SERIALIZER_FACTORY)).getOutputFormat();
  218. format.setMethod(OutputFormat.XML);
  219. format.setVersion(version);
  220. format.setIndenting(indent);
  221. // There is a bad interaction between the indentation and the
  222. // setPreserveSpace option. The indentated output is strangely indented.
  223. if (!indent) {
  224. format.setPreserveSpace(true);
  225. }
  226. return format;
  227. } //-- getOutputFormat
  228. /**
  229. * Returns the currently configured XMLSerializerFactory instance.
  230. * @param serializerFactoryName the class name of the serializer factory
  231. * @return XMLSerializerFactory to use by Castor
  232. */
  233. public static XMLSerializerFactory getSerializerFactory(final String serializerFactoryName) {
  234. XMLSerializerFactory serializerFactory;
  235. try {
  236. serializerFactory = (XMLSerializerFactory)
  237. Class.forName(serializerFactoryName).newInstance();
  238. } catch (Exception except) {
  239. throw new RuntimeException(
  240. Messages.format("conf.failedInstantiateSerializerFactory",
  241. serializerFactoryName, except));
  242. }
  243. return serializerFactory;
  244. }
  245. }