1 package org.apache.maven.shared.jar.classes;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
38
39
40
41
42
43
44
45 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
62
63
64
65
66
67
68 public JarClasses analyze( JarAnalyzer jarAnalyzer )
69 {
70 JarClasses classes = jarAnalyzer.getJarData().getJarClasses();
71 if ( classes == null )
72 {
73 String jarfilename = jarAnalyzer.getFile().getAbsolutePath();
74 classes = new JarClasses();
75
76 List classList = jarAnalyzer.getClassEntries();
77
78 classes.setDebugPresent( false );
79
80 double maxVersion = 0.0;
81
82 Iterator it = classList.iterator();
83 while ( it.hasNext() )
84 {
85 JarEntry entry = (JarEntry) it.next();
86 String classname = entry.getName();
87
88 try
89 {
90 ClassParser classParser = new ClassParser( jarfilename, classname );
91
92 JavaClass javaClass = classParser.parse();
93
94 String classSignature = javaClass.getClassName();
95
96 if ( !classes.isDebugPresent() )
97 {
98 if ( hasDebugSymbols( javaClass ) )
99 {
100 classes.setDebugPresent( true );
101 }
102 }
103
104 double classVersion = javaClass.getMajor();
105 if ( javaClass.getMinor() > 0 )
106 {
107 classVersion = classVersion + 1 / (double) javaClass.getMinor();
108 }
109
110 if ( classVersion > maxVersion )
111 {
112 maxVersion = classVersion;
113 }
114
115 Method[] methods = javaClass.getMethods();
116 for ( int i = 0; i < methods.length; i++ )
117 {
118 classes.addMethod( classSignature + "." + methods[i].getName() + methods[i].getSignature() );
119 }
120
121 String classPackageName = javaClass.getPackageName();
122
123 classes.addClassName( classSignature );
124 classes.addPackage( classPackageName );
125
126 ImportVisitor importVisitor = new ImportVisitor( javaClass );
127 DescendingVisitor descVisitor = new DescendingVisitor( javaClass, importVisitor );
128 javaClass.accept( descVisitor );
129
130 classes.addImports( importVisitor.getImports() );
131 }
132 catch ( ClassFormatException e )
133 {
134 getLogger().warn( "Unable to process class " + classname + " in JarAnalyzer File " + jarfilename,
135 e );
136 }
137 catch ( IOException e )
138 {
139 getLogger().warn( "Unable to process JarAnalyzer File " + jarfilename, e );
140 }
141 }
142
143
144 if ( maxVersion >= JAVA_1_6_CLASS_VERSION )
145 {
146 classes.setJdkRevision( "1.6" );
147 }
148 else if ( maxVersion >= JAVA_1_5_CLASS_VERSION )
149 {
150 classes.setJdkRevision( "1.5" );
151 }
152 else if ( maxVersion > JAVA_1_4_CLASS_VERSION )
153 {
154 classes.setJdkRevision( "1.4" );
155 }
156 else if ( maxVersion > JAVA_1_3_CLASS_VERSION )
157 {
158 classes.setJdkRevision( "1.3" );
159 }
160 else if ( maxVersion > JAVA_1_2_CLASS_VERSION )
161 {
162 classes.setJdkRevision( "1.2" );
163 }
164 else if ( maxVersion > JAVA_1_1_CLASS_VERSION )
165 {
166 classes.setJdkRevision( "1.1" );
167 }
168 else if ( maxVersion > 0 )
169 {
170 classes.setJdkRevision( "1.0" );
171 }
172
173 jarAnalyzer.getJarData().setJarClasses( classes );
174 }
175 return classes;
176 }
177
178 private boolean hasDebugSymbols( JavaClass javaClass )
179 {
180 boolean ret = false;
181 Method[] methods = javaClass.getMethods();
182 for ( int i = 0; i < methods.length; i++ )
183 {
184 LineNumberTable linenumbers = methods[i].getLineNumberTable();
185 if ( linenumbers != null && linenumbers.getLength() > 0 )
186 {
187 ret = true;
188 break;
189 }
190 }
191 return ret;
192 }
193 }