001
002 /*
003 * Copyright (C) 2012 Archie L. Cobbs. All rights reserved.
004 *
005 * $Id: TransformErrorListener.java 226 2012-01-18 16:30:35Z archie.cobbs $
006 */
007
008 package org.dellroad.stuff.xml;
009
010 import javax.xml.transform.ErrorListener;
011 import javax.xml.transform.TransformerException;
012
013 import org.slf4j.Logger;
014
015 /**
016 * {@link ErrorListener} implementation that logs the messgaes to a configured {@link Logger}
017 * and throws exceptions in cases of errors and fatal errors.
018 *
019 * <p>
020 * This class also optionally works around some stupid Xalan-J bugs:
021 * <ul>
022 * <li>Throw exceptions in the case of {@link #warning} also; this is required because Xalan-J
023 * reports even <code><message terminate="yes"></code> messages as warnings</li>
024 * <li>When throwing exceptions, wrap them in {@link RuntimeException}s to avoid being swallowed;
025 * otherwise Xalan-J will not terminate on a <code><message terminate="yes"></code></li>
026 * </ul>
027 */
028 public class TransformErrorListener implements ErrorListener {
029
030 protected final Logger log;
031 protected final boolean xalanWorkarounds;
032
033 public TransformErrorListener(Logger log, boolean xalanWorkarounds) {
034 this.log = log;
035 this.xalanWorkarounds = xalanWorkarounds;
036 }
037
038 @Override
039 public void warning(TransformerException e) throws TransformerException {
040 this.log.warn(this.getLogMessageFor(e));
041 if (this.xalanWorkarounds)
042 this.rethrow(e);
043 }
044
045 @Override
046 public void error(TransformerException e) throws TransformerException {
047 this.log.error(this.getLogMessageFor(e));
048 this.rethrow(e);
049 }
050
051 @Override
052 public void fatalError(TransformerException e) throws TransformerException {
053 this.log.error(this.getLogMessageFor(e));
054 this.rethrow(e);
055 }
056
057 protected String getLogMessageFor(TransformerException e) {
058 return e.getMessageAndLocation();
059 }
060
061 protected void rethrow(TransformerException e) throws TransformerException {
062 if (!this.xalanWorkarounds)
063 throw e;
064 throw new RuntimeException("exception from XSL transform", e);
065 }
066 }
067