Coverage Report - org.apache.maven.doxia.docrenderer.AbstractDocumentRenderer
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractDocumentRenderer
57%
89/154
43%
31/72
3,227
 
 1  
 package org.apache.maven.doxia.docrenderer;
 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.BufferedReader;
 23  
 import java.io.File;
 24  
 import java.io.IOException;
 25  
 import java.io.Reader;
 26  
 import java.io.StringReader;
 27  
 import java.io.StringWriter;
 28  
 import java.util.Arrays;
 29  
 import java.util.Collection;
 30  
 import java.util.HashMap;
 31  
 import java.util.Iterator;
 32  
 import java.util.LinkedHashMap;
 33  
 import java.util.LinkedList;
 34  
 import java.util.List;
 35  
 import java.util.Locale;
 36  
 import java.util.Map;
 37  
 
 38  
 import org.apache.maven.doxia.Doxia;
 39  
 import org.apache.maven.doxia.document.DocumentModel;
 40  
 import org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Reader;
 41  
 import org.apache.maven.doxia.sink.Sink;
 42  
 import org.apache.maven.doxia.parser.ParseException;
 43  
 import org.apache.maven.doxia.parser.Parser;
 44  
 import org.apache.maven.doxia.parser.manager.ParserNotFoundException;
 45  
 import org.apache.maven.doxia.logging.PlexusLoggerWrapper;
 46  
 import org.apache.maven.doxia.module.site.SiteModule;
 47  
 import org.apache.maven.doxia.module.site.manager.SiteModuleManager;
 48  
 import org.apache.maven.doxia.util.XmlValidator;
 49  
 
 50  
 import org.apache.velocity.VelocityContext;
 51  
 import org.apache.velocity.context.Context;
 52  
 
 53  
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 54  
 
 55  
 import org.codehaus.plexus.util.DirectoryScanner;
 56  
 import org.codehaus.plexus.util.FileUtils;
 57  
 import org.codehaus.plexus.util.IOUtil;
 58  
 import org.codehaus.plexus.util.ReaderFactory;
 59  
 import org.codehaus.plexus.util.xml.XmlStreamReader;
 60  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 61  
 import org.codehaus.plexus.velocity.SiteResourceLoader;
 62  
 import org.codehaus.plexus.velocity.VelocityComponent;
 63  
 
 64  
 /**
 65  
  * Abstract <code>document</code> renderer.
 66  
  *
 67  
  * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 68  
  * @author ltheussl
 69  
  * @version $Id: AbstractDocumentRenderer.java 1185508 2011-10-18 06:58:50Z ltheussl $
 70  
  * @since 1.1
 71  
  */
 72  8
 public abstract class AbstractDocumentRenderer
 73  
     extends AbstractLogEnabled
 74  
     implements DocumentRenderer
 75  
 {
 76  
     /** @plexus.requirement */
 77  
     protected SiteModuleManager siteModuleManager;
 78  
 
 79  
     /** @plexus.requirement */
 80  
     protected Doxia doxia;
 81  
 
 82  
     /** @plexus.requirement */
 83  
     private VelocityComponent velocity;
 84  
 
 85  
     /**
 86  
      * The common base directory of source files.
 87  
      */
 88  
     private String baseDir;
 89  
 
 90  
       //--------------------------------------------
 91  
      //
 92  
     //--------------------------------------------
 93  
 
 94  
     /**
 95  
      * Render an aggregate document from the files found in a Map.
 96  
      *
 97  
      * @param filesToProcess the Map of Files to process. The Map should contain as keys the paths of the
 98  
      *      source files (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
 99  
      * @param outputDirectory the output directory where the aggregate document should be generated.
 100  
      * @param documentModel the document model, containing all the metadata, etc.
 101  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 102  
      * @throws java.io.IOException if any
 103  
      * @deprecated since 1.1.2, use {@link #render(Map, File, DocumentModel, DocumentRendererContext)}
 104  
      */
 105  
     public abstract void render( Map<String, SiteModule> filesToProcess, File outputDirectory,
 106  
                                  DocumentModel documentModel )
 107  
         throws DocumentRendererException, IOException;
 108  
 
 109  
       //--------------------------------------------
 110  
      //
 111  
     //--------------------------------------------
 112  
 
 113  
     /** {@inheritDoc} */
 114  
     public void render( Collection<String> files, File outputDirectory, DocumentModel documentModel )
 115  
         throws DocumentRendererException, IOException
 116  
     {
 117  0
         render( getFilesToProcess( files ), outputDirectory, documentModel, null );
 118  0
     }
 119  
 
 120  
     /** {@inheritDoc} */
 121  
     public void render( File baseDirectory, File outputDirectory, DocumentModel documentModel )
 122  
         throws DocumentRendererException, IOException
 123  
     {
 124  8
         render( baseDirectory, outputDirectory, documentModel, null );
 125  8
     }
 126  
 
 127  
     /**
 128  
      * Render an aggregate document from the files found in a Map.
 129  
      *
 130  
      * @param filesToProcess the Map of Files to process. The Map should contain as keys the paths of the
 131  
      *      source files (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
 132  
      * @param outputDirectory the output directory where the aggregate document should be generated.
 133  
      * @param documentModel the document model, containing all the metadata, etc.
 134  
      * @param context the rendering context when processing files.
 135  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 136  
      * @throws java.io.IOException if any
 137  
      */
 138  
     public void render( Map<String, SiteModule> filesToProcess, File outputDirectory, DocumentModel documentModel,
 139  
                         DocumentRendererContext context )
 140  
         throws DocumentRendererException, IOException
 141  
     {
 142  
         // nop
 143  0
     }
 144  
 
 145  
     /**
 146  
      * Render a document from the files found in a source directory, depending on a rendering context.
 147  
      *
 148  
      * @param baseDirectory the directory containing the source files.
 149  
      *              This should follow the standard Maven convention, ie containing all the site modules.
 150  
      * @param outputDirectory the output directory where the document should be generated.
 151  
      * @param documentModel the document model, containing all the metadata, etc.
 152  
      *              If the model contains a TOC, only the files found in this TOC are rendered,
 153  
      *              otherwise all files found under baseDirectory will be processed.
 154  
      *              If the model is null, render all files from baseDirectory individually.
 155  
      * @param context the rendering context when processing files.
 156  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 157  
      * @throws java.io.IOException if any
 158  
      * @since 1.1.2
 159  
      */
 160  
     public void render( File baseDirectory, File outputDirectory, DocumentModel documentModel,
 161  
                         DocumentRendererContext context )
 162  
         throws DocumentRendererException, IOException
 163  
     {
 164  8
         render( getFilesToProcess( baseDirectory ), outputDirectory, documentModel, context );
 165  8
     }
 166  
 
 167  
     /**
 168  
      * Render a document from the files found in baseDirectory. This just forwards to
 169  
      *              {@link #render(File,File,DocumentModel)} with a new DocumentModel.
 170  
      *
 171  
      * @param baseDirectory the directory containing the source files.
 172  
      *              This should follow the standard Maven convention, ie containing all the site modules.
 173  
      * @param outputDirectory the output directory where the document should be generated.
 174  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 175  
      * @throws java.io.IOException if any
 176  
      * @see #render(File, File, DocumentModel)
 177  
      */
 178  
     public void render( File baseDirectory, File outputDirectory )
 179  
         throws DocumentRendererException, IOException
 180  
     {
 181  0
         render( baseDirectory, outputDirectory, (DocumentModel) null );
 182  0
     }
 183  
 
 184  
     /**
 185  
      * Render a document from the files found in baseDirectory.
 186  
      *
 187  
      * @param baseDirectory the directory containing the source files.
 188  
      *              This should follow the standard Maven convention, ie containing all the site modules.
 189  
      * @param outputDirectory the output directory where the document should be generated.
 190  
      * @param documentDescriptor a file containing the document model.
 191  
      *              If this file does not exist or is null, some default settings will be used.
 192  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 193  
      * @throws java.io.IOException if any
 194  
      * @see #render(File, File) if documentDescriptor does not exist or is null
 195  
      * @see #render(Map, File, DocumentModel) otherwise
 196  
      */
 197  
     public void render( File baseDirectory, File outputDirectory, File documentDescriptor )
 198  
         throws DocumentRendererException, IOException
 199  
     {
 200  0
         if ( ( documentDescriptor == null ) || ( !documentDescriptor.exists() ) )
 201  
         {
 202  0
             getLogger().warn( "No documentDescriptor found: using default settings!" );
 203  
 
 204  0
             render( baseDirectory, outputDirectory );
 205  
         }
 206  
         else
 207  
         {
 208  0
             render( getFilesToProcess( baseDirectory ), outputDirectory, readDocumentModel( documentDescriptor ), null );
 209  
         }
 210  0
     }
 211  
 
 212  
     /**
 213  
      * Render documents separately for each file found in a Map.
 214  
      *
 215  
      * @param filesToProcess the Map of Files to process. The Map should contain as keys the paths of the
 216  
      *      source files (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
 217  
      * @param outputDirectory the output directory where the documents should be generated.
 218  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 219  
      * @throws java.io.IOException if any
 220  
      * @since 1.1.1
 221  
      * @deprecated since 1.1.2, use {@link #renderIndividual(Map, File, DocumentRendererContext)}
 222  
      */
 223  
     public void renderIndividual( Map<String, SiteModule> filesToProcess, File outputDirectory )
 224  
         throws DocumentRendererException, IOException
 225  
     {
 226  
         // nop
 227  0
     }
 228  
 
 229  
     /**
 230  
      * Render documents separately for each file found in a Map.
 231  
      *
 232  
      * @param filesToProcess the Map of Files to process. The Map should contain as keys the paths of the
 233  
      *      source files (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
 234  
      * @param outputDirectory the output directory where the documents should be generated.
 235  
      * @param context the rendering context.
 236  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 237  
      * @throws java.io.IOException if any
 238  
      * @since 1.1.2
 239  
      */
 240  
     public void renderIndividual( Map<String, SiteModule> filesToProcess, File outputDirectory,
 241  
                                   DocumentRendererContext context )
 242  
         throws DocumentRendererException, IOException
 243  
     {
 244  
         // nop
 245  0
     }
 246  
 
 247  
     /**
 248  
      * Returns a Map of files to process. The Map contains as keys the paths of the source files
 249  
      *      (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
 250  
      *
 251  
      * @param baseDirectory the directory containing the source files.
 252  
      *              This should follow the standard Maven convention, ie containing all the site modules.
 253  
      * @return a Map of files to process.
 254  
      * @throws java.io.IOException in case of a problem reading the files under baseDirectory.
 255  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
 256  
      */
 257  
     public Map<String, SiteModule> getFilesToProcess( File baseDirectory )
 258  
         throws IOException, DocumentRendererException
 259  
     {
 260  8
         if ( !baseDirectory.isDirectory() )
 261  
         {
 262  0
             getLogger().warn( "No files found to process!" );
 263  
 
 264  0
             return new HashMap<String, SiteModule>();
 265  
         }
 266  
 
 267  8
         setBaseDir( baseDirectory.getAbsolutePath() );
 268  
 
 269  8
         Map<String, SiteModule> filesToProcess = new LinkedHashMap<String, SiteModule>();
 270  8
         Map<String, String> duplicatesFiles = new LinkedHashMap<String, String>();
 271  
 
 272  8
         Collection<SiteModule> modules = siteModuleManager.getSiteModules();
 273  8
         for ( SiteModule module : modules )
 274  
         {
 275  32
             File moduleBasedir = new File( baseDirectory, module.getSourceDirectory() );
 276  
 
 277  32
             if ( moduleBasedir.exists() )
 278  
             {
 279  
                 // TODO: handle in/excludes
 280  
                 @SuppressWarnings ( "unchecked" )
 281  24
                 List<String> allFiles = FileUtils.getFileNames( moduleBasedir, "**/*.*", null, false );
 282  
 
 283  24
                 String lowerCaseExtension = module.getExtension().toLowerCase( Locale.ENGLISH );
 284  24
                 List<String> docs = new LinkedList<String>( allFiles );
 285  
                 // Take care of extension case
 286  24
                 for ( Iterator<String> it = docs.iterator(); it.hasNext(); )
 287  
                 {
 288  144
                     String name = it.next().trim();
 289  
 
 290  144
                     if ( !name.toLowerCase( Locale.ENGLISH ).endsWith( "." + lowerCaseExtension ) )
 291  
                     {
 292  96
                         it.remove();
 293  
                     }
 294  144
                 }
 295  
 
 296  24
                 List<String> velocityFiles = new LinkedList<String>( allFiles );
 297  
                 // *.xml.vm
 298  24
                 for ( Iterator<String> it = velocityFiles.iterator(); it.hasNext(); )
 299  
                 {
 300  144
                     String name = it.next().trim();
 301  
 
 302  144
                     if ( !name.toLowerCase( Locale.ENGLISH ).endsWith( lowerCaseExtension + ".vm" ) )
 303  
                     {
 304  144
                         it.remove();
 305  
                     }
 306  144
                 }
 307  24
                 docs.addAll( velocityFiles );
 308  
 
 309  24
                 for ( String filePath : docs )
 310  
                 {
 311  48
                     filePath = filePath.trim();
 312  
 
 313  48
                     if ( filePath.lastIndexOf( '.') > 0 )
 314  
                     {
 315  48
                         String key = filePath.substring( 0, filePath.lastIndexOf( '.') );
 316  
 
 317  48
                         if ( duplicatesFiles.containsKey( key ) )
 318  
                         {
 319  0
                             throw new DocumentRendererException( "Files '" + module.getSourceDirectory()
 320  
                                 + File.separator + filePath + "' clashes with existing '"
 321  
                                 + duplicatesFiles.get( key ) + "'." );
 322  
                         }
 323  
 
 324  48
                         duplicatesFiles.put( key, module.getSourceDirectory() + File.separator + filePath );
 325  
                     }
 326  
 
 327  48
                     filesToProcess.put( filePath, module );
 328  
                 }
 329  
             }
 330  32
         }
 331  
 
 332  8
         return filesToProcess;
 333  
     }
 334  
 
 335  
     /**
 336  
      * Returns a Map of files to process. The Map contains as keys the paths of the source files
 337  
      *      (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
 338  
      *
 339  
      * @param files The Collection of source files.
 340  
      * @return a Map of files to process.
 341  
      */
 342  
     public Map<String, SiteModule> getFilesToProcess( Collection<String> files )
 343  
     {
 344  
         // ----------------------------------------------------------------------
 345  
         // Map all the file names to parser ids
 346  
         // ----------------------------------------------------------------------
 347  
 
 348  0
         Map<String, SiteModule> filesToProcess = new HashMap<String, SiteModule>();
 349  
 
 350  0
         Collection<SiteModule> modules = siteModuleManager.getSiteModules();
 351  0
         for ( SiteModule siteModule : modules )
 352  
         {
 353  0
             String extension = "." + siteModule.getExtension();
 354  
 
 355  0
             String sourceDirectory = File.separator + siteModule.getSourceDirectory() + File.separator;
 356  
 
 357  0
             for ( String file : files )
 358  
             {
 359  
                 // first check if the file path contains one of the recognized source dir identifiers
 360  
                 // (there's trouble if a pathname contains 2 identifiers), then match file extensions (not unique).
 361  
 
 362  0
                 if ( file.indexOf( sourceDirectory ) != -1 )
 363  
                 {
 364  0
                     filesToProcess.put( file, siteModule );
 365  
                 }
 366  0
                 else if ( file.toLowerCase( Locale.ENGLISH ).endsWith( extension ) )
 367  
                 {
 368  
                     // don't overwrite if it's there already
 369  0
                     if ( !filesToProcess.containsKey( file ) )
 370  
                     {
 371  0
                         filesToProcess.put( file, siteModule );
 372  
                     }
 373  
                 }
 374  
             }
 375  0
         }
 376  
 
 377  0
         return filesToProcess;
 378  
     }
 379  
 
 380  
     /** {@inheritDoc} */
 381  
     public DocumentModel readDocumentModel( File documentDescriptor )
 382  
         throws DocumentRendererException, IOException
 383  
     {
 384  
         DocumentModel documentModel;
 385  
 
 386  4
         Reader reader = null;
 387  
         try
 388  
         {
 389  4
             reader = ReaderFactory.newXmlReader( documentDescriptor );
 390  4
             documentModel = new DocumentXpp3Reader().read( reader );
 391  
         }
 392  0
         catch ( XmlPullParserException e )
 393  
         {
 394  0
             throw new DocumentRendererException( "Error parsing document descriptor", e );
 395  
         }
 396  
         finally
 397  
         {
 398  4
             IOUtil.close( reader );
 399  4
         }
 400  
 
 401  4
         return documentModel;
 402  
     }
 403  
 
 404  
     /**
 405  
      * Sets the current base directory.
 406  
      *
 407  
      * @param newDir the absolute path to the base directory to set.
 408  
      */
 409  
     public void setBaseDir( String newDir )
 410  
     {
 411  8
         this.baseDir = newDir;
 412  8
     }
 413  
 
 414  
     /**
 415  
      * Return the current base directory.
 416  
      *
 417  
      * @return the current base directory.
 418  
      */
 419  
     public String getBaseDir()
 420  
     {
 421  136
         return this.baseDir;
 422  
     }
 423  
 
 424  
       //--------------------------------------------
 425  
      //
 426  
     //--------------------------------------------
 427  
 
 428  
     /**
 429  
      * Parse a source document into a sink.
 430  
      *
 431  
      * @param fullDocPath absolute path to the source document.
 432  
      * @param parserId determines the parser to use.
 433  
      * @param sink the sink to receive the events.
 434  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException in case of a parsing error.
 435  
      * @throws java.io.IOException if the source document cannot be opened.
 436  
      * @deprecated since 1.1.2, use {@link #parse(String, String, Sink, DocumentRendererContext)}
 437  
      */
 438  
     protected void parse( String fullDocPath, String parserId, Sink sink )
 439  
         throws DocumentRendererException, IOException
 440  
     {
 441  0
         parse( fullDocPath, parserId, sink, null );
 442  0
     }
 443  
 
 444  
     /**
 445  
      * Parse a source document into a sink.
 446  
      *
 447  
      * @param fullDocPath absolute path to the source document.
 448  
      * @param parserId determines the parser to use.
 449  
      * @param sink the sink to receive the events.
 450  
      * @param context the rendering context.
 451  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException in case of a parsing error.
 452  
      * @throws java.io.IOException if the source document cannot be opened.
 453  
      */
 454  
     protected void parse( String fullDocPath, String parserId, Sink sink, DocumentRendererContext context )
 455  
         throws DocumentRendererException, IOException
 456  
     {
 457  48
         if ( getLogger().isDebugEnabled() )
 458  
         {
 459  0
             getLogger().debug( "Parsing file " + fullDocPath );
 460  
         }
 461  
 
 462  48
         Reader reader = null;
 463  
         try
 464  
         {
 465  48
             File f = new File( fullDocPath );
 466  
 
 467  48
             Parser parser = doxia.getParser( parserId );
 468  48
             switch ( parser.getType() )
 469  
             {
 470  
                 case Parser.XML_TYPE:
 471  24
                     reader = ReaderFactory.newXmlReader( f );
 472  
 
 473  24
                     if ( isVelocityFile( f ) )
 474  
                     {
 475  0
                         reader = getVelocityReader( f, ( (XmlStreamReader) reader ).getEncoding(), context );
 476  
                     }
 477  24
                     if ( context != null && Boolean.TRUE.equals( (Boolean) context.get( "validate" ) ) )
 478  
                     {
 479  0
                         reader = validate( reader, fullDocPath );
 480  
                     }
 481  
                     break;
 482  
 
 483  
                 case Parser.TXT_TYPE:
 484  
                 case Parser.UNKNOWN_TYPE:
 485  
                 default:
 486  24
                     if ( isVelocityFile( f ) )
 487  
                     {
 488  0
                         reader =
 489  
                             getVelocityReader( f, ( context == null ? ReaderFactory.FILE_ENCODING
 490  
                                             : context.getInputEncoding() ), context );
 491  
                     }
 492  
                     else
 493  
                     {
 494  24
                         if ( context == null )
 495  
                         {
 496  24
                             reader = ReaderFactory.newPlatformReader( f );
 497  
                         }
 498  
                         else
 499  
                         {
 500  0
                             reader = ReaderFactory.newReader( f, context.getInputEncoding() );
 501  
                         }
 502  
                     }
 503  
             }
 504  
 
 505  48
             sink.enableLogging( new PlexusLoggerWrapper( getLogger() ) );
 506  
 
 507  48
             doxia.parse( reader, parserId, sink );
 508  
         }
 509  0
         catch ( ParserNotFoundException e )
 510  
         {
 511  0
             throw new DocumentRendererException( "No parser '" + parserId
 512  
                         + "' found for " + fullDocPath + ": " + e.getMessage(), e );
 513  
         }
 514  0
         catch ( ParseException e )
 515  
         {
 516  0
             throw new DocumentRendererException( "Error parsing " + fullDocPath + ": " + e.getMessage(), e );
 517  
         }
 518  
         finally
 519  
         {
 520  48
             IOUtil.close( reader );
 521  
 
 522  48
             sink.flush();
 523  48
         }
 524  48
     }
 525  
 
 526  
     /**
 527  
      * Copies the contents of the resource directory to an output folder.
 528  
      *
 529  
      * @param outputDirectory the destination folder.
 530  
      * @throws java.io.IOException if any.
 531  
      */
 532  
     protected void copyResources( File outputDirectory )
 533  
             throws IOException
 534  
     {
 535  8
         File resourcesDirectory = new File( getBaseDir(), "resources" );
 536  
 
 537  8
         if ( !resourcesDirectory.isDirectory() )
 538  
         {
 539  0
             return;
 540  
         }
 541  
 
 542  8
         if ( !outputDirectory.exists() )
 543  
         {
 544  0
             outputDirectory.mkdirs();
 545  
         }
 546  
 
 547  8
         copyDirectory( resourcesDirectory, outputDirectory );
 548  8
     }
 549  
 
 550  
     /**
 551  
      * Copy content of a directory, excluding scm-specific files.
 552  
      *
 553  
      * @param source directory that contains the files and sub-directories to be copied.
 554  
      * @param destination destination folder.
 555  
      * @throws java.io.IOException if any.
 556  
      */
 557  
     protected void copyDirectory( File source, File destination )
 558  
             throws IOException
 559  
     {
 560  8
         if ( source.isDirectory() && destination.isDirectory() )
 561  
         {
 562  8
             DirectoryScanner scanner = new DirectoryScanner();
 563  
 
 564  8
             String[] includedResources = {"**/**"};
 565  
 
 566  8
             scanner.setIncludes( includedResources );
 567  
 
 568  8
             scanner.addDefaultExcludes();
 569  
 
 570  8
             scanner.setBasedir( source );
 571  
 
 572  8
             scanner.scan();
 573  
 
 574  8
             List<String> includedFiles = Arrays.asList( scanner.getIncludedFiles() );
 575  
 
 576  8
             for ( String name : includedFiles )
 577  
             {
 578  40
                 File sourceFile = new File( source, name );
 579  
 
 580  40
                 File destinationFile = new File( destination, name );
 581  
 
 582  40
                 FileUtils.copyFile( sourceFile, destinationFile );
 583  40
             }
 584  
         }
 585  8
     }
 586  
 
 587  
     /**
 588  
      * @param documentModel not null
 589  
      * @return the output name defined in the documentModel without the output extension. If the output name is not
 590  
      * defined, return target by default.
 591  
      * @since 1.1.1
 592  
      * @see org.apache.maven.doxia.document.DocumentModel#getOutputName()
 593  
      * @see #getOutputExtension()
 594  
      */
 595  
     protected String getOutputName( DocumentModel documentModel )
 596  
     {
 597  4
         String outputName = documentModel.getOutputName();
 598  4
         if ( outputName == null )
 599  
         {
 600  0
             getLogger().info( "No outputName is defined in the document descriptor. Using 'target'" );
 601  
 
 602  0
             documentModel.setOutputName( "target" );
 603  
         }
 604  
 
 605  4
         outputName = outputName.trim();
 606  4
         if ( outputName.toLowerCase( Locale.ENGLISH ).endsWith( "." + getOutputExtension() ) )
 607  
         {
 608  0
             outputName =
 609  
                 outputName.substring( 0, outputName.toLowerCase( Locale.ENGLISH )
 610  
                                                    .lastIndexOf( "." + getOutputExtension() ) );
 611  
         }
 612  4
         documentModel.setOutputName( outputName );
 613  
 
 614  4
         return documentModel.getOutputName();
 615  
     }
 616  
 
 617  
     /**
 618  
      * TODO: DOXIA-111: we need a general filter here that knows how to alter the context
 619  
      *
 620  
      * @param f the file to process, not null
 621  
      * @param encoding the wanted encoding, not null
 622  
      * @param context the current render document context not null
 623  
      * @return a reader with
 624  
      * @throws DocumentRendererException
 625  
      */
 626  
     private Reader getVelocityReader( File f, String encoding, DocumentRendererContext context )
 627  
         throws DocumentRendererException
 628  
     {
 629  0
         if ( getLogger().isDebugEnabled() )
 630  
         {
 631  0
             getLogger().debug( "Velocity render for " + f.getAbsolutePath() );
 632  
         }
 633  
 
 634  0
         SiteResourceLoader.setResource( f.getAbsolutePath() );
 635  
 
 636  0
         Context velocityContext = new VelocityContext();
 637  
 
 638  0
         if ( context.getKeys() != null )
 639  
         {
 640  0
             for ( int i = 0; i < context.getKeys().length; i++ )
 641  
             {
 642  0
                 String key = (String) context.getKeys()[i];
 643  
 
 644  0
                 velocityContext.put( key, context.get( key ) );
 645  
             }
 646  
         }
 647  
 
 648  0
         StringWriter sw = new StringWriter();
 649  
         try
 650  
         {
 651  0
             velocity.getEngine().mergeTemplate( f.getAbsolutePath(), encoding, velocityContext, sw );
 652  
         }
 653  0
         catch ( Exception e )
 654  
         {
 655  0
             throw new DocumentRendererException( "Error whenn parsing Velocity file " + f.getAbsolutePath() + ": "
 656  
                 + e.getMessage(), e );
 657  0
         }
 658  
 
 659  0
         return new StringReader( sw.toString() );
 660  
     }
 661  
 
 662  
     /**
 663  
      * @param f not null
 664  
      * @return <code>true</code> if file has a vm extension, <code>false</false> otherwise.
 665  
      */
 666  
     private static boolean isVelocityFile( File f )
 667  
     {
 668  48
         return FileUtils.getExtension( f.getAbsolutePath() ).toLowerCase( Locale.ENGLISH ).endsWith( "vm" );
 669  
     }
 670  
 
 671  
     private Reader validate( Reader source, String resource )
 672  
             throws ParseException, IOException
 673  
     {
 674  0
         getLogger().debug( "Validating: " + resource );
 675  
 
 676  
         try
 677  
         {
 678  0
             String content = IOUtil.toString( new BufferedReader( source ) );
 679  
 
 680  0
             new XmlValidator( new PlexusLoggerWrapper( getLogger() ) ).validate( content );
 681  
 
 682  0
             return new StringReader( content );
 683  
         }
 684  
         finally
 685  
         {
 686  0
             IOUtil.close( source );
 687  
         }
 688  
     }
 689  
 }