Clover coverage report - MetaClass - 1.1
Coverage timestamp: Tue Apr 27 2004 10:46:24 EST
file stats: LOC: 404   Methods: 18
NCLOC: 252   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
ClassDescriptorCompiler.java 97.2% 97.9% 100% 98%
coverage coverage
 1   
 /*
 2   
  * Copyright (C) The MetaClass Group. All rights reserved.
 3   
  *
 4   
  * This software is published under the terms of the Spice
 5   
  * Software License version 1.1, a copy of which has been included
 6   
  * with this distribution in the LICENSE.txt file.
 7   
  */
 8   
 package org.codehaus.metaclass.tools.compiler;
 9   
 
 10   
 import com.thoughtworks.qdox.JavaDocBuilder;
 11   
 import com.thoughtworks.qdox.model.JavaClass;
 12   
 import com.thoughtworks.qdox.model.JavaSource;
 13   
 import java.io.File;
 14   
 import java.io.FileInputStream;
 15   
 import java.io.FileNotFoundException;
 16   
 import java.io.FileReader;
 17   
 import java.io.IOException;
 18   
 import java.io.InputStream;
 19   
 import java.util.ArrayList;
 20   
 import java.util.Collection;
 21   
 import java.util.HashSet;
 22   
 import java.util.Iterator;
 23   
 import java.util.List;
 24   
 import java.util.Set;
 25   
 import org.codehaus.metaclass.io.MetaClassIO;
 26   
 import org.codehaus.metaclass.model.ClassDescriptor;
 27   
 import org.codehaus.metaclass.tools.packer.ClassDescriptorPacker;
 28   
 import org.codehaus.metaclass.tools.qdox.QDoxAttributeInterceptor;
 29   
 import org.codehaus.metaclass.tools.qdox.QDoxDescriptorParser;
 30   
 
 31   
 /**
 32   
  * A bean that can create MetaClass descriptors by processing Java Source files
 33   
  * with qdox.
 34   
  *
 35   
  * @author Peter Donald
 36   
  * @version $Revision: 1.16 $ $Date: 2003/12/11 08:41:50 $
 37   
  */
 38   
 public class ClassDescriptorCompiler
 39   
 {
 40   
     /** The utility class used to generate MetaClass object. */
 41   
     private static final QDoxDescriptorParser c_descriptorParser = new QDoxDescriptorParser();
 42   
 
 43   
     /**
 44   
      * Flag indicating whether the compacter should methods with no attributes.
 45   
      */
 46   
     private boolean m_keepEmptyMethods;
 47   
 
 48   
     /** Destination directory */
 49   
     private File m_destDir;
 50   
 
 51   
     /** The IO object to use when writing descriptors. */
 52   
     private MetaClassIO m_metaClassIO;
 53   
 
 54   
     /** the monitor that receives messages about operation of compiler. */
 55   
     private CompilerMonitor m_monitor = new DefaultCompilerMonitor();
 56   
 
 57   
     /** The source files to process. */
 58   
     private final List m_sourceFiles = new ArrayList();
 59   
 
 60   
     /** The interceptors used to process source files. */
 61   
     private final List m_interceptors = new ArrayList();
 62   
 
 63   
     /** The filters used to filter source files. */
 64   
     private final List m_filters = new ArrayList();
 65   
 
 66   
     /**
 67   
      * Set flag indicating whether Compacter should keep empty methods.
 68   
      *
 69   
      * @param keepEmptyMethods the flag
 70   
      */
 71  24
     public void setKeepEmptyMethods( final boolean keepEmptyMethods )
 72   
     {
 73  24
         m_keepEmptyMethods = keepEmptyMethods;
 74   
     }
 75   
 
 76   
     /**
 77   
      * Set the monitor to receive messages about compiler operation.
 78   
      *
 79   
      * @param monitor the monitor.
 80   
      */
 81  32
     public void setMonitor( final CompilerMonitor monitor )
 82   
     {
 83  32
         if( null == monitor )
 84   
         {
 85  2
             throw new NullPointerException( "monitor" );
 86   
         }
 87  30
         m_monitor = monitor;
 88   
     }
 89   
 
 90   
     /**
 91   
      * Add a sourceFile to process.
 92   
      *
 93   
      * @param sourceFile the sourceFile
 94   
      */
 95  34
     public void addSourceFile( final File sourceFile )
 96   
     {
 97  34
         if( null == sourceFile )
 98   
         {
 99  2
             throw new NullPointerException( "sourceFile" );
 100   
         }
 101  32
         m_sourceFiles.add( sourceFile );
 102   
     }
 103   
 
 104   
     /**
 105   
      * Add a filter to process metadata.
 106   
      *
 107   
      * @param filter the filter
 108   
      */
 109  6
     public void addFilter( final JavaClassFilter filter )
 110   
     {
 111  6
         if( null == filter )
 112   
         {
 113  2
             throw new NullPointerException( "filter" );
 114   
         }
 115  4
         m_filters.add( filter );
 116   
     }
 117   
 
 118   
     /**
 119   
      * Add an interceptor to process metadata.
 120   
      *
 121   
      * @param interceptor the interceptor
 122   
      */
 123  24
     public void addInterceptor( final QDoxAttributeInterceptor interceptor )
 124   
     {
 125  24
         if( null == interceptor )
 126   
         {
 127  2
             throw new NullPointerException( "interceptor" );
 128   
         }
 129  22
         m_interceptors.add( interceptor );
 130   
     }
 131   
 
 132   
     /**
 133   
      * Set the destination directory for generated files.
 134   
      *
 135   
      * @param destDir the destination directory for generated files.
 136   
      */
 137  44
     public void setDestDir( final File destDir )
 138   
     {
 139  44
         m_destDir = destDir;
 140   
     }
 141   
 
 142   
     /**
 143   
      * Set the IO object used to write descriptors.
 144   
      *
 145   
      * @param metaClassIO the IO object used to write descriptors.
 146   
      */
 147  48
     public void setMetaClassIO( final MetaClassIO metaClassIO )
 148   
     {
 149  48
         if( null == metaClassIO )
 150   
         {
 151  2
             throw new NullPointerException( "metaClassIO" );
 152   
         }
 153  46
         m_metaClassIO = metaClassIO;
 154   
     }
 155   
 
 156   
     /**
 157   
      * Return the MetaClassIO used to serialize descriptors.
 158   
      *
 159   
      * @return the MetaClassIO used to serialize descriptors.
 160   
      */
 161  6
     public MetaClassIO getMetaClassIO()
 162   
     {
 163  6
         return m_metaClassIO;
 164   
     }
 165   
 
 166   
     /**
 167   
      * Generate classes and output.
 168   
      *
 169   
      * @throws Exception if unable to compile descriptors
 170   
      */
 171  44
     public void execute()
 172   
         throws Exception
 173   
     {
 174  44
         validate();
 175  36
         processSourceFiles();
 176   
     }
 177   
 
 178   
     /**
 179   
      * Output the ClassDescriptors that are not filtered out.
 180   
      */
 181  36
     protected void processSourceFiles()
 182   
     {
 183  36
         final List classes = collectJavaClassesToSerialize();
 184  36
         m_monitor.javaClassObjectsLoaded( classes );
 185   
 
 186  36
         final Collection filteredClasses = filterJavaClassObjects( classes );
 187  36
         m_monitor.postFilterJavaClassList( classes );
 188   
 
 189  36
         final Collection descriptors = buildClassDescriptors( filteredClasses );
 190  36
         m_monitor.postBuildDescriptorsList( descriptors );
 191   
 
 192  36
         final Set output = compactClassDescriptors( descriptors );
 193  36
         m_monitor.postCompactDescriptorsList( output );
 194   
 
 195  36
         writeClassDescriptors( output );
 196   
     }
 197   
 
 198   
     /**
 199   
      * Build class descriptors from input JavaCLass objects.
 200   
      *
 201   
      * @param classes the list containing JavaClass objects.
 202   
      * @return a list containing created ClassDescriptor objects.
 203   
      */
 204  36
     private List buildClassDescriptors( final Collection classes )
 205   
     {
 206  36
         final QDoxAttributeInterceptor[] interceptors =
 207   
             (QDoxAttributeInterceptor[])m_interceptors.
 208   
             toArray( new QDoxAttributeInterceptor[ m_interceptors.size() ] );
 209   
 
 210  36
         final ArrayList descriptors = new ArrayList();
 211  36
         final Iterator iterator = classes.iterator();
 212  36
         while( iterator.hasNext() )
 213   
         {
 214  28
             final JavaClass javaClass = (JavaClass)iterator.next();
 215  28
             try
 216   
             {
 217  28
                 final ClassDescriptor descriptor =
 218   
                     c_descriptorParser.buildClassDescriptor( javaClass,
 219   
                                                              interceptors );
 220  26
                 descriptors.add( descriptor );
 221   
             }
 222   
             catch( final Throwable t )
 223   
             {
 224  2
                 final String classname = javaClass.getFullyQualifiedName();
 225  2
                 m_monitor.errorGeneratingDescriptor( classname, t );
 226   
             }
 227   
         }
 228  36
         return descriptors;
 229   
     }
 230   
 
 231   
     /**
 232   
      * Output the specified ClassDescriptors.
 233   
      *
 234   
      * @param classes the list containing ClassDescriptor objects.
 235   
      */
 236  36
     private void writeClassDescriptors( final Collection classes )
 237   
     {
 238  36
         final Iterator iterator = classes.iterator();
 239  36
         while( iterator.hasNext() )
 240   
         {
 241  24
             final ClassDescriptor descriptor = (ClassDescriptor)iterator.next();
 242  24
             writeClassDescriptor( descriptor );
 243   
         }
 244   
     }
 245   
 
 246   
     /**
 247   
      * Return the set of classes that will actually be serialized and have not
 248   
      * been filtered out.
 249   
      *
 250   
      * @return list of classes to serialize
 251   
      */
 252  36
     private List collectJavaClassesToSerialize()
 253   
     {
 254  36
         final JavaDocBuilder builder = new JavaDocBuilder();
 255  36
         final int count = m_sourceFiles.size();
 256  36
         for( int i = 0; i < count; i++ )
 257   
         {
 258  32
             final File file = (File)m_sourceFiles.get( i );
 259  32
             FileInputStream in = null;
 260  32
             try
 261   
             {
 262  32
                 builder.addSource( new FileReader( file ) );
 263   
             }
 264   
             catch( final FileNotFoundException fnfe )
 265   
             {
 266  2
                 m_monitor.missingSourceFile( file );
 267   
             }
 268   
             finally
 269   
             {
 270  32
                 shutdownStream( in );
 271   
             }
 272   
         }
 273  36
         final JavaSource[] sources = builder.getSources();
 274  36
         final ArrayList classes = new ArrayList();
 275  36
         for( int i = 0; i < sources.length; i++ )
 276   
         {
 277  30
             final JavaClass[] javaClasses = sources[ i ].getClasses();
 278  30
             for( int j = 0; j < javaClasses.length; j++ )
 279   
             {
 280  30
                 classes.add( javaClasses[ j ] );
 281   
             }
 282   
         }
 283  36
         return classes;
 284   
     }
 285   
 
 286   
     /**
 287   
      * Return the set of classes that will actually be serialized and have not
 288   
      * been filtered out.
 289   
      *
 290   
      * @param input the list of input classes to filter
 291   
      * @return list of classes to serialize
 292   
      */
 293  36
     private Set filterJavaClassObjects( final List input )
 294   
     {
 295  36
         final JavaClassFilter[] filters = (JavaClassFilter[])m_filters.
 296   
             toArray( new JavaClassFilter[ m_filters.size() ] );
 297  36
         final MulticastJavaClassFilter filter =
 298   
             new MulticastJavaClassFilter( filters );
 299   
 
 300  36
         final Set classes = new HashSet();
 301  36
         final int classCount = input.size();
 302  36
         for( int i = 0; i < classCount; i++ )
 303   
         {
 304  30
             final JavaClass candidate = (JavaClass)input.get( i );
 305  30
             final JavaClass javaClass = filter.filterClass( candidate );
 306  30
             if( null == javaClass )
 307   
             {
 308  2
                 continue;
 309   
             }
 310  28
             classes.add( javaClass );
 311   
         }
 312  36
         return classes;
 313   
     }
 314   
 
 315   
     /**
 316   
      * Return the set of ClassDescriptors after cmpaction.
 317   
      *
 318   
      * @param input the list of input ClassDescriptors to compact
 319   
      * @return list of ClassDescriptors to serialize
 320   
      */
 321  36
     private Set compactClassDescriptors( final Collection input )
 322   
     {
 323  36
         final ClassDescriptorPacker packer =
 324   
             new ClassDescriptorPacker( m_keepEmptyMethods );
 325  36
         final Set classes = new HashSet();
 326  36
         final Iterator iterator = input.iterator();
 327  36
         while( iterator.hasNext() )
 328   
         {
 329  26
             final ClassDescriptor candidate = (ClassDescriptor)iterator.next();
 330  26
             final ClassDescriptor descriptor = packer.pack( candidate );
 331  26
             if( null == descriptor )
 332   
             {
 333  2
                 continue;
 334   
             }
 335  24
             classes.add( descriptor );
 336   
         }
 337  36
         return classes;
 338   
     }
 339   
 
 340   
     /**
 341   
      * Validate that the parameters are valid.
 342   
      *
 343   
      * @throws Exception if unable to validate settings
 344   
      */
 345  44
     private void validate()
 346   
         throws Exception
 347   
     {
 348  44
         if( null == m_destDir )
 349   
         {
 350  4
             final String message = "DestDir not specified";
 351  4
             throw new Exception( message );
 352   
         }
 353  40
         if( m_destDir.exists() && !m_destDir.isDirectory() )
 354   
         {
 355  4
             final String message =
 356   
                 "DestDir (" + m_destDir + ") is not a directory.";
 357  4
             throw new Exception( message );
 358   
         }
 359  36
         if( !m_destDir.exists() && !m_destDir.mkdirs() )
 360   
         {
 361  0
             final String message =
 362   
                 "DestDir (" + m_destDir + ") could not be created.";
 363  0
             throw new Exception( message );
 364   
         }
 365   
     }
 366   
 
 367   
     /**
 368   
      * Write ClassDescriptor out into a file.
 369   
      *
 370   
      * @param descriptor the ClassDescriptor object
 371   
      */
 372  26
     void writeClassDescriptor( final ClassDescriptor descriptor )
 373   
     {
 374  26
         try
 375   
         {
 376  26
             m_metaClassIO.writeDescriptor( m_destDir, descriptor );
 377   
         }
 378   
         catch( final Exception e )
 379   
         {
 380  6
             m_monitor.errorWritingDescriptor( descriptor, e );
 381   
         }
 382   
     }
 383   
 
 384   
     /**
 385   
      * Close the specified input stream and swallow any exceptions.
 386   
      *
 387   
      * @param inputStream the input stream
 388   
      */
 389  34
     void shutdownStream( final InputStream inputStream )
 390   
     {
 391  34
         if( null != inputStream )
 392   
         {
 393  2
             try
 394   
             {
 395  2
                 inputStream.close();
 396   
             }
 397   
             catch( IOException e )
 398   
             {
 399   
                 //Ignored
 400   
             }
 401   
         }
 402   
     }
 403   
 }
 404