Coverage Report - org.apache.maven.jxr.DirectoryIndexer
 
Classes in this File Line Coverage Branch Coverage Complexity
DirectoryIndexer
100%
100/100
N/A
1,733
 
 1  
 package org.apache.maven.jxr;
 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 org.apache.maven.jxr.pacman.ClassType;
 23  
 import org.apache.maven.jxr.pacman.PackageManager;
 24  
 import org.apache.maven.jxr.pacman.PackageType;
 25  
 import org.apache.maven.jxr.log.VelocityLogger;
 26  
 import org.apache.maven.jxr.log.Log;
 27  
 import org.apache.oro.text.perl.Perl5Util;
 28  
 import org.apache.velocity.Template;
 29  
 import org.apache.velocity.VelocityContext;
 30  
 import org.apache.velocity.app.VelocityEngine;
 31  
 import org.codehaus.plexus.util.IOUtil;
 32  
 
 33  
 import java.io.File;
 34  
 import java.io.FileWriter;
 35  
 import java.util.Enumeration;
 36  
 import java.util.HashMap;
 37  
 import java.util.Iterator;
 38  
 import java.util.Map;
 39  
 import java.util.TreeMap;
 40  
 
 41  
 /**
 42  
  * This class creates the navigational pages for jxr's cross-referenced source
 43  
  * files.  The navigation is inspired by javadoc, so it should have a familiar feel.
 44  
  *
 45  
  * Creates the following files:
 46  
  * <ul>
 47  
  * <li>index.html            main index containing the frameset</li>
 48  
  * <li>overview-frame.html   list of the project's packages              (top left)</li>
 49  
  * <li>allclasses-frame.html list of all classes in the project          (bottom left)</li>
 50  
  * <li>overview-summary.html top-level listing of the project's packages (main frame)</li>
 51  
  *
 52  
  * <ul>
 53  
  * Package specific:
 54  
  * <li>package-summary.html listing of all classes in this package    (main frame)</li>
 55  
  * <li>package-frame.html   listing of all classes in this package    (bottom left)</li>
 56  
  * </ul>
 57  
  * </ul>
 58  
  *
 59  
  * @author <a href="mailto:bellingard@gmail.com">Fabrice Bellingard </a>
 60  
  * @author <a href="mailto:brian@brainslug.org">Brian Leonard</a>
 61  
  * @version $Id: DirectoryIndexer.java 524455 2007-03-31 17:15:38Z dennisl $
 62  
  */
 63  
 public class DirectoryIndexer
 64  
 {
 65  
     /*
 66  
      * JavaCodeTransform uses this to cross-reference package references
 67  
      * with that package's main summary page.
 68  
      */
 69  
     static final String INDEX = "package-summary.html";
 70  
 
 71  
     /*
 72  
      * Path to the root output directory.
 73  
      */
 74  
     private String root;
 75  
 
 76  
     /*
 77  
      * Package Manager for this project.
 78  
      */
 79  
     private PackageManager packageManager;
 80  
 
 81  
     /*
 82  
      * see the getter/setter docs for these properties
 83  
      */
 84  
     private String outputEncoding;
 85  
 
 86  
     private String templateDir;
 87  
 
 88  
     private String windowTitle;
 89  
 
 90  
     private String docTitle;
 91  
 
 92  
     private String bottom;
 93  
 
 94  
     /**
 95  
      * Constructor for the DirectoryIndexer object
 96  
      *
 97  
      * @param packageManager PackageManager for this project
 98  
      * @param root Path of the root output directory
 99  
      */
 100  
     public DirectoryIndexer( PackageManager packageManager, String root )
 101  2
     {
 102  2
         this.packageManager = packageManager;
 103  2
         this.root = root;
 104  2
     }
 105  
 
 106  
     /**
 107  
      * OutputEncoding is the encoding of output files.
 108  
      *
 109  
      * @param outputEncoding output Encoding
 110  
      */
 111  
     public void setOutputEncoding( String outputEncoding )
 112  
     {
 113  2
         this.outputEncoding = outputEncoding;
 114  2
     }
 115  
 
 116  
     /**
 117  
      * see setOutputEncoding(String)
 118  
      */
 119  
     public String getOutputEncoding()
 120  
     {
 121  2
         return outputEncoding;
 122  
     }
 123  
 
 124  
     /**
 125  
      * TemplateDir is the location of the jelly template files used
 126  
      * to generate the navigation pages.
 127  
      *
 128  
      * @param templateDir location of the template directory
 129  
      */
 130  
     public void setTemplateDir( String templateDir )
 131  
     {
 132  2
         this.templateDir = templateDir;
 133  2
     }
 134  
 
 135  
     /**
 136  
      * see setTemplateDir(String)
 137  
      */
 138  
     public String getTemplateDir()
 139  
     {
 140  26
         return templateDir;
 141  
     }
 142  
 
 143  
     /**
 144  
      * WindowTitle is used in the output's &lt;title&gt; tags
 145  
      * see the javadoc documentation for the property of the same name
 146  
      *
 147  
      * @param windowTitle the &lt;title&gt; attribute
 148  
      */
 149  
     public void setWindowTitle( String windowTitle )
 150  
     {
 151  2
         this.windowTitle = windowTitle;
 152  2
     }
 153  
 
 154  
     /**
 155  
      * see setWindowTitle(String)
 156  
      *
 157  
      * @see #setWindowTitle(String) setWindowTitle
 158  
      */
 159  
     public String getWindowTitle()
 160  
     {
 161  2
         return windowTitle;
 162  
     }
 163  
 
 164  
     /**
 165  
      * DocTitle is used as a page heading for the summary files
 166  
      * see the javadoc documentation for the property of the same name
 167  
      *
 168  
      * @param docTitle major page heading
 169  
      */
 170  
     public void setDocTitle( String docTitle )
 171  
     {
 172  2
         this.docTitle = docTitle;
 173  2
     }
 174  
 
 175  
     /**
 176  
      * see setDocTitle(String)
 177  
      *
 178  
      * @see #setDocTitle(String) setDocTitle
 179  
      */
 180  
     public String getDocTitle()
 181  
     {
 182  2
         return docTitle;
 183  
     }
 184  
 
 185  
     /**
 186  
      * Bottom is a footer for the navigation pages, usually a copyright
 187  
      * see the javadoc documentation for the property of the same name
 188  
      *
 189  
      * @param bottom page footer
 190  
      */
 191  
     public void setBottom( String bottom )
 192  
     {
 193  2
         this.bottom = bottom;
 194  2
     }
 195  
 
 196  
     /**
 197  
      * see setBottom(String)
 198  
      *
 199  
      * @see #setBottom(String) setBottom
 200  
      */
 201  
     public String getBottom()
 202  
     {
 203  2
         return bottom;
 204  
     }
 205  
 
 206  
     /**
 207  
      * Does the actual indexing.
 208  
      *
 209  
      * @throws JxrException If something went wrong
 210  
      */
 211  
     public void process( Log log )
 212  
         throws JxrException
 213  
     {
 214  2
         Map info = getPackageInfo();
 215  
 
 216  2
         VelocityEngine engine = new VelocityEngine();
 217  2
         setProperties( engine, log );
 218  
         try
 219  
         {
 220  2
             engine.init();
 221  
         }
 222  
         catch ( Exception e )
 223  
         {
 224  
             throw new JxrException( "Error initialising Velocity", e );
 225  2
         }
 226  
 
 227  2
         VelocityContext context = new VelocityContext();
 228  2
         context.put( "outputEncoding", getOutputEncoding() );
 229  2
         context.put( "windowTitle", getWindowTitle() );
 230  2
         context.put( "docTitle", getDocTitle() );
 231  2
         context.put( "bottom", getBottom() );
 232  2
         context.put( "info", info );
 233  
 
 234  2
         doVelocity( "index", root, context, engine );
 235  2
         doVelocity( "overview-frame", root, context, engine );
 236  2
         doVelocity( "allclasses-frame", root, context, engine );
 237  2
         doVelocity( "overview-summary", root, context, engine );
 238  
 
 239  2
         Iterator iter = ( (Map) info.get( "allPackages" ) ).values().iterator();
 240  4
         while ( iter.hasNext() )
 241  
         {
 242  2
             Map pkgInfo = (Map) iter.next();
 243  
 
 244  2
             VelocityContext subContext = new VelocityContext( context );
 245  2
             subContext.put( "pkgInfo", pkgInfo );
 246  
 
 247  2
             String outDir = root + "/" + (String) pkgInfo.get( "dir" );
 248  2
             doVelocity( "package-summary", outDir, subContext, engine );
 249  2
             doVelocity( "package-frame", outDir, subContext, engine );
 250  
         }
 251  2
     }
 252  
 
 253  
     /*
 254  
      * Set Velocity properties to find templates
 255  
      */
 256  
     private void setProperties( VelocityEngine engine, Log log )
 257  
     {
 258  2
         File templateDirFile = new File( getTemplateDir() );
 259  2
         if ( templateDirFile.isAbsolute() )
 260  
         {
 261  
             // the property has been overriden: need to use a FileResourceLoader
 262  
             engine.setProperty( "resource.loader", "file" );
 263  
             engine.setProperty( "file.resource.loader.class",
 264  
                                 "org.apache.velocity.runtime.resource.loader.FileResourceLoader" );
 265  
             engine.setProperty( "file.resource.loader.path", templateDirFile.toString() );
 266  
         }
 267  
         else
 268  
         {
 269  
             // use of the default templates
 270  2
             engine.setProperty( "resource.loader", "classpath" );
 271  2
             engine.setProperty( "classpath.resource.loader.class",
 272  
                                 "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader" );
 273  
         }
 274  
         // avoid "unable to find resource 'VM_global_library.vm' in any resource loader."
 275  2
         engine.setProperty( "velocimacro.library", "" );
 276  4
         engine.setProperty( Log.class.getName(), log );
 277  2
         engine.setProperty( "runtime.log.logsystem.class", VelocityLogger.class.getName() );
 278  2
     }
 279  
 
 280  
     /*
 281  
      * Generate the HTML file according to the Velocity template
 282  
      */
 283  
     private void doVelocity( String templateName, String outDir, VelocityContext context, VelocityEngine engine )
 284  
         throws JxrException
 285  
     {
 286  
         // output file
 287  12
         File file = new File( outDir, templateName + ".html" );
 288  12
         file.getParentFile().mkdirs();
 289  12
         FileWriter writer = null;
 290  
 
 291  
         try
 292  
         {
 293  12
             writer = new FileWriter( file );
 294  
 
 295  
             // template file
 296  12
             StringBuffer templateFile = new StringBuffer();
 297  12
             File templateDirFile = new File( getTemplateDir() );
 298  12
             if ( !templateDirFile.isAbsolute() )
 299  
             {
 300  
                 // default templates
 301  12
                 templateFile.append( getTemplateDir() );
 302  12
                 templateFile.append( "/" );
 303  
             }
 304  12
             templateFile.append( templateName );
 305  12
             templateFile.append( ".vm" );
 306  12
             Template template = engine.getTemplate( templateFile.toString() );
 307  
 
 308  
             // do the merge
 309  12
             template.merge( context, writer );
 310  12
             writer.flush();
 311  
         }
 312  
         catch ( Exception e )
 313  
         {
 314  
             throw new JxrException( "Error merging velocity template", e );
 315  
         }
 316  
         finally
 317  
         {
 318  12
             IOUtil.close( writer );
 319  12
         }
 320  12
     }
 321  
 
 322  
     /*
 323  
      * Creates a Map of other Maps containing information about
 324  
      * this project's packages and classes, obtained from the PackageManager.
 325  
      *
 326  
      * allPackages collection of Maps with package info, with the following format
 327  
      *   {name}    package name (e.g., "org.apache.maven.jxr")
 328  
      *   {dir}     package dir relative to the root output dir (e.g., "org/apache/maven/jxr")
 329  
      *   {rootRef} relative link to root output dir (e.g., "../../../../") note trailing slash
 330  
      *   {classes} collection of Maps with class info
 331  
      *      {name}  class name (e.g., "DirectoryIndexer")
 332  
      *      {dir}   duplicate of package {dir}
 333  
      *
 334  
      * allClasses collection of Maps with class info, format as above
 335  
      *
 336  
      */
 337  
     private Map getPackageInfo()
 338  
     {
 339  2
         TreeMap allPackages = new TreeMap();
 340  2
         TreeMap allClasses = new TreeMap();
 341  2
         Perl5Util perl = new Perl5Util();
 342  
 
 343  2
         Enumeration packages = packageManager.getPackageTypes();
 344  4
         while ( packages.hasMoreElements() )
 345  
         {
 346  2
             PackageType pkg = (PackageType) packages.nextElement();
 347  2
             String pkgName = pkg.getName();
 348  2
             String pkgDir = perl.substitute( "s/\\./\\//g", pkgName );
 349  2
             String rootRef = perl.substitute( "s/[^\\.]*(\\.|$)/..\\//g", pkgName );
 350  
 
 351  
             // special case for the default package
 352  
             // javadoc doesn't deal with it, but it's easy for us
 353  2
             if ( pkgName.length() == 0 )
 354  
             {
 355  
                 pkgName = "(default package)";
 356  
                 pkgDir = ".";
 357  
                 rootRef = "./";
 358  
             }
 359  
 
 360  2
             TreeMap pkgClasses = new TreeMap();
 361  2
             Enumeration classes = pkg.getClassTypes();
 362  7
             while ( classes.hasMoreElements() )
 363  
             {
 364  5
                 ClassType clazz = (ClassType) classes.nextElement();
 365  
 
 366  5
                 String className = clazz.getName();
 367  5
                 Map classInfo = new HashMap();
 368  5
                 if ( clazz.getFilename() != null )
 369  
                 {
 370  5
                     classInfo.put( "filename", clazz.getFilename() );
 371  
                 }
 372  
                 else
 373  
                 {
 374  
                     classInfo.put( "filename", "" );
 375  
                 }
 376  5
                 classInfo.put( "name", className );
 377  5
                 classInfo.put( "dir", pkgDir );
 378  
 
 379  5
                 pkgClasses.put( className, classInfo );
 380  5
                 allClasses.put( className, classInfo );
 381  
             }
 382  
 
 383  2
             Map pkgInfo = new HashMap();
 384  2
             pkgInfo.put( "name", pkgName );
 385  2
             pkgInfo.put( "dir", pkgDir );
 386  2
             pkgInfo.put( "classes", pkgClasses );
 387  2
             pkgInfo.put( "rootRef", rootRef );
 388  2
             allPackages.put( pkgName, pkgInfo );
 389  
         }
 390  
 
 391  2
         Map info = new HashMap();
 392  2
         info.put( "allPackages", allPackages );
 393  2
         info.put( "allClasses", allClasses );
 394  
 
 395  2
         return info;
 396  
     }
 397  
 }