1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 2001, 2002 The Apache Software Foundation.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xerces" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, International
  53. * Business Machines, Inc., http://www.apache.org. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package com.sun.org.apache.xerces.internal.util;
  58. import com.sun.org.apache.xerces.internal.xni.XNIException;
  59. import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
  60. import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
  61. import org.w3c.dom.Node;
  62. import org.w3c.dom.DOMError;
  63. import org.w3c.dom.DOMLocator;
  64. import org.w3c.dom.DOMErrorHandler;
  65. import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
  66. import com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl;
  67. import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
  68. import java.io.PrintWriter;
  69. import java.util.Hashtable;
  70. /**
  71. * This class handles DOM errors .
  72. *
  73. * @see DOMErrorHandler
  74. *
  75. * @author Gopal Sharma, SUN Microsystems Inc.
  76. * @version $Id: DOMErrorHandlerWrapper.java,v 1.12 2004/04/23 04:40:38 mrglavas Exp $
  77. */
  78. // REVISIT: current implementations wraps error several times:
  79. // XMLErrorReport.reportError creates XMLParserException (by wrapping all info)
  80. // and goes via switch to send errors.
  81. // DOMErrorHandlerWrapper catches calls, copies info from XMLParserException and
  82. // sends one call back to the application
  83. // I think we can avoid this indirection if we modify XMLErrorReporter. --el
  84. public class DOMErrorHandlerWrapper
  85. implements XMLErrorHandler, DOMErrorHandler {
  86. /** Map for converting internal error codes to DOM error types. **/
  87. private static Hashtable fgDOMErrorTypeTable;
  88. // It keeps the reference of DOMErrorHandler of application
  89. protected DOMErrorHandler fDomErrorHandler;
  90. // Error Status
  91. boolean eStatus = true ;
  92. // Print writer
  93. protected PrintWriter fOut;
  94. // some components may set error node
  95. // @see DOMNormalizer.
  96. public Node fCurrentNode;
  97. /** Error code for comparisons. **/
  98. protected final XMLErrorCode fErrorCode = new XMLErrorCode(null, null);
  99. protected final DOMErrorImpl fDOMError = new DOMErrorImpl();
  100. static {
  101. // initialize error type table: internal error codes (represented by domain and key) need to be mapped to a DOM error type.
  102. fgDOMErrorTypeTable = new Hashtable();
  103. fgDOMErrorTypeTable.put(new XMLErrorCode(XMLMessageFormatter.XML_DOMAIN, "DoctypeNotAllowed"), "doctype-not-allowed");
  104. fgDOMErrorTypeTable.put(new XMLErrorCode(XMLMessageFormatter.XML_DOMAIN, "ElementUnterminated"), "wf-invalid-character-in-node-name");
  105. fgDOMErrorTypeTable.put(new XMLErrorCode(XMLMessageFormatter.XML_DOMAIN, "EncodingDeclInvalid"), "unsupported-encoding");
  106. fgDOMErrorTypeTable.put(new XMLErrorCode(XMLMessageFormatter.XML_DOMAIN, "EqRequiredInAttribute"), "wf-invalid-character-in-node-name");
  107. fgDOMErrorTypeTable.put(new XMLErrorCode(XMLMessageFormatter.XML_DOMAIN, "LessthanInAttValue"), "wf-invalid-character");
  108. }
  109. //
  110. // Constructors
  111. //
  112. // Default constructor /
  113. public DOMErrorHandlerWrapper() {
  114. fOut = new PrintWriter(System.err);
  115. }
  116. public DOMErrorHandlerWrapper(DOMErrorHandler domErrorHandler) {
  117. fDomErrorHandler = domErrorHandler;
  118. } // DOMErrorHandlerWrapper(DOMErrorHandler domErrorHandler)
  119. //
  120. // Public methods
  121. //
  122. /** Sets the DOM error handler. */
  123. public void setErrorHandler(DOMErrorHandler errorHandler) {
  124. fDomErrorHandler = errorHandler;
  125. } // setErrorHandler(ErrorHandler)
  126. public DOMErrorHandler getErrorHandler(){
  127. return fDomErrorHandler;
  128. } //getErrorHandler()
  129. //
  130. // XMLErrorHandler methods
  131. //
  132. /**
  133. * Reports a warning. Warnings are non-fatal and can be safely ignored
  134. * by most applications.
  135. *
  136. * @param domain The domain of the warning. The domain can be any
  137. * string but is suggested to be a valid URI. The
  138. * domain can be used to conveniently specify a web
  139. * site location of the relevent specification or
  140. * document pertaining to this warning.
  141. * @param key The warning key. This key can be any string and
  142. * is implementation dependent.
  143. * @param exception Exception.
  144. *
  145. * @throws XNIException Thrown to signal that the parser should stop
  146. * parsing the document.
  147. */
  148. public void warning(String domain, String key,
  149. XMLParseException exception) throws XNIException {
  150. fDOMError.fSeverity = DOMError.SEVERITY_WARNING;
  151. fDOMError.fException = exception;
  152. fDOMError.fType = key;
  153. fDOMError.fRelatedData = fDOMError.fMessage = exception.getMessage();
  154. DOMLocatorImpl locator = fDOMError.fLocator;
  155. if (locator != null) {
  156. locator.fColumnNumber = exception.getColumnNumber();
  157. locator.fLineNumber = exception.getLineNumber();
  158. locator.fUri = exception.getExpandedSystemId();
  159. locator.fRelatedNode = fCurrentNode;
  160. }
  161. if (fDomErrorHandler != null) {
  162. fDomErrorHandler.handleError(fDOMError);
  163. }
  164. } // warning(String,String,XMLParseException)
  165. /**
  166. * Reports an error. Errors are non-fatal and usually signify that the
  167. * document is invalid with respect to its grammar(s).
  168. *
  169. * @param domain The domain of the error. The domain can be any
  170. * string but is suggested to be a valid URI. The
  171. * domain can be used to conveniently specify a web
  172. * site location of the relevent specification or
  173. * document pertaining to this error.
  174. * @param key The error key. This key can be any string and
  175. * is implementation dependent.
  176. * @param exception Exception.
  177. *
  178. * @throws XNIException Thrown to signal that the parser should stop
  179. * parsing the document.
  180. */
  181. public void error(String domain, String key,
  182. XMLParseException exception) throws XNIException {
  183. fDOMError.fSeverity = DOMError.SEVERITY_ERROR;
  184. fDOMError.fException = exception;
  185. fDOMError.fType = key;
  186. fDOMError.fRelatedData = fDOMError.fMessage = exception.getMessage();
  187. DOMLocatorImpl locator = fDOMError.fLocator;
  188. if (locator != null) {
  189. locator.fColumnNumber = exception.getColumnNumber();
  190. locator.fLineNumber = exception.getLineNumber();
  191. locator.fUri = exception.getExpandedSystemId();
  192. locator.fRelatedNode= fCurrentNode;
  193. }
  194. if (fDomErrorHandler != null) {
  195. fDomErrorHandler.handleError(fDOMError);
  196. }
  197. } // error(String,String,XMLParseException)
  198. /**
  199. * Report a fatal error. Fatal errors usually occur when the document
  200. * is not well-formed and signifies that the parser cannot continue
  201. * normal operation.
  202. * <p>
  203. * <strong>Note:</strong> The error handler should <em>always</em>
  204. * throw an <code>XNIException</code> from this method. This exception
  205. * can either be the same exception that is passed as a parameter to
  206. * the method or a new XNI exception object. If the registered error
  207. * handler fails to throw an exception, the continuing operation of
  208. * the parser is undetermined.
  209. *
  210. * @param domain The domain of the fatal error. The domain can be
  211. * any string but is suggested to be a valid URI. The
  212. * domain can be used to conveniently specify a web
  213. * site location of the relevent specification or
  214. * document pertaining to this fatal error.
  215. * @param key The fatal error key. This key can be any string
  216. * and is implementation dependent.
  217. * @param exception Exception.
  218. *
  219. * @throws XNIException Thrown to signal that the parser should stop
  220. * parsing the document.
  221. */
  222. public void fatalError(String domain, String key,
  223. XMLParseException exception) throws XNIException {
  224. fDOMError.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
  225. fDOMError.fException = exception;
  226. fErrorCode.setValues(domain, key);
  227. String domErrorType = (String) fgDOMErrorTypeTable.get(fErrorCode);
  228. fDOMError.fType = (domErrorType != null) ? domErrorType : key;
  229. fDOMError.fRelatedData = fDOMError.fMessage = exception.getMessage();
  230. DOMLocatorImpl locator = fDOMError.fLocator;
  231. if (locator != null) {
  232. locator.fColumnNumber = exception.getColumnNumber();
  233. locator.fLineNumber = exception.getLineNumber();
  234. locator.fUri = exception.getExpandedSystemId();
  235. locator.fRelatedNode = fCurrentNode;
  236. }
  237. if (fDomErrorHandler != null) {
  238. fDomErrorHandler.handleError(fDOMError);
  239. }
  240. } // fatalError(String,String,XMLParseException)
  241. public boolean handleError(DOMError error) {
  242. printError(error);
  243. return eStatus;
  244. }
  245. /** Prints the error message. */
  246. private void printError(DOMError error) {
  247. int severity = error.getSeverity();
  248. fOut.print("[");
  249. if ( severity == DOMError.SEVERITY_WARNING) {
  250. fOut.print("Warning");
  251. } else if ( severity == DOMError.SEVERITY_ERROR) {
  252. fOut.print("Error");
  253. } else {
  254. fOut.print("FatalError");
  255. eStatus = false ; //REVISIT: Abort processing if fatal error, do we need to??
  256. }
  257. fOut.print("] ");
  258. DOMLocator locator = error.getLocation();
  259. if (locator != null) {
  260. fOut.print(locator.getLineNumber());
  261. fOut.print(":");
  262. fOut.print(locator.getColumnNumber());
  263. fOut.print(":");
  264. fOut.print(locator.getByteOffset());
  265. fOut.print(",");
  266. fOut.print(locator.getUtf16Offset());
  267. Node node = locator.getRelatedNode();
  268. if (node != null) {
  269. fOut.print("[");
  270. fOut.print(node.getNodeName());
  271. fOut.print("]");
  272. }
  273. String systemId = locator.getUri();
  274. if (systemId != null) {
  275. int index = systemId.lastIndexOf('/');
  276. if (index != -1)
  277. systemId = systemId.substring(index + 1);
  278. fOut.print(": ");
  279. fOut.print(systemId);
  280. }
  281. }
  282. fOut.print(":");
  283. fOut.print(error.getMessage());
  284. fOut.println();
  285. fOut.flush();
  286. } // printError(DOMError)
  287. } // class DOMErrorHandlerWrapper