JAXPFactory.java 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /* JAXPFactory.java --
  2. Copyright (C) 2001 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package gnu.xml.dom;
  32. import java.io.IOException;
  33. import org.w3c.dom.Document;
  34. import org.w3c.dom.DOMImplementation;
  35. import org.xml.sax.EntityResolver;
  36. import org.xml.sax.ErrorHandler;
  37. import org.xml.sax.InputSource;
  38. import org.xml.sax.XMLReader;
  39. import org.xml.sax.SAXException;
  40. import org.xml.sax.SAXParseException;
  41. import javax.xml.XMLConstants;
  42. import javax.xml.parsers.DocumentBuilder;
  43. import javax.xml.parsers.DocumentBuilderFactory;
  44. import javax.xml.parsers.ParserConfigurationException;
  45. import javax.xml.parsers.SAXParserFactory;
  46. /**
  47. * DOM bootstrapping API, for use with JAXP.
  48. *
  49. * @see Consumer
  50. *
  51. * @author David Brownell
  52. */
  53. public final class JAXPFactory
  54. extends DocumentBuilderFactory
  55. {
  56. private static final String PROPERTY = "http://xml.org/sax/properties/";
  57. private static final String FEATURE = "http://xml.org/sax/features/";
  58. private SAXParserFactory pf;
  59. private boolean secureProcessing;
  60. /**
  61. * Default constructor.
  62. */
  63. public JAXPFactory()
  64. {
  65. }
  66. /**
  67. * Constructs a JAXP document builder which uses the default
  68. * JAXP SAX2 parser and the DOM implementation in this package.
  69. */
  70. public DocumentBuilder newDocumentBuilder()
  71. throws ParserConfigurationException
  72. {
  73. if (pf == null)
  74. {
  75. // Force use of AElfred2 since not all JAXP parsers
  76. // conform very well to the SAX2 API spec ...
  77. pf = new gnu.xml.aelfred2.JAXPFactory();
  78. // pf = SAXParserFactory.newInstance ();
  79. }
  80. // JAXP default: false
  81. pf.setValidating(isValidating());
  82. // FIXME: this namespace setup may cause errors in some
  83. // conformant SAX2 parsers, which we CAN patch up by
  84. // splicing a "NSFilter" stage up front ...
  85. // JAXP default: false
  86. pf.setNamespaceAware(isNamespaceAware());
  87. try
  88. {
  89. // undo rude "namespace-prefixes=false" default
  90. pf.setFeature(FEATURE + "namespace-prefixes", true);
  91. return new JAXPBuilder(pf.newSAXParser().getXMLReader(), this);
  92. }
  93. catch (SAXException e)
  94. {
  95. String msg = "can't create JAXP DocumentBuilder: " + e.getMessage();
  96. throw new ParserConfigurationException(msg);
  97. }
  98. }
  99. /** There seems to be no useful specification for attribute names */
  100. public void setAttribute(String name, Object value)
  101. throws IllegalArgumentException
  102. {
  103. if ("http://java.sun.com/xml/jaxp/properties/schemaLanguage".equals(name))
  104. {
  105. // TODO
  106. }
  107. else
  108. {
  109. throw new IllegalArgumentException(name);
  110. }
  111. }
  112. /** There seems to be no useful specification for attribute names */
  113. public Object getAttribute(String name)
  114. throws IllegalArgumentException
  115. {
  116. throw new IllegalArgumentException(name);
  117. }
  118. public void setFeature(String name, boolean value)
  119. throws ParserConfigurationException
  120. {
  121. if (name == null)
  122. throw new NullPointerException();
  123. if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(name))
  124. {
  125. secureProcessing = true;
  126. return;
  127. }
  128. throw new ParserConfigurationException(name);
  129. }
  130. public boolean getFeature(String name)
  131. throws ParserConfigurationException
  132. {
  133. if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(name))
  134. return secureProcessing;
  135. throw new ParserConfigurationException(name);
  136. }
  137. static final class JAXPBuilder
  138. extends DocumentBuilder
  139. implements ErrorHandler
  140. {
  141. private Consumer consumer;
  142. private XMLReader producer;
  143. private DomImpl impl;
  144. JAXPBuilder(XMLReader parser, JAXPFactory factory)
  145. throws ParserConfigurationException
  146. {
  147. impl = new DomImpl();
  148. // set up consumer side
  149. try
  150. {
  151. consumer = new Consumer();
  152. }
  153. catch (SAXException e)
  154. {
  155. throw new ParserConfigurationException(e.getMessage());
  156. }
  157. // JAXP defaults: true, noise nodes are good (bleech)
  158. consumer.setHidingReferences(factory.isExpandEntityReferences());
  159. consumer.setHidingComments(factory.isIgnoringComments());
  160. consumer.setHidingWhitespace(factory.isIgnoringElementContentWhitespace());
  161. consumer.setHidingCDATA(factory.isCoalescing());
  162. // set up producer side
  163. producer = parser;
  164. producer.setContentHandler(consumer.getContentHandler());
  165. producer.setDTDHandler(consumer.getDTDHandler());
  166. try
  167. {
  168. String id;
  169. // if validating, report validity errors, and default
  170. // to treating them as fatal
  171. if (factory.isValidating ())
  172. {
  173. producer.setFeature(FEATURE + "validation", true);
  174. producer.setErrorHandler(this);
  175. }
  176. // always save prefix info, maybe do namespace processing
  177. producer.setFeature(FEATURE + "namespace-prefixes", true);
  178. producer.setFeature(FEATURE + "namespaces",
  179. factory.isNamespaceAware());
  180. // set important handlers
  181. id = PROPERTY + "lexical-handler";
  182. producer.setProperty(id, consumer.getProperty(id));
  183. id = PROPERTY + "declaration-handler";
  184. producer.setProperty(id, consumer.getProperty(id));
  185. }
  186. catch (SAXException e)
  187. {
  188. throw new ParserConfigurationException(e.getMessage());
  189. }
  190. }
  191. public Document parse(InputSource source)
  192. throws SAXException, IOException
  193. {
  194. producer.parse(source);
  195. Document doc = consumer.getDocument();
  196. // TODO inputEncoding
  197. doc.setDocumentURI(source.getSystemId());
  198. return doc;
  199. }
  200. public boolean isNamespaceAware()
  201. {
  202. try
  203. {
  204. return producer.getFeature(FEATURE + "namespaces");
  205. }
  206. catch (SAXException e)
  207. {
  208. // "can't happen"
  209. throw new RuntimeException(e.getMessage());
  210. }
  211. }
  212. public boolean isValidating()
  213. {
  214. try
  215. {
  216. return producer.getFeature(FEATURE + "validation");
  217. }
  218. catch (SAXException e)
  219. {
  220. // "can't happen"
  221. throw new RuntimeException(e.getMessage());
  222. }
  223. }
  224. public void setEntityResolver(EntityResolver resolver)
  225. {
  226. producer.setEntityResolver(resolver);
  227. }
  228. public void setErrorHandler(ErrorHandler handler)
  229. {
  230. producer.setErrorHandler(handler);
  231. consumer.setErrorHandler(handler);
  232. }
  233. public DOMImplementation getDOMImplementation()
  234. {
  235. return impl;
  236. }
  237. public Document newDocument()
  238. {
  239. return new DomDocument();
  240. }
  241. // implementation of error handler that's used when validating
  242. public void fatalError(SAXParseException e)
  243. throws SAXException
  244. {
  245. throw e;
  246. }
  247. public void error(SAXParseException e)
  248. throws SAXException
  249. {
  250. throw e;
  251. }
  252. public void warning(SAXParseException e)
  253. throws SAXException
  254. {
  255. /* ignore */
  256. }
  257. }
  258. }