Coverage Report - org.apache.maven.shared.jar.classes.JarClassesAnalysis
 
Classes in this File Line Coverage Branch Coverage Complexity
JarClassesAnalysis
0%
0/63
0%
0/34
10
 
 1  
 package org.apache.maven.shared.jar.classes;
 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.bcel.classfile.ClassFormatException;
 23  
 import org.apache.bcel.classfile.ClassParser;
 24  
 import org.apache.bcel.classfile.DescendingVisitor;
 25  
 import org.apache.bcel.classfile.JavaClass;
 26  
 import org.apache.bcel.classfile.LineNumberTable;
 27  
 import org.apache.bcel.classfile.Method;
 28  
 import org.apache.maven.shared.jar.JarAnalyzer;
 29  
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 30  
 
 31  
 import java.io.IOException;
 32  
 import java.util.Iterator;
 33  
 import java.util.List;
 34  
 import java.util.jar.JarEntry;
 35  
 
 36  
 /**
 37  
  * Analyze the classes in a JAR file. This class is thread safe and immutable as it retains no state.
 38  
  * <p/>
 39  
  * Note that you must first create an instance of {@link org.apache.maven.shared.jar.JarAnalyzer} - see its Javadoc for
 40  
  * a typical use.
 41  
  *
 42  
  * @plexus.component role="org.apache.maven.shared.jar.classes.JarClassesAnalysis" role-hint="default"
 43  
  * @see #analyze(org.apache.maven.shared.jar.JarAnalyzer)
 44  
  */
 45  0
 public class JarClassesAnalysis
 46  
     extends AbstractLogEnabled
 47  
 {
 48  
     private static final double JAVA_1_6_CLASS_VERSION = 50.0;
 49  
 
 50  
     private static final double JAVA_1_5_CLASS_VERSION = 49.0;
 51  
 
 52  
     private static final double JAVA_1_4_CLASS_VERSION = 47.0;
 53  
 
 54  
     private static final double JAVA_1_3_CLASS_VERSION = 46.0;
 55  
 
 56  
     private static final double JAVA_1_2_CLASS_VERSION = 45.65536;
 57  
 
 58  
     private static final double JAVA_1_1_CLASS_VERSION = 45.3;
 59  
 
 60  
     /**
 61  
      * Analyze a JAR and find any classes and their details. Note that if the provided JAR analyzer has previously
 62  
      * analyzed the JAR, the cached results will be returned. You must obtain a new JAR analyzer to the re-read the
 63  
      * contents of the file.
 64  
      *
 65  
      * @param jarAnalyzer the JAR to analyze. This must not yet have been closed.
 66  
      * @return the details of the classes found
 67  
      */
 68  
     public JarClasses analyze( JarAnalyzer jarAnalyzer )
 69  
     {
 70  0
         JarClasses classes = jarAnalyzer.getJarData().getJarClasses();
 71  0
         if ( classes == null )
 72  
         {
 73  0
             String jarfilename = jarAnalyzer.getFile().getAbsolutePath();
 74  0
             classes = new JarClasses();
 75  
 
 76  0
             List classList = jarAnalyzer.getClassEntries();
 77  
 
 78  0
             classes.setDebugPresent( false );
 79  
 
 80  0
             double maxVersion = 0.0;
 81  
 
 82  0
             Iterator it = classList.iterator();
 83  0
             while ( it.hasNext() )
 84  
             {
 85  0
                 JarEntry entry = (JarEntry) it.next();
 86  0
                 String classname = entry.getName();
 87  
 
 88  
                 try
 89  
                 {
 90  0
                     ClassParser classParser = new ClassParser( jarfilename, classname );
 91  
 
 92  0
                     JavaClass javaClass = classParser.parse();
 93  
 
 94  0
                     String classSignature = javaClass.getClassName();
 95  
 
 96  0
                     if ( !classes.isDebugPresent() )
 97  
                     {
 98  0
                         if ( hasDebugSymbols( javaClass ) )
 99  
                         {
 100  0
                             classes.setDebugPresent( true );
 101  
                         }
 102  
                     }
 103  
 
 104  0
                     double classVersion = javaClass.getMajor();
 105  0
                     if ( javaClass.getMinor() > 0 )
 106  
                     {
 107  0
                         classVersion = classVersion + 1 / (double) javaClass.getMinor();
 108  
                     }
 109  
 
 110  0
                     if ( classVersion > maxVersion )
 111  
                     {
 112  0
                         maxVersion = classVersion;
 113  
                     }
 114  
 
 115  0
                     Method[] methods = javaClass.getMethods();
 116  0
                     for ( int i = 0; i < methods.length; i++ )
 117  
                     {
 118  0
                         classes.addMethod( classSignature + "." + methods[i].getName() + methods[i].getSignature() );
 119  
                     }
 120  
 
 121  0
                     String classPackageName = javaClass.getPackageName();
 122  
 
 123  0
                     classes.addClassName( classSignature );
 124  0
                     classes.addPackage( classPackageName );
 125  
 
 126  0
                     ImportVisitor importVisitor = new ImportVisitor( javaClass );
 127  0
                     DescendingVisitor descVisitor = new DescendingVisitor( javaClass, importVisitor );
 128  0
                     javaClass.accept( descVisitor );
 129  
 
 130  0
                     classes.addImports( importVisitor.getImports() );
 131  
                 }
 132  0
                 catch ( ClassFormatException e )
 133  
                 {
 134  0
                     getLogger().warn( "Unable to process class " + classname + " in JarAnalyzer File " + jarfilename,
 135  
                                       e );
 136  
                 }
 137  0
                 catch ( IOException e )
 138  
                 {
 139  0
                     getLogger().warn( "Unable to process JarAnalyzer File " + jarfilename, e );
 140  0
                 }
 141  0
             }
 142  
 
 143  
             // TODO: check these since they are > instead of >=
 144  0
             if ( maxVersion >= JAVA_1_6_CLASS_VERSION )
 145  
             {
 146  0
                 classes.setJdkRevision( "1.6" );
 147  
             }
 148  0
             else if ( maxVersion >= JAVA_1_5_CLASS_VERSION )
 149  
             {
 150  0
                 classes.setJdkRevision( "1.5" );
 151  
             }
 152  0
             else if ( maxVersion > JAVA_1_4_CLASS_VERSION )
 153  
             {
 154  0
                 classes.setJdkRevision( "1.4" );
 155  
             }
 156  0
             else if ( maxVersion > JAVA_1_3_CLASS_VERSION )
 157  
             {
 158  0
                 classes.setJdkRevision( "1.3" );
 159  
             }
 160  0
             else if ( maxVersion > JAVA_1_2_CLASS_VERSION )
 161  
             {
 162  0
                 classes.setJdkRevision( "1.2" );
 163  
             }
 164  0
             else if ( maxVersion > JAVA_1_1_CLASS_VERSION )
 165  
             {
 166  0
                 classes.setJdkRevision( "1.1" );
 167  
             }
 168  0
             else if ( maxVersion > 0 )
 169  
             {
 170  0
                 classes.setJdkRevision( "1.0" );
 171  
             }
 172  
 
 173  0
             jarAnalyzer.getJarData().setJarClasses( classes );
 174  
         }
 175  0
         return classes;
 176  
     }
 177  
 
 178  
     private boolean hasDebugSymbols( JavaClass javaClass )
 179  
     {
 180  0
         boolean ret = false;
 181  0
         Method[] methods = javaClass.getMethods();
 182  0
         for ( int i = 0; i < methods.length; i++ )
 183  
         {
 184  0
             LineNumberTable linenumbers = methods[i].getLineNumberTable();
 185  0
             if ( linenumbers != null && linenumbers.getLength() > 0 )
 186  
             {
 187  0
                 ret = true;
 188  0
                 break;
 189  
             }
 190  
         }
 191  0
         return ret;
 192  
     }
 193  
 }