Coverage Report - org.apache.maven.doxia.docrenderer.itext.AbstractITextRender
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractITextRender
0%
0/162
0%
0/66
8,125
 
 1  
 package org.apache.maven.doxia.docrenderer.itext;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.io.File;
 23  
 import java.io.IOException;
 24  
 import java.io.Reader;
 25  
 import java.io.Writer;
 26  
 import java.net.URL;
 27  
 import java.net.URLClassLoader;
 28  
 import java.util.Collection;
 29  
 import java.util.Date;
 30  
 import java.util.Iterator;
 31  
 import java.util.LinkedList;
 32  
 import java.util.List;
 33  
 
 34  
 import javax.xml.parsers.DocumentBuilderFactory;
 35  
 import javax.xml.parsers.ParserConfigurationException;
 36  
 import javax.xml.transform.OutputKeys;
 37  
 import javax.xml.transform.Transformer;
 38  
 import javax.xml.transform.TransformerConfigurationException;
 39  
 import javax.xml.transform.TransformerException;
 40  
 import javax.xml.transform.TransformerFactory;
 41  
 import javax.xml.transform.dom.DOMSource;
 42  
 import javax.xml.transform.stream.StreamResult;
 43  
 import javax.xml.transform.stream.StreamSource;
 44  
 
 45  
 import org.apache.maven.doxia.Doxia;
 46  
 import org.apache.maven.doxia.docrenderer.DocRenderer;
 47  
 import org.apache.maven.doxia.docrenderer.DocumentRendererException;
 48  
 import org.apache.maven.doxia.document.DocumentModel;
 49  
 import org.apache.maven.doxia.document.DocumentTOCItem;
 50  
 import org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Reader;
 51  
 import org.apache.maven.doxia.module.itext.ITextSink;
 52  
 import org.apache.maven.doxia.module.itext.ITextSinkFactory;
 53  
 import org.apache.maven.doxia.module.itext.ITextUtil;
 54  
 import org.apache.maven.doxia.module.site.SiteModule;
 55  
 import org.apache.maven.doxia.module.site.manager.SiteModuleManager;
 56  
 import org.apache.maven.doxia.parser.ParseException;
 57  
 import org.apache.maven.doxia.parser.manager.ParserNotFoundException;
 58  
 import org.apache.xml.utils.DefaultErrorHandler;
 59  
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 60  
 import org.codehaus.plexus.util.FileUtils;
 61  
 import org.codehaus.plexus.util.IOUtil;
 62  
 import org.codehaus.plexus.util.ReaderFactory;
 63  
 import org.codehaus.plexus.util.StringUtils;
 64  
 import org.codehaus.plexus.util.WriterFactory;
 65  
 import org.codehaus.plexus.util.xml.XmlUtil;
 66  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 67  
 import org.w3c.dom.DOMException;
 68  
 import org.w3c.dom.Document;
 69  
 import org.w3c.dom.Node;
 70  
 import org.xml.sax.SAXException;
 71  
 
 72  
 import com.lowagie.text.ElementTags;
 73  
 
 74  
 /**
 75  
  * Abstract <code>document</code> render with the <code>iText</code> framework
 76  
  *
 77  
  * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 78  
  * @version $Id: AbstractITextRender.java 1185508 2011-10-18 06:58:50Z ltheussl $
 79  
  * @deprecated since 1.1, use an implementation of {@link org.apache.maven.doxia.docrenderer.DocumentRenderer}.
 80  
  */
 81  0
 public abstract class AbstractITextRender
 82  
     extends AbstractLogEnabled
 83  
     implements DocRenderer
 84  
 {
 85  
     private static final String XSLT_RESOURCE = "org/apache/maven/doxia/docrenderer/pdf/itext/TOC.xslt";
 86  
 
 87  0
     private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance();
 88  
 
 89  0
     private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
 90  
 
 91  
     /**
 92  
      * @plexus.requirement
 93  
      */
 94  
     protected SiteModuleManager siteModuleManager;
 95  
 
 96  
     /**
 97  
      * @plexus.requirement
 98  
      */
 99  
     protected Doxia doxia;
 100  
 
 101  
     static
 102  
     {
 103  0
         TRANSFORMER_FACTORY.setErrorListener( new DefaultErrorHandler() );
 104  0
     }
 105  
 
 106  
     /** {@inheritDoc} */
 107  
     public void render( File siteDirectory, File outputDirectory )
 108  
         throws DocumentRendererException, IOException
 109  
     {
 110  0
         Collection<SiteModule> modules = siteModuleManager.getSiteModules();
 111  0
         for ( SiteModule module : modules )
 112  
         {
 113  0
             File moduleBasedir = new File( siteDirectory, module.getSourceDirectory() );
 114  
 
 115  0
             if ( moduleBasedir.exists() )
 116  
             {
 117  
                 @SuppressWarnings ( "unchecked" )
 118  0
                 List<String> docs =
 119  
                     FileUtils.getFileNames( moduleBasedir, "**/*." + module.getExtension(), null, false );
 120  
 
 121  0
                 for ( String doc : docs )
 122  
                 {
 123  0
                     String fullPathDoc = new File( moduleBasedir, doc ).getPath();
 124  
 
 125  0
                     String outputITextName = doc.substring( 0, doc.indexOf( '.') + 1 ) + "xml";
 126  0
                     File outputITextFile = new File( outputDirectory, outputITextName );
 127  0
                     if ( !outputITextFile.getParentFile().exists() )
 128  
                     {
 129  0
                         outputITextFile.getParentFile().mkdirs();
 130  
                     }
 131  0
                     String iTextOutputName = doc.substring( 0, doc.indexOf( '.') + 1 ) + getOutputExtension();
 132  0
                     File iTextOutputFile = new File( outputDirectory, iTextOutputName );
 133  0
                     if ( !iTextOutputFile.getParentFile().exists() )
 134  
                     {
 135  0
                         iTextOutputFile.getParentFile().mkdirs();
 136  
                     }
 137  
 
 138  0
                     parse( fullPathDoc, module, outputITextFile );
 139  
 
 140  0
                     generateOutput( outputITextFile, iTextOutputFile );
 141  0
                 }
 142  
             }
 143  0
         }
 144  0
     }
 145  
 
 146  
     /** {@inheritDoc} */
 147  
     public void render( File siteDirectory, File outputDirectory, File documentDescriptor )
 148  
         throws DocumentRendererException, IOException
 149  
     {
 150  0
         if ( ( documentDescriptor == null ) || ( !documentDescriptor.exists() ) )
 151  
         {
 152  0
             if ( getLogger().isInfoEnabled() )
 153  
             {
 154  0
                 getLogger().info( "No documentDescriptor is found. Generate all documents." );
 155  
             }
 156  0
             render( siteDirectory, outputDirectory );
 157  0
             return;
 158  
         }
 159  
 
 160  
         DocumentModel documentModel;
 161  0
         Reader reader = null;
 162  
         try
 163  
         {
 164  0
             reader = ReaderFactory.newXmlReader( documentDescriptor );
 165  0
             documentModel = new DocumentXpp3Reader().read( reader );
 166  
         }
 167  0
         catch ( XmlPullParserException e )
 168  
         {
 169  0
             throw new DocumentRendererException( "Error parsing document descriptor", e );
 170  
         }
 171  0
         catch ( IOException e )
 172  
         {
 173  0
             throw new DocumentRendererException( "Error reading document descriptor", e );
 174  
         }
 175  
         finally
 176  
         {
 177  0
             IOUtil.close( reader );
 178  0
         }
 179  
 
 180  0
         if ( documentModel.getOutputName() == null )
 181  
         {
 182  0
             if ( getLogger().isInfoEnabled() )
 183  
             {
 184  0
                 getLogger().info( "No outputName is defined in the document descriptor. Using 'generated_itext'" );
 185  
             }
 186  0
             documentModel.setOutputName( "generated_itext" );
 187  
         }
 188  
 
 189  0
         if ( ( documentModel.getToc() == null ) || ( documentModel.getToc().getItems() == null ) )
 190  
         {
 191  0
             if ( getLogger().isInfoEnabled() )
 192  
             {
 193  0
                 getLogger().info( "No TOC is defined in the document descriptor. Merging all documents." );
 194  
             }
 195  
         }
 196  
 
 197  0
         List<File> iTextFiles = new LinkedList<File>();
 198  0
         Collection<SiteModule> modules = siteModuleManager.getSiteModules();
 199  0
         for ( SiteModule module : modules )
 200  
         {
 201  0
             File moduleBasedir = new File( siteDirectory, module.getSourceDirectory() );
 202  
 
 203  0
             if ( moduleBasedir.exists() )
 204  
             {
 205  
                 @SuppressWarnings ( "unchecked" )
 206  0
                 List<String> docs =
 207  
                     FileUtils.getFileNames( moduleBasedir, "**/*." + module.getExtension(), null, false );
 208  
 
 209  0
                 for ( String doc : docs )
 210  
                 {
 211  0
                     String fullPathDoc = new File( moduleBasedir, doc ).getPath();
 212  
 
 213  0
                     String outputITextName = doc.substring( 0, doc.lastIndexOf( '.') + 1 ) + "xml";
 214  0
                     File outputITextFile = new File( outputDirectory, outputITextName );
 215  
 
 216  0
                     if ( ( documentModel.getToc() == null ) || ( documentModel.getToc().getItems() == null ) )
 217  
                     {
 218  0
                         iTextFiles.add( outputITextFile );
 219  
 
 220  0
                         if ( !outputITextFile.getParentFile().exists() )
 221  
                         {
 222  0
                             outputITextFile.getParentFile().mkdirs();
 223  
                         }
 224  
 
 225  0
                         parse( fullPathDoc, module, outputITextFile );
 226  
                     }
 227  
                     else
 228  
                     {
 229  0
                         for ( Iterator<DocumentTOCItem> k = documentModel.getToc().getItems().iterator(); k.hasNext(); )
 230  
                         {
 231  0
                             DocumentTOCItem tocItem = k.next();
 232  
 
 233  0
                             if ( tocItem.getRef() == null )
 234  
                             {
 235  0
                                 if ( getLogger().isInfoEnabled() )
 236  
                                 {
 237  0
                                     getLogger().info( "No ref defined for an tocItem in the document descriptor." );
 238  
                                 }
 239  
                                 continue;
 240  
                             }
 241  
 
 242  0
                             String outTmp = StringUtils.replace( outputITextFile.getAbsolutePath(), "\\", "/" );
 243  0
                             outTmp = outTmp.substring( 0, outTmp.lastIndexOf( '.') );
 244  
 
 245  0
                             String outRef = StringUtils.replace( tocItem.getRef(), "\\", "/" );
 246  0
                             if ( outRef.lastIndexOf( '.') != -1 )
 247  
                             {
 248  0
                                 outRef = outRef.substring( 0, outRef.lastIndexOf( '.') );
 249  
                             }
 250  
                             else
 251  
                             {
 252  0
                                 outRef = outRef.substring( 0, outRef.length() );
 253  
                             }
 254  
 
 255  0
                             if ( outTmp.indexOf( outRef ) != -1 )
 256  
                             {
 257  0
                                 iTextFiles.add( outputITextFile );
 258  
 
 259  0
                                 if ( !outputITextFile.getParentFile().exists() )
 260  
                                 {
 261  0
                                     outputITextFile.getParentFile().mkdirs();
 262  
                                 }
 263  
 
 264  0
                                 parse( fullPathDoc, module, outputITextFile );
 265  
                             }
 266  0
                         }
 267  
                     }
 268  0
                 }
 269  
             }
 270  0
         }
 271  
 
 272  0
         File iTextFile = new File( outputDirectory, documentModel.getOutputName() + ".xml" );
 273  0
         File iTextOutput = new File( outputDirectory, documentModel.getOutputName() + "." + getOutputExtension() );
 274  0
         Document document = generateDocument( iTextFiles );
 275  0
         transform( documentModel, document, iTextFile );
 276  0
         generateOutput( iTextFile, iTextOutput );
 277  0
     }
 278  
 
 279  
     /**
 280  
      * Generate an ouput file with the iText framework
 281  
      *
 282  
      * @param iTextFile
 283  
      * @param iTextOutput
 284  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 285  
      * @throws java.io.IOException if any
 286  
      */
 287  
     public abstract void generateOutput( File iTextFile, File iTextOutput )
 288  
         throws DocumentRendererException, IOException;
 289  
 
 290  
     /**
 291  
      * Parse a sink
 292  
      *
 293  
      * @param fullPathDoc
 294  
      * @param module
 295  
      * @param outputITextFile
 296  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException
 297  
      * @throws java.io.IOException
 298  
      */
 299  
     private void parse( String fullPathDoc, SiteModule module, File outputITextFile )
 300  
         throws DocumentRendererException, IOException
 301  
     {
 302  0
         Writer writer = WriterFactory.newXmlWriter( outputITextFile );
 303  0
         ITextSink sink = (ITextSink) new ITextSinkFactory().createSink( writer );
 304  
 
 305  0
         sink.setClassLoader( new URLClassLoader( new URL[] { outputITextFile.getParentFile().toURI().toURL() } ) );
 306  
 
 307  0
         Reader reader = null;
 308  
         try
 309  
         {
 310  0
             File f = new File( fullPathDoc );
 311  0
             if ( XmlUtil.isXml( f ) )
 312  
             {
 313  0
                 reader = ReaderFactory.newXmlReader( f );
 314  
             }
 315  
             else
 316  
             {
 317  
                 // TODO Platform dependent?
 318  0
                 reader = ReaderFactory.newPlatformReader( f );
 319  
             }
 320  
 
 321  0
             System.setProperty( "itext.basedir", outputITextFile.getParentFile().getAbsolutePath() );
 322  
 
 323  0
             doxia.parse( reader, module.getParserId(), sink );
 324  
         }
 325  0
         catch ( ParserNotFoundException e )
 326  
         {
 327  0
             throw new DocumentRendererException( "Error getting a parser for '"
 328  
                     + fullPathDoc + "': " + e.getMessage() );
 329  
         }
 330  0
         catch ( ParseException e )
 331  
         {
 332  0
             throw new DocumentRendererException( "Error parsing '"
 333  
                     + fullPathDoc + "': line [" + e.getLineNumber() + "] " + e.getMessage(), e );
 334  
         }
 335  
         finally
 336  
         {
 337  0
             IOUtil.close( reader );
 338  
 
 339  0
             sink.flush();
 340  
 
 341  0
             sink.close();
 342  
 
 343  0
             IOUtil.close( writer );
 344  
 
 345  0
             System.getProperties().remove( "itext.basedir" );
 346  0
         }
 347  0
     }
 348  
 
 349  
     /**
 350  
      * Merge all iTextFiles to a single one
 351  
      *
 352  
      * @param iTextFiles
 353  
      * @return a document
 354  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 355  
      * @throws java.io.IOException if any
 356  
      */
 357  
     private Document generateDocument( List<File> iTextFiles )
 358  
         throws DocumentRendererException, IOException
 359  
     {
 360  
         Document document;
 361  
         try
 362  
         {
 363  0
             document = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder().newDocument();
 364  
         }
 365  0
         catch ( ParserConfigurationException e )
 366  
         {
 367  0
             throw new DocumentRendererException( "Error building document :" + e.getMessage() );
 368  0
         }
 369  0
         document.appendChild( document.createElement( ElementTags.ITEXT ) ); // Used only to set a root
 370  
 
 371  0
         for ( File iTextFile : iTextFiles )
 372  
         {
 373  
             Document iTextDocument;
 374  
             try
 375  
             {
 376  0
                 iTextDocument = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder().parse( iTextFile );
 377  
             }
 378  0
             catch ( SAXException e )
 379  
             {
 380  0
                 throw new DocumentRendererException( "SAX Error : " + e.getMessage() );
 381  
             }
 382  0
             catch ( ParserConfigurationException e )
 383  
             {
 384  0
                 throw new DocumentRendererException( "Error parsing configuration : " + e.getMessage() );
 385  0
             }
 386  
 
 387  
             // Only one chapter per doc
 388  0
             Node chapter = iTextDocument.getElementsByTagName( ElementTags.CHAPTER ).item( 0 );
 389  
             try
 390  
             {
 391  0
                 document.getDocumentElement().appendChild( document.importNode( chapter, true ) );
 392  
             }
 393  0
             catch ( DOMException e )
 394  
             {
 395  0
                 throw new DocumentRendererException( "Error appending chapter for "
 396  
                         + iTextFile + " : " + e.getMessage() );
 397  0
             }
 398  0
         }
 399  
 
 400  0
         return document;
 401  
     }
 402  
 
 403  
     /**
 404  
      * Init the transformer object
 405  
      *
 406  
      * @return an instanced transformer object
 407  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 408  
      */
 409  
     private Transformer initTransformer()
 410  
         throws DocumentRendererException
 411  
     {
 412  
         try
 413  
         {
 414  0
             Transformer transformer = TRANSFORMER_FACTORY.newTransformer( new StreamSource( DefaultPdfRenderer.class
 415  
                 .getResourceAsStream( "/" + XSLT_RESOURCE ) ) );
 416  0
             transformer.setErrorListener( TRANSFORMER_FACTORY.getErrorListener() );
 417  
 
 418  0
             transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "false" );
 419  0
             transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
 420  0
             transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
 421  0
             transformer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
 422  
 
 423  0
             return transformer;
 424  
         }
 425  0
         catch ( TransformerConfigurationException e )
 426  
         {
 427  0
             throw new DocumentRendererException( "Error configuring Transformer for " + XSLT_RESOURCE + ": "
 428  
                 + e.getMessage() );
 429  
         }
 430  0
         catch ( IllegalArgumentException e )
 431  
         {
 432  0
             throw new DocumentRendererException( "Error configuring Transformer for " + XSLT_RESOURCE + ": "
 433  
                 + e.getMessage() );
 434  
         }
 435  
     }
 436  
 
 437  
     /**
 438  
      * Add transformer parameters
 439  
      *
 440  
      * @param transformer
 441  
      * @param documentModel
 442  
      */
 443  
     private void addTransformerParameters( Transformer transformer, DocumentModel documentModel )
 444  
     {
 445  0
         if ( documentModel.getMeta().getTitle() != null )
 446  
         {
 447  0
             transformer.setParameter( "title", documentModel.getMeta().getTitle() );
 448  
         }
 449  0
         if ( documentModel.getMeta().getAuthor() != null )
 450  
         {
 451  0
             transformer.setParameter( "author", documentModel.getMeta().getAuthor() );
 452  
         }
 453  0
         transformer.setParameter( "creationdate", new Date().toString() );
 454  0
         if ( documentModel.getMeta().getSubject() != null )
 455  
         {
 456  0
             transformer.setParameter( "subject", documentModel.getMeta().getSubject() );
 457  
         }
 458  0
         if ( documentModel.getMeta().getKeywords() != null )
 459  
         {
 460  0
             transformer.setParameter( "keywords", documentModel.getMeta().getKeywords() );
 461  
         }
 462  0
         transformer.setParameter( "producer", "Generated with Doxia by " + System.getProperty( "user.name" ) );
 463  0
         if ( ITextUtil.isPageSizeSupported( documentModel.getMeta().getTitle() ) )
 464  
         {
 465  0
             transformer.setParameter( "pagesize", documentModel.getMeta().getPageSize() );
 466  
         }
 467  
         else
 468  
         {
 469  0
             transformer.setParameter( "pagesize", "A4" );
 470  
         }
 471  
 
 472  0
         transformer.setParameter( "frontPageHeader", "" );
 473  0
         if ( documentModel.getMeta().getTitle() != null )
 474  
         {
 475  0
             transformer.setParameter( "frontPageTitle", documentModel.getMeta().getTitle() );
 476  
         }
 477  0
         transformer.setParameter( "frontPageFooter", "Generated date " + new Date().toString() );
 478  0
     }
 479  
 
 480  
     /**
 481  
      * Transform a document to an iTextFile
 482  
      *
 483  
      * @param documentModel
 484  
      * @param document
 485  
      * @param iTextFile
 486  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any.
 487  
      */
 488  
     private void transform( DocumentModel documentModel, Document document, File iTextFile )
 489  
         throws DocumentRendererException
 490  
     {
 491  0
         Transformer transformer = initTransformer();
 492  
 
 493  0
         addTransformerParameters( transformer, documentModel );
 494  
 
 495  
         try
 496  
         {
 497  0
             transformer.transform( new DOMSource( document ), new StreamResult( iTextFile ) );
 498  
         }
 499  0
         catch ( TransformerException e )
 500  
         {
 501  0
             throw new DocumentRendererException( "Error transformer Document from "
 502  
                     + document + ": " + e.getMessage() );
 503  0
         }
 504  0
     }
 505  
 }