1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * Licensed to the Apache Software Foundation (ASF) under one or more
7  * contributor license agreements.  See the NOTICE file distributed with
8  * this work for additional information regarding copyright ownership.
9  * The ASF licenses this file to You under the Apache License, Version 2.0
10  * (the "License"); you may not use this file except in compliance with
11  * the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 package com.sun.org.apache.xml.internal.utils;
23 
24 import java.io.PrintStream;
25 import java.io.PrintWriter;
26 
27 import javax.xml.transform.ErrorListener;
28 import javax.xml.transform.SourceLocator;
29 import javax.xml.transform.TransformerException;
30 
31 import com.sun.org.apache.xml.internal.res.XMLErrorResources;
32 import com.sun.org.apache.xml.internal.res.XMLMessages;
33 
34 import org.xml.sax.ErrorHandler;
35 import org.xml.sax.SAXException;
36 import org.xml.sax.SAXParseException;
37 
38 
39 /**
40  * Implement SAX error handler for default reporting.
41  * @xsl.usage general
42  */
43 public class DefaultErrorHandler implements ErrorHandler, ErrorListener
44 {
45   PrintWriter m_pw;
46 
47   /**
48    * if this flag is set to true, we will rethrow the exception on
49    * the error() and fatalError() methods. If it is false, the errors
50    * are reported to System.err.
51    */
52   boolean m_throwExceptionOnError = true;
53 
54   /**
55    * Constructor DefaultErrorHandler
56    */
DefaultErrorHandler(PrintWriter pw)57   public DefaultErrorHandler(PrintWriter pw)
58   {
59     m_pw = pw;
60   }
61 
62   /**
63    * Constructor DefaultErrorHandler
64    */
DefaultErrorHandler(PrintStream pw)65   public DefaultErrorHandler(PrintStream pw)
66   {
67     m_pw = new PrintWriter(pw, true);
68   }
69 
70   /**
71    * Constructor DefaultErrorHandler
72    */
DefaultErrorHandler()73   public DefaultErrorHandler()
74   {
75     this(true);
76   }
77 
78   /**
79    * Constructor DefaultErrorHandler
80    */
DefaultErrorHandler(boolean throwExceptionOnError)81   public DefaultErrorHandler(boolean throwExceptionOnError)
82   {
83     m_pw = new PrintWriter(System.err, true);
84     m_throwExceptionOnError = throwExceptionOnError;
85   }
86 
87 
88   /**
89    * Receive notification of a warning.
90    *
91    * <p>SAX parsers will use this method to report conditions that
92    * are not errors or fatal errors as defined by the XML 1.0
93    * recommendation.  The default behaviour is to take no action.</p>
94    *
95    * <p>The SAX parser must continue to provide normal parsing events
96    * after invoking this method: it should still be possible for the
97    * application to process the document through to the end.</p>
98    *
99    * @param exception The warning information encapsulated in a
100    *                  SAX parse exception.
101    * @throws SAXException Any SAX exception, possibly
102    *            wrapping another exception.
103    */
warning(SAXParseException exception)104   public void warning(SAXParseException exception) throws SAXException
105   {
106     printLocation(m_pw, exception);
107     m_pw.println("Parser warning: " + exception.getMessage());
108   }
109 
110   /**
111    * Receive notification of a recoverable error.
112    *
113    * <p>This corresponds to the definition of "error" in section 1.2
114    * of the W3C XML 1.0 Recommendation.  For example, a validating
115    * parser would use this callback to report the violation of a
116    * validity constraint.  The default behaviour is to take no
117    * action.</p>
118    *
119    * <p>The SAX parser must continue to provide normal parsing events
120    * after invoking this method: it should still be possible for the
121    * application to process the document through to the end.  If the
122    * application cannot do so, then the parser should report a fatal
123    * error even if the XML 1.0 recommendation does not require it to
124    * do so.</p>
125    *
126    * @param exception The error information encapsulated in a
127    *                  SAX parse exception.
128    * @throws SAXException Any SAX exception, possibly
129    *            wrapping another exception.
130    */
error(SAXParseException exception)131   public void error(SAXParseException exception) throws SAXException
132   {
133     //printLocation(exception);
134     // m_pw.println(exception.getMessage());
135 
136     throw exception;
137   }
138 
139   /**
140    * Receive notification of a non-recoverable error.
141    *
142    * <p>This corresponds to the definition of "fatal error" in
143    * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
144    * parser would use this callback to report the violation of a
145    * well-formedness constraint.</p>
146    *
147    * <p>The application must assume that the document is unusable
148    * after the parser has invoked this method, and should continue
149    * (if at all) only for the sake of collecting addition error
150    * messages: in fact, SAX parsers are free to stop reporting any
151    * other events once this method has been invoked.</p>
152    *
153    * @param exception The error information encapsulated in a
154    *                  SAX parse exception.
155    * @throws SAXException Any SAX exception, possibly
156    *            wrapping another exception.
157    */
fatalError(SAXParseException exception)158   public void fatalError(SAXParseException exception) throws SAXException
159   {
160     // printLocation(exception);
161     // m_pw.println(exception.getMessage());
162 
163     throw exception;
164   }
165 
166   /**
167    * Receive notification of a warning.
168    *
169    * <p>SAX parsers will use this method to report conditions that
170    * are not errors or fatal errors as defined by the XML 1.0
171    * recommendation.  The default behaviour is to take no action.</p>
172    *
173    * <p>The SAX parser must continue to provide normal parsing events
174    * after invoking this method: it should still be possible for the
175    * application to process the document through to the end.</p>
176    *
177    * @param exception The warning information encapsulated in a
178    *                  SAX parse exception.
179    * @throws javax.xml.transform.TransformerException Any SAX exception, possibly
180    *            wrapping another exception.
181    * @see javax.xml.transform.TransformerException
182    */
warning(TransformerException exception)183   public void warning(TransformerException exception) throws TransformerException
184   {
185     printLocation(m_pw, exception);
186 
187     m_pw.println(exception.getMessage());
188   }
189 
190   /**
191    * Receive notification of a recoverable error.
192    *
193    * <p>This corresponds to the definition of "error" in section 1.2
194    * of the W3C XML 1.0 Recommendation.  For example, a validating
195    * parser would use this callback to report the violation of a
196    * validity constraint.  The default behaviour is to take no
197    * action.</p>
198    *
199    * <p>The SAX parser must continue to provide normal parsing events
200    * after invoking this method: it should still be possible for the
201    * application to process the document through to the end.  If the
202    * application cannot do so, then the parser should report a fatal
203    * error even if the XML 1.0 recommendation does not require it to
204    * do so.</p>
205    *
206    * @param exception The error information encapsulated in a
207    *                  SAX parse exception.
208    * @throws javax.xml.transform.TransformerException Any SAX exception, possibly
209    *            wrapping another exception.
210    * @see javax.xml.transform.TransformerException
211    */
error(TransformerException exception)212   public void error(TransformerException exception) throws TransformerException
213   {
214     // If the m_throwExceptionOnError flag is true, rethrow the exception.
215     // Otherwise report the error to System.err.
216     if (m_throwExceptionOnError)
217       throw exception;
218     else
219     {
220       printLocation(m_pw, exception);
221       m_pw.println(exception.getMessage());
222     }
223   }
224 
225   /**
226    * Receive notification of a non-recoverable error.
227    *
228    * <p>This corresponds to the definition of "fatal error" in
229    * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
230    * parser would use this callback to report the violation of a
231    * well-formedness constraint.</p>
232    *
233    * <p>The application must assume that the document is unusable
234    * after the parser has invoked this method, and should continue
235    * (if at all) only for the sake of collecting addition error
236    * messages: in fact, SAX parsers are free to stop reporting any
237    * other events once this method has been invoked.</p>
238    *
239    * @param exception The error information encapsulated in a
240    *                  SAX parse exception.
241    * @throws javax.xml.transform.TransformerException Any SAX exception, possibly
242    *            wrapping another exception.
243    * @see javax.xml.transform.TransformerException
244    */
fatalError(TransformerException exception)245   public void fatalError(TransformerException exception) throws TransformerException
246   {
247     // If the m_throwExceptionOnError flag is true, rethrow the exception.
248     // Otherwise report the error to System.err.
249     if (m_throwExceptionOnError)
250       throw exception;
251     else
252     {
253       printLocation(m_pw, exception);
254       m_pw.println(exception.getMessage());
255     }
256   }
257 
ensureLocationSet(TransformerException exception)258   public static void ensureLocationSet(TransformerException exception)
259   {
260     // SourceLocator locator = exception.getLocator();
261     SourceLocator locator = null;
262     Throwable cause = exception;
263 
264     // Try to find the locator closest to the cause.
265     do
266     {
267       if(cause instanceof SAXParseException)
268       {
269         locator = new SAXSourceLocator((SAXParseException)cause);
270       }
271       else if (cause instanceof TransformerException)
272       {
273         SourceLocator causeLocator = ((TransformerException)cause).getLocator();
274         if(null != causeLocator)
275           locator = causeLocator;
276       }
277 
278       if(cause instanceof TransformerException)
279         cause = ((TransformerException)cause).getCause();
280       else if(cause instanceof SAXException)
281         cause = ((SAXException)cause).getException();
282       else
283         cause = null;
284     }
285     while(null != cause);
286 
287     exception.setLocator(locator);
288   }
289 
printLocation(PrintStream pw, TransformerException exception)290   public static void printLocation(PrintStream pw, TransformerException exception)
291   {
292     printLocation(new PrintWriter(pw), exception);
293   }
294 
printLocation(java.io.PrintStream pw, org.xml.sax.SAXParseException exception)295   public static void printLocation(java.io.PrintStream pw, org.xml.sax.SAXParseException exception)
296   {
297     printLocation(new PrintWriter(pw), exception);
298   }
299 
printLocation(PrintWriter pw, Throwable exception)300   public static void printLocation(PrintWriter pw, Throwable exception)
301   {
302     SourceLocator locator = null;
303     Throwable cause = exception;
304 
305     // Try to find the locator closest to the cause.
306     do
307     {
308       if(cause instanceof SAXParseException)
309       {
310         locator = new SAXSourceLocator((SAXParseException)cause);
311       }
312       else if (cause instanceof TransformerException)
313       {
314         SourceLocator causeLocator = ((TransformerException)cause).getLocator();
315         if(null != causeLocator)
316           locator = causeLocator;
317       }
318       if(cause instanceof TransformerException)
319         cause = ((TransformerException)cause).getCause();
320       else if(cause instanceof WrappedRuntimeException)
321         cause = ((WrappedRuntimeException)cause).getException();
322       else if(cause instanceof SAXException)
323         cause = ((SAXException)cause).getException();
324       else
325         cause = null;
326     }
327     while(null != cause);
328 
329     if(null != locator)
330     {
331       // m_pw.println("Parser fatal error: "+exception.getMessage());
332       String id = (null != locator.getPublicId() )
333                   ? locator.getPublicId()
334                     : (null != locator.getSystemId())
335                       ? locator.getSystemId() : XMLMessages.createXMLMessage(XMLErrorResources.ER_SYSTEMID_UNKNOWN, null); //"SystemId Unknown";
336 
337       pw.print(id + "; " +XMLMessages.createXMLMessage("line", null) + locator.getLineNumber()
338                          + "; " +XMLMessages.createXMLMessage("column", null) + locator.getColumnNumber()+"; ");
339     }
340     else
341       pw.print("("+XMLMessages.createXMLMessage(XMLErrorResources.ER_LOCATION_UNKNOWN, null)+")");
342   }
343 }
344