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 1087124 2011-03-30 22:45:41Z hboutemy $
 70  
  * @since 1.1
 71  
  */
 72  24
 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  24
         render( baseDirectory, outputDirectory, documentModel, null );
 125  24
     }
 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  24
         render( getFilesToProcess( baseDirectory ), outputDirectory, documentModel, context );
 165  24
     }
 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  24
         if ( !baseDirectory.isDirectory() )
 261  
         {
 262  0
             getLogger().warn( "No files found to process!" );
 263  
 
 264  0
             return new HashMap<String, SiteModule>();
 265  
         }
 266  
 
 267  24
         setBaseDir( baseDirectory.getAbsolutePath() );
 268  
 
 269  24
         Map<String, SiteModule> filesToProcess = new LinkedHashMap<String, SiteModule>();
 270  24
         Map<String, String> duplicatesFiles = new LinkedHashMap<String, String>();
 271  
 
 272  24
         Collection<SiteModule> modules = siteModuleManager.getSiteModules();
 273  24
         for ( SiteModule module : modules )
 274  
         {
 275  96
             File moduleBasedir = new File( baseDirectory, module.getSourceDirectory() );
 276  
 
 277  96
             if ( moduleBasedir.exists() )
 278  
             {
 279  
                 // TODO: handle in/excludes
 280  72
                 List<String> allFiles = FileUtils.getFileNames( moduleBasedir, "**/*.*", null, false );
 281  
 
 282  72
                 String lowerCaseExtension = module.getExtension().toLowerCase( Locale.ENGLISH );
 283  72
                 List<String> docs = new LinkedList<String>( allFiles );
 284  
                 // Take care of extension case
 285  72
                 for ( Iterator<String> it = docs.iterator(); it.hasNext(); )
 286  
                 {
 287  432
                     String name = it.next().trim();
 288  
 
 289  432
                     if ( !name.toLowerCase( Locale.ENGLISH ).endsWith( "." + lowerCaseExtension ) )
 290  
                     {
 291  288
                         it.remove();
 292  
                     }
 293  432
                 }
 294  
 
 295  72
                 List<String> velocityFiles = new LinkedList<String>( allFiles );
 296  
                 // *.xml.vm
 297  72
                 for ( Iterator<String> it = velocityFiles.iterator(); it.hasNext(); )
 298  
                 {
 299  432
                     String name = it.next().trim();
 300  
 
 301  432
                     if ( !name.toLowerCase( Locale.ENGLISH ).endsWith( lowerCaseExtension + ".vm" ) )
 302  
                     {
 303  432
                         it.remove();
 304  
                     }
 305  432
                 }
 306  72
                 docs.addAll( velocityFiles );
 307  
 
 308  72
                 for ( String filePath : docs )
 309  
                 {
 310  144
                     filePath = filePath.trim();
 311  
 
 312  144
                     if ( filePath.lastIndexOf( "." ) > 0 )
 313  
                     {
 314  144
                         String key = filePath.substring( 0, filePath.lastIndexOf( "." ) );
 315  
 
 316  144
                         if ( duplicatesFiles.containsKey( key ) )
 317  
                         {
 318  0
                             throw new DocumentRendererException( "Files '" + module.getSourceDirectory()
 319  
                                 + File.separator + filePath + "' clashes with existing '"
 320  
                                 + duplicatesFiles.get( key ) + "'." );
 321  
                         }
 322  
 
 323  144
                         duplicatesFiles.put( key, module.getSourceDirectory() + File.separator + filePath );
 324  
                     }
 325  
 
 326  144
                     filesToProcess.put( filePath, module );
 327  
                 }
 328  
             }
 329  96
         }
 330  
 
 331  24
         return filesToProcess;
 332  
     }
 333  
 
 334  
     /**
 335  
      * Returns a Map of files to process. The Map contains as keys the paths of the source files
 336  
      *      (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
 337  
      *
 338  
      * @param files The Collection of source files.
 339  
      * @return a Map of files to process.
 340  
      */
 341  
     public Map<String, SiteModule> getFilesToProcess( Collection<String> files )
 342  
     {
 343  
         // ----------------------------------------------------------------------
 344  
         // Map all the file names to parser ids
 345  
         // ----------------------------------------------------------------------
 346  
 
 347  0
         Map<String, SiteModule> filesToProcess = new HashMap<String, SiteModule>();
 348  
 
 349  0
         Collection<SiteModule> modules = siteModuleManager.getSiteModules();
 350  0
         for ( SiteModule siteModule : modules )
 351  
         {
 352  0
             String extension = "." + siteModule.getExtension();
 353  
 
 354  0
             String sourceDirectory = File.separator + siteModule.getSourceDirectory() + File.separator;
 355  
 
 356  0
             for ( String file : files )
 357  
             {
 358  
                 // first check if the file path contains one of the recognized source dir identifiers
 359  
                 // (there's trouble if a pathname contains 2 identifiers), then match file extensions (not unique).
 360  
 
 361  0
                 if ( file.indexOf( sourceDirectory ) != -1 )
 362  
                 {
 363  0
                     filesToProcess.put( file, siteModule );
 364  
                 }
 365  0
                 else if ( file.toLowerCase( Locale.ENGLISH ).endsWith( extension ) )
 366  
                 {
 367  
                     // don't overwrite if it's there already
 368  0
                     if ( !filesToProcess.containsKey( file ) )
 369  
                     {
 370  0
                         filesToProcess.put( file, siteModule );
 371  
                     }
 372  
                 }
 373  
             }
 374  0
         }
 375  
 
 376  0
         return filesToProcess;
 377  
     }
 378  
 
 379  
     /** {@inheritDoc} */
 380  
     public DocumentModel readDocumentModel( File documentDescriptor )
 381  
         throws DocumentRendererException, IOException
 382  
     {
 383  
         DocumentModel documentModel;
 384  
 
 385  12
         Reader reader = null;
 386  
         try
 387  
         {
 388  12
             reader = ReaderFactory.newXmlReader( documentDescriptor );
 389  12
             documentModel = new DocumentXpp3Reader().read( reader );
 390  
         }
 391  0
         catch ( XmlPullParserException e )
 392  
         {
 393  0
             throw new DocumentRendererException( "Error parsing document descriptor", e );
 394  
         }
 395  
         finally
 396  
         {
 397  12
             IOUtil.close( reader );
 398  12
         }
 399  
 
 400  12
         return documentModel;
 401  
     }
 402  
 
 403  
     /**
 404  
      * Sets the current base directory.
 405  
      *
 406  
      * @param newDir the absolute path to the base directory to set.
 407  
      */
 408  
     public void setBaseDir( String newDir )
 409  
     {
 410  24
         this.baseDir = newDir;
 411  24
     }
 412  
 
 413  
     /**
 414  
      * Return the current base directory.
 415  
      *
 416  
      * @return the current base directory.
 417  
      */
 418  
     public String getBaseDir()
 419  
     {
 420  408
         return this.baseDir;
 421  
     }
 422  
 
 423  
       //--------------------------------------------
 424  
      //
 425  
     //--------------------------------------------
 426  
 
 427  
     /**
 428  
      * Parse a source document into a sink.
 429  
      *
 430  
      * @param fullDocPath absolute path to the source document.
 431  
      * @param parserId determines the parser to use.
 432  
      * @param sink the sink to receive the events.
 433  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException in case of a parsing error.
 434  
      * @throws java.io.IOException if the source document cannot be opened.
 435  
      * @deprecated since 1.1.2, use {@link #parse(String, String, Sink, DocumentRendererContext)}
 436  
      */
 437  
     protected void parse( String fullDocPath, String parserId, Sink sink )
 438  
         throws DocumentRendererException, IOException
 439  
     {
 440  0
         parse( fullDocPath, parserId, sink, null );
 441  0
     }
 442  
 
 443  
     /**
 444  
      * Parse a source document into a sink.
 445  
      *
 446  
      * @param fullDocPath absolute path to the source document.
 447  
      * @param parserId determines the parser to use.
 448  
      * @param sink the sink to receive the events.
 449  
      * @param context the rendering context.
 450  
      * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException in case of a parsing error.
 451  
      * @throws java.io.IOException if the source document cannot be opened.
 452  
      */
 453  
     protected void parse( String fullDocPath, String parserId, Sink sink, DocumentRendererContext context )
 454  
         throws DocumentRendererException, IOException
 455  
     {
 456  144
         if ( getLogger().isDebugEnabled() )
 457  
         {
 458  0
             getLogger().debug( "Parsing file " + fullDocPath );
 459  
         }
 460  
 
 461  144
         Reader reader = null;
 462  
         try
 463  
         {
 464  144
             File f = new File( fullDocPath );
 465  
 
 466  144
             Parser parser = doxia.getParser( parserId );
 467  144
             switch ( parser.getType() )
 468  
             {
 469  
                 case Parser.XML_TYPE:
 470  72
                     reader = ReaderFactory.newXmlReader( f );
 471  
 
 472  72
                     if ( isVelocityFile( f ) )
 473  
                     {
 474  0
                         reader = getVelocityReader( f, ( (XmlStreamReader) reader ).getEncoding(), context );
 475  
                     }
 476  72
                     if ( context != null && Boolean.TRUE.equals( (Boolean) context.get( "validate" ) ) )
 477  
                     {
 478  0
                         reader = validate( reader, fullDocPath );
 479  
                     }
 480  
                     break;
 481  
 
 482  
                 case Parser.TXT_TYPE:
 483  
                 case Parser.UNKNOWN_TYPE:
 484  
                 default:
 485  72
                     if ( isVelocityFile( f ) )
 486  
                     {
 487  0
                         reader =
 488  
                             getVelocityReader( f, ( context == null ? ReaderFactory.FILE_ENCODING
 489  
                                             : context.getInputEncoding() ), context );
 490  
                     }
 491  
                     else
 492  
                     {
 493  72
                         if ( context == null )
 494  
                         {
 495  72
                             reader = ReaderFactory.newPlatformReader( f );
 496  
                         }
 497  
                         else
 498  
                         {
 499  0
                             reader = ReaderFactory.newReader( f, context.getInputEncoding() );
 500  
                         }
 501  
                     }
 502  
             }
 503  
 
 504  144
             sink.enableLogging( new PlexusLoggerWrapper( getLogger() ) );
 505  
 
 506  144
             doxia.parse( reader, parserId, sink );
 507  
         }
 508  0
         catch ( ParserNotFoundException e )
 509  
         {
 510  0
             throw new DocumentRendererException( "No parser '" + parserId
 511  
                         + "' found for " + fullDocPath + ": " + e.getMessage(), e );
 512  
         }
 513  0
         catch ( ParseException e )
 514  
         {
 515  0
             throw new DocumentRendererException( "Error parsing " + fullDocPath + ": " + e.getMessage(), e );
 516  
         }
 517  
         finally
 518  
         {
 519  144
             IOUtil.close( reader );
 520  
 
 521  144
             sink.flush();
 522  144
         }
 523  144
     }
 524  
 
 525  
     /**
 526  
      * Copies the contents of the resource directory to an output folder.
 527  
      *
 528  
      * @param outputDirectory the destination folder.
 529  
      * @throws java.io.IOException if any.
 530  
      */
 531  
     protected void copyResources( File outputDirectory )
 532  
             throws IOException
 533  
     {
 534  24
         File resourcesDirectory = new File( getBaseDir(), "resources" );
 535  
 
 536  24
         if ( !resourcesDirectory.isDirectory() )
 537  
         {
 538  0
             return;
 539  
         }
 540  
 
 541  24
         if ( !outputDirectory.exists() )
 542  
         {
 543  0
             outputDirectory.mkdirs();
 544  
         }
 545  
 
 546  24
         copyDirectory( resourcesDirectory, outputDirectory );
 547  24
     }
 548  
 
 549  
     /**
 550  
      * Copy content of a directory, excluding scm-specific files.
 551  
      *
 552  
      * @param source directory that contains the files and sub-directories to be copied.
 553  
      * @param destination destination folder.
 554  
      * @throws java.io.IOException if any.
 555  
      */
 556  
     protected void copyDirectory( File source, File destination )
 557  
             throws IOException
 558  
     {
 559  24
         if ( source.isDirectory() && destination.isDirectory() )
 560  
         {
 561  24
             DirectoryScanner scanner = new DirectoryScanner();
 562  
 
 563  24
             String[] includedResources = {"**/**"};
 564  
 
 565  24
             scanner.setIncludes( includedResources );
 566  
 
 567  24
             scanner.addDefaultExcludes();
 568  
 
 569  24
             scanner.setBasedir( source );
 570  
 
 571  24
             scanner.scan();
 572  
 
 573  24
             List<String> includedFiles = Arrays.asList( scanner.getIncludedFiles() );
 574  
 
 575  24
             for ( String name : includedFiles )
 576  
             {
 577  120
                 File sourceFile = new File( source, name );
 578  
 
 579  120
                 File destinationFile = new File( destination, name );
 580  
 
 581  120
                 FileUtils.copyFile( sourceFile, destinationFile );
 582  120
             }
 583  
         }
 584  24
     }
 585  
 
 586  
     /**
 587  
      * @param documentModel not null
 588  
      * @return the output name defined in the documentModel without the output extension. If the output name is not
 589  
      * defined, return target by default.
 590  
      * @since 1.1.1
 591  
      * @see org.apache.maven.doxia.document.DocumentModel#getOutputName()
 592  
      * @see #getOutputExtension()
 593  
      */
 594  
     protected String getOutputName( DocumentModel documentModel )
 595  
     {
 596  12
         String outputName = documentModel.getOutputName();
 597  12
         if ( outputName == null )
 598  
         {
 599  0
             getLogger().info( "No outputName is defined in the document descriptor. Using 'target'" );
 600  
 
 601  0
             documentModel.setOutputName( "target" );
 602  
         }
 603  
 
 604  12
         outputName = outputName.trim();
 605  12
         if ( outputName.toLowerCase( Locale.ENGLISH ).endsWith( "." + getOutputExtension() ) )
 606  
         {
 607  0
             outputName =
 608  
                 outputName.substring( 0, outputName.toLowerCase( Locale.ENGLISH )
 609  
                                                    .lastIndexOf( "." + getOutputExtension() ) );
 610  
         }
 611  12
         documentModel.setOutputName( outputName );
 612  
 
 613  12
         return documentModel.getOutputName();
 614  
     }
 615  
 
 616  
     /**
 617  
      * TODO: DOXIA-111: we need a general filter here that knows how to alter the context
 618  
      *
 619  
      * @param f the file to process, not null
 620  
      * @param encoding the wanted encoding, not null
 621  
      * @param context the current render document context not null
 622  
      * @return a reader with
 623  
      * @throws DocumentRendererException
 624  
      */
 625  
     private Reader getVelocityReader( File f, String encoding, DocumentRendererContext context )
 626  
         throws DocumentRendererException
 627  
     {
 628  0
         if ( getLogger().isDebugEnabled() )
 629  
         {
 630  0
             getLogger().debug( "Velocity render for " + f.getAbsolutePath() );
 631  
         }
 632  
 
 633  0
         SiteResourceLoader.setResource( f.getAbsolutePath() );
 634  
 
 635  0
         Context velocityContext = new VelocityContext();
 636  
 
 637  0
         if ( context.getKeys() != null )
 638  
         {
 639  0
             for ( int i = 0; i < context.getKeys().length; i++ )
 640  
             {
 641  0
                 String key = (String) context.getKeys()[i];
 642  
 
 643  0
                 velocityContext.put( key, context.get( key ) );
 644  
             }
 645  
         }
 646  
 
 647  0
         StringWriter sw = new StringWriter();
 648  
         try
 649  
         {
 650  0
             velocity.getEngine().mergeTemplate( f.getAbsolutePath(), encoding, velocityContext, sw );
 651  
         }
 652  0
         catch ( Exception e )
 653  
         {
 654  0
             throw new DocumentRendererException( "Error whenn parsing Velocity file " + f.getAbsolutePath() + ": "
 655  
                 + e.getMessage(), e );
 656  0
         }
 657  
 
 658  0
         return new StringReader( sw.toString() );
 659  
     }
 660  
 
 661  
     /**
 662  
      * @param f not null
 663  
      * @return <code>true</code> if file has a vm extension, <code>false</false> otherwise.
 664  
      */
 665  
     private static boolean isVelocityFile( File f )
 666  
     {
 667  144
         return FileUtils.getExtension( f.getAbsolutePath() ).toLowerCase( Locale.ENGLISH ).endsWith( "vm" );
 668  
     }
 669  
 
 670  
     private Reader validate( Reader source, String resource )
 671  
             throws ParseException, IOException
 672  
     {
 673  0
         getLogger().debug( "Validating: " + resource );
 674  
 
 675  
         try
 676  
         {
 677  0
             String content = IOUtil.toString( new BufferedReader( source ) );
 678  
 
 679  0
             new XmlValidator( new PlexusLoggerWrapper( getLogger() ) ).validate( content );
 680  
 
 681  0
             return new StringReader( content );
 682  
         }
 683  
         finally
 684  
         {
 685  0
             IOUtil.close( source );
 686  
         }
 687  
     }
 688  
 }