View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.common.xsl;
20  
21  import javax.xml.transform.ErrorListener;
22  import javax.xml.transform.SourceLocator;
23  import javax.xml.transform.TransformerException;
24  
25  import org.apache.logging.log4j.LogManager;
26  import org.apache.logging.log4j.Logger;
27  import org.apache.xml.utils.WrappedRuntimeException;
28  
29  /**
30   * @author Thomas Scheffler (yagee)
31   *
32   */
33  public class MCRErrorListener implements ErrorListener {
34      private static Logger LOGGER = LogManager.getLogger(MCRErrorListener.class);
35  
36      private TransformerException exceptionThrown;
37  
38      private String lastMessage;
39  
40      public static MCRErrorListener getInstance() {
41          return new MCRErrorListener();
42      }
43  
44      private MCRErrorListener() {
45          this.exceptionThrown = null;
46      }
47  
48      public TransformerException getExceptionThrown() {
49          return exceptionThrown;
50      }
51  
52      private boolean triggerException(TransformerException e) {
53          if (exceptionThrown != null) {
54              return false;
55          } else {
56              exceptionThrown = e;
57              return true;
58          }
59      }
60  
61      /* (non-Javadoc)
62       * @see javax.xml.transform.ErrorListener#warning(javax.xml.transform.TransformerException)
63       */
64      @Override
65      public void warning(TransformerException exception) throws TransformerException {
66          exception = unwrapException(exception);
67          StackTraceElement[] stackTrace = exception.getStackTrace();
68          if (stackTrace.length > 0 && stackTrace[0].getMethodName().equals("message")) {
69              //org.apache.xalan.transformer.MsgMgr.message to print a message
70              String messageAndLocation = getMyMessageAndLocation(exception);
71              this.lastMessage = messageAndLocation;
72              LOGGER.info(messageAndLocation);
73          } else {
74              LOGGER.warn("Exception while XSL transformation:{}", exception.getMessageAndLocation());
75          }
76      }
77  
78      /* (non-Javadoc)
79       * @see javax.xml.transform.ErrorListener#error(javax.xml.transform.TransformerException)
80       */
81      @Override
82      public void error(TransformerException exception) throws TransformerException {
83          exception = unwrapException(exception);
84          if (triggerException(exception)) {
85              LOGGER.error("Exception while XSL transformation:{}", exception.getMessageAndLocation());
86          }
87          throw exception;
88      }
89  
90      /* (non-Javadoc)
91       * @see javax.xml.transform.ErrorListener#fatalError(javax.xml.transform.TransformerException)
92       */
93      @Override
94      public void fatalError(TransformerException exception) throws TransformerException {
95          exception = unwrapException(exception);
96          StackTraceElement[] stackTrace = exception.getStackTrace();
97          if (stackTrace.length > 0 && stackTrace[0].getMethodName().equals("execute")
98              && stackTrace[0].getClassName().endsWith("ElemMessage")) {
99              LOGGER.debug("Original exception: ", exception);
100             exception = new TransformerException(lastMessage);
101         }
102         if (triggerException(exception)) {
103             LOGGER.fatal("Exception while XSL transformation.", exception);
104         }
105         throw exception;
106     }
107 
108     public static TransformerException unwrapException(TransformerException exception) {
109         Throwable cause = exception.getCause();
110         while (cause != null) {
111             if (cause instanceof TransformerException) {
112                 return unwrapException((TransformerException) cause);
113             }
114             if (cause instanceof WrappedRuntimeException) {
115                 cause = ((WrappedRuntimeException) cause).getException();
116             } else {
117                 cause = cause.getCause();
118             }
119         }
120         return exception;
121     }
122 
123     public static String getMyMessageAndLocation(TransformerException exception) {
124         SourceLocator locator = exception.getLocator();
125         StringBuilder msg = new StringBuilder();
126         if (locator != null) {
127             String systemID = locator.getSystemId();
128             int line = locator.getLineNumber();
129             int col = locator.getColumnNumber();
130             if (systemID != null) {
131                 msg.append("SystemID: ");
132                 msg.append(systemID);
133             }
134             if (line != 0) {
135                 msg.append(" [");
136                 msg.append(line);
137                 if (col != 0) {
138                     msg.append(',');
139                     msg.append(col);
140                 }
141                 msg.append("]");
142             }
143         }
144         msg.append(": ");
145         msg.append(exception.getMessage());
146         return msg.toString();
147     }
148 }