You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

JAXPUtils.java 9.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if
  20. * any, must include the following acknowlegement:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowlegement may appear in the software itself,
  24. * if and wherever such third-party acknowlegements normally appear.
  25. *
  26. * 4. The names "Ant" and "Apache Software
  27. * Foundation" must not be used to endorse or promote products derived
  28. * from this software without prior written permission. For written
  29. * permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache"
  32. * nor may "Apache" appear in their names without prior written
  33. * permission of the Apache Group.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation. For more
  51. * information on the Apache Software Foundation, please see
  52. * <http://www.apache.org/>.
  53. */
  54. package org.apache.tools.ant.util;
  55. import java.io.File;
  56. import javax.xml.parsers.DocumentBuilder;
  57. import javax.xml.parsers.DocumentBuilderFactory;
  58. import javax.xml.parsers.FactoryConfigurationError;
  59. import javax.xml.parsers.ParserConfigurationException;
  60. import javax.xml.parsers.SAXParser;
  61. import javax.xml.parsers.SAXParserFactory;
  62. import org.apache.tools.ant.BuildException;
  63. import org.xml.sax.Parser;
  64. import org.xml.sax.SAXException;
  65. import org.xml.sax.XMLReader;
  66. /**
  67. * Collection of helper methods that retrieve a ParserFactory or
  68. * Parsers and Readers.
  69. *
  70. * <p>This class will create only a single factory instance.</p>
  71. *
  72. * @author Stefan Bodewig
  73. *
  74. * @since Ant 1.5
  75. */
  76. public class JAXPUtils {
  77. /**
  78. * Helper for systemId.
  79. *
  80. * @since Ant 1.6
  81. */
  82. private static final FileUtils fu = FileUtils.newFileUtils();
  83. /**
  84. * Parser factory to use to create parsers.
  85. * @see #getParserFactory
  86. *
  87. * @since Ant 1.5
  88. */
  89. private static SAXParserFactory parserFactory = null;
  90. /**
  91. * Parser Factory to create Namespace aware parsers.
  92. *
  93. * @since Ant 1.6
  94. */
  95. private static SAXParserFactory nsParserFactory = null;
  96. /**
  97. * Parser factory to use to create document builders.
  98. *
  99. * @since Ant 1.7
  100. */
  101. private static DocumentBuilderFactory builderFactory = null;
  102. /**
  103. * Returns the parser factory to use. Only one parser factory is
  104. * ever created by this method and is then cached for future use.
  105. *
  106. * @return a SAXParserFactory to use
  107. *
  108. * @since Ant 1.5
  109. */
  110. public static synchronized SAXParserFactory getParserFactory()
  111. throws BuildException {
  112. if (parserFactory == null) {
  113. parserFactory = newParserFactory();
  114. }
  115. return parserFactory;
  116. }
  117. /**
  118. * Returns the parser factory to use to create namespace aware parsers.
  119. *
  120. * @return a SAXParserFactory to use which supports manufacture of
  121. * namespace aware parsers
  122. *
  123. * @since Ant 1.6
  124. */
  125. public static synchronized SAXParserFactory getNSParserFactory()
  126. throws BuildException {
  127. if (nsParserFactory == null) {
  128. nsParserFactory = newParserFactory();
  129. nsParserFactory.setNamespaceAware(true);
  130. }
  131. return nsParserFactory;
  132. }
  133. /**
  134. * Returns a new parser factory instance.
  135. *
  136. * @since Ant 1.5
  137. */
  138. public static SAXParserFactory newParserFactory() throws BuildException {
  139. try {
  140. return SAXParserFactory.newInstance();
  141. } catch (FactoryConfigurationError e) {
  142. throw new BuildException("XML parser factory has not been "
  143. + "configured correctly: "
  144. + e.getMessage(), e);
  145. }
  146. }
  147. /**
  148. * Returns a newly created SAX 1 Parser, using the default parser
  149. * factory.
  150. *
  151. * @return a SAX 1 Parser.
  152. * @see #getParserFactory
  153. * @since Ant 1.5
  154. */
  155. public static Parser getParser() throws BuildException {
  156. try {
  157. return newSAXParser(getParserFactory()).getParser();
  158. } catch (SAXException e) {
  159. throw convertToBuildException(e);
  160. }
  161. }
  162. /**
  163. * Returns a newly created SAX 2 XMLReader, using the default parser
  164. * factory.
  165. *
  166. * @return a SAX 2 XMLReader.
  167. * @see #getParserFactory
  168. * @since Ant 1.5
  169. */
  170. public static XMLReader getXMLReader() throws BuildException {
  171. try {
  172. return newSAXParser(getParserFactory()).getXMLReader();
  173. } catch (SAXException e) {
  174. throw convertToBuildException(e);
  175. }
  176. }
  177. /**
  178. * Returns a newly created SAX 2 XMLReader, which is namespace aware
  179. *
  180. * @return a SAX 2 XMLReader.
  181. * @see #getParserFactory
  182. * @since Ant 1.6
  183. */
  184. public static XMLReader getNamespaceXMLReader() throws BuildException {
  185. try {
  186. return newSAXParser(getNSParserFactory()).getXMLReader();
  187. } catch (SAXException e) {
  188. throw convertToBuildException(e);
  189. }
  190. }
  191. /**
  192. * This is a best attempt to provide a URL.toExternalForm() from
  193. * a file URL. Some parsers like Crimson choke on uri that are made of
  194. * backslashed paths (ie windows) as it is does not conform
  195. * URI specifications.
  196. * @param file the file to create the system id from.
  197. * @return the systemid corresponding to the given file.
  198. * @since Ant 1.5.2
  199. */
  200. public static String getSystemId(File file) {
  201. return fu.toURI(file.getAbsolutePath());
  202. }
  203. /**
  204. * Returns a newly created DocumentBuilder.
  205. *
  206. * @return a DocumentVuilder
  207. * @since Ant 1.7
  208. */
  209. public static DocumentBuilder getDocumentBuilder() throws BuildException {
  210. try {
  211. return getDocumentBuilderFactory().newDocumentBuilder();
  212. } catch (ParserConfigurationException e) {
  213. throw new BuildException(e);
  214. }
  215. }
  216. /**
  217. * @return a new SAXParser instance as helper for getParser and
  218. * getXMLReader.
  219. *
  220. * @since Ant 1.5
  221. */
  222. private static SAXParser newSAXParser(SAXParserFactory factory)
  223. throws BuildException {
  224. try {
  225. return factory.newSAXParser();
  226. } catch (ParserConfigurationException e) {
  227. throw new BuildException("Cannot create parser for the given "
  228. + "configuration: " + e.getMessage(), e);
  229. } catch (SAXException e) {
  230. throw convertToBuildException(e);
  231. }
  232. }
  233. /**
  234. * Translate a SAXException into a BuildException
  235. *
  236. * @since Ant 1.5
  237. */
  238. private static BuildException convertToBuildException(SAXException e) {
  239. Exception nested = e.getException();
  240. if (nested != null) {
  241. return new BuildException(nested);
  242. } else {
  243. return new BuildException(e);
  244. }
  245. }
  246. /**
  247. * Obtains the default builder factory if not already.
  248. *
  249. * @since Ant 1.7
  250. */
  251. private static synchronized
  252. DocumentBuilderFactory getDocumentBuilderFactory()
  253. throws BuildException {
  254. if (builderFactory == null) {
  255. try {
  256. builderFactory = DocumentBuilderFactory.newInstance();
  257. } catch (FactoryConfigurationError e) {
  258. throw new BuildException("Document builder factory has not "
  259. + "been configured correctly: "
  260. + e.getMessage(), e);
  261. }
  262. }
  263. return builderFactory;
  264. }
  265. }