/*
* Copyright (C) 2008 Laurent Caillette
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.novelang.outfit.xml;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.TransformerException;
import com.google.common.collect.ImmutableList;
import static com.google.common.base.Preconditions.checkNotNull;
import org.novelang.logger.Logger;
import org.novelang.logger.LoggerFactory;
/**
* Logs all errors as they come and keeps them for rethrowing.
*
* @author Laurent Caillette
*/
public class TransformerErrorListener implements ErrorListener {
private final Logger logger ;
private final ImmutableList.Builder< Exception > exceptions = ImmutableList.builder() ;
public TransformerErrorListener() {
this( LoggerFactory.getLogger( TransformerErrorListener.class ) ) ;
}
public TransformerErrorListener( final Logger logger ) {
this.logger = checkNotNull( logger ) ;
}
@Override
public void warning( final TransformerException e ) throws TransformerException {
logger.warn( e.getMessageAndLocation() ) ;
addException( e ) ;
}
@Override
public void error( final TransformerException e ) throws TransformerException {
logger.error( e.getMessageAndLocation() ) ;
addException( e ) ;
}
@Override
public void fatalError( final TransformerException e ) throws TransformerException {
logger.error( "Fatal !!! ", e.getMessageAndLocation() ) ;
addException( e ) ;
}
/**
* Create safe {@code Exception} objects that don't suffer from {@code SourceLocator}
* state change that occurs after notification.
*/
@SuppressWarnings( { "ThrowableInstanceNeverThrown" } )
private void addException( final TransformerException original ) {
final TransformerException safeException ;
if( original.getLocator() == null ) {
safeException = new TransformerException(
original.getMessage(),
original.getCause()
) ;
} else {
safeException = new TransformerException(
original.getMessage(),
ImmutableSourceLocator.create( original.getLocator() ),
original.getCause()
) ;
}
safeException.setStackTrace( original.getStackTrace() ) ;
exceptions.add( safeException ) ;
}
public void flush() throws TransformerCompositeException {
final ImmutableList< Exception > list = exceptions.build() ;
if( ! list.isEmpty() ) {
throw new TransformerCompositeException(
"Problem" + ( list.size() > 1 ? "s" : "" ) + " hit when processing stylesheet", list ) ;
}
}
}