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>&lt;message terminate="yes"&gt;</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>&lt;message terminate="yes"&gt;</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