/*
* Copyright (C) 2011 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.rendering.multipage;
import java.io.OutputStream;
import java.nio.charset.Charset;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.TransformerHandler;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.output.NullOutputStream;
import org.xml.sax.ContentHandler;
import org.xml.sax.EntityResolver;
import static com.google.common.base.Preconditions.checkNotNull;
import org.novelang.common.SyntacticTree;
import org.novelang.common.metadata.DocumentMetadata;
import org.novelang.common.metadata.PageIdentifier;
import org.novelang.outfit.xml.SaxRecorder;
import org.novelang.outfit.xml.TransformerErrorListener;
import org.novelang.outfit.xml.XslTransformerFactory;
import org.novelang.rendering.GenericRenderer;
import org.novelang.rendering.RenditionMimeType;
import org.novelang.rendering.XmlWriter;
/**
* Computes the pages of a document tree, using
* previously-{@link XslMultipageStylesheetCapture captured}
* stylesheet.
*
* @author Laurent Caillette
*/
public class XslPageIdentifierExtractor implements PagesExtractor {
private final SaxRecorder.Player stylesheetPlayer;
private final EntityResolver entityResolver ;
private final URIResolver uriResolver ;
public XslPageIdentifierExtractor(
final EntityResolver entityResolver,
final URIResolver uriResolver,
final SaxRecorder.Player stylesheetPlayer
) {
this.entityResolver = checkNotNull( entityResolver ) ;
this.uriResolver = checkNotNull( uriResolver ) ;
this.stylesheetPlayer = stylesheetPlayer ;
}
@Override
public ImmutableMap<PageIdentifier, String > extractPages(
final SyntacticTree documentTree
)
throws Exception
{
if( stylesheetPlayer == null ) {
return PagesExtractor.EMPTY_MAP ;
}
final TransformerErrorListener transformerErrorListener = new TransformerErrorListener() ;
final XslTransformerFactory xslTransformerFactory = new XslTransformerFactory.FromPlayer(
stylesheetPlayer,
entityResolver,
uriResolver,
transformerErrorListener
) ;
transformerErrorListener.flush() ;
final TransformerHandler transformerHandler = xslTransformerFactory.newTransformerHandler() ;
transformerHandler.getTransformer().setErrorListener( transformerErrorListener ) ;
final XmlMultipageReader multipageReader = new XmlMultipageReader() ;
transformerHandler.setResult( new SAXResult( multipageReader ) );
final XmlWriter xmlWriter = new XmlWriter( RenditionMimeType.XML ) {
@Override
protected ContentHandler createContentHandler(
final OutputStream outputStream,
final DocumentMetadata documentMetadata,
final Charset charset
) throws Exception {
return transformerHandler ;
}
} ;
final GenericRenderer renderer = new GenericRenderer( xmlWriter ) ;
renderer.renderTree( documentTree, new NullOutputStream(), null, null, null ) ;
transformerErrorListener.flush() ;
return multipageReader.getPageIdentifiers() ;
}
}