Skip to content

Commit ddcb0ef

Browse files
122305122305
authored andcommitted
Handle array type and parse classes files prior using BCEL to get static
structure
1 parent 5a72371 commit ddcb0ef

File tree

10 files changed

+421
-218
lines changed

10 files changed

+421
-218
lines changed

JavaMethodFlowTracer/pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,16 @@
1515
<artifactId>commons-io</artifactId>
1616
<version>2.4</version>
1717
</dependency>
18+
<dependency>
19+
<groupId>org.apache.bcel</groupId>
20+
<artifactId>bcel</artifactId>
21+
<version>5.2</version>
22+
</dependency>
23+
<dependency>
24+
<groupId>commons-lang</groupId>
25+
<artifactId>commons-lang</artifactId>
26+
<version>2.6</version>
27+
</dependency>
28+
1829
</dependencies>
1930
</project>

JavaMethodFlowTracer/src/main/java/com/sample/SourceParser2.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ public static void main(String[] args) throws Exception {
6969

7070
parser.processSrcDir(files, true);
7171
parser.processSrcDir(files, false);
72-
System.out.println("************************************");
73-
System.out.println(ClassStructContainer2.getInstance().toString());
74-
System.out.println("************************************");
72+
//System.out.println("************************************");
73+
//System.out.println(ClassStructContainer2.getInstance().toString());
74+
//System.out.println("************************************");
7575
String methodName = "com.sample.Test.printHello";
7676
parser.printMethodCallTreeForMethod(methodName);
7777
}

JavaMethodFlowTracer/src/main/java/com/sample/base/MethodStruct2.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,7 @@ public String getArgsAsCSSep() {
289289
int i = 1;
290290
buff.append("<");
291291
for(VariableStruct2 var : this.callArgs.values()) {
292-
if(var.getTypePkg() != null) {
293-
buff.append(var.getTypePkg()).append(".");
294-
}
295-
if(var.getType() != null) {
296-
buff.append(var.getType());
297-
}
292+
buff.append(var.getQualifiedNameWithoutVarName());
298293

299294
if(i < this.callArgs.size()) {
300295
buff.append(",");

JavaMethodFlowTracer/src/main/java/com/sample/base/VariableStruct2.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,29 @@ public class VariableStruct2 {
3939
//Should not be null if this is delcared in side method.
4040
MethodStruct2 parentMethod;
4141

42+
boolean arrayVar;
4243

44+
45+
/**
46+
* Gets the arrayVar
47+
*
48+
* @return the arrayVar
49+
*/
50+
public boolean isArrayVar()
51+
{
52+
return arrayVar;
53+
}
54+
55+
/**
56+
* Sets the arrayVar value
57+
*
58+
* @param arrayVar the arrayVar to set
59+
*/
60+
public void setArrayVar(boolean arrayVar)
61+
{
62+
this.arrayVar = arrayVar;
63+
}
64+
4365
/**
4466
* Gets the parent
4567
*
@@ -215,7 +237,9 @@ public String getQualifiedNameWithoutVarName() {
215237
if(this.type != null) {
216238
buff.append(this.type);
217239
}
218-
240+
if(this.arrayVar) {
241+
buff.append("[]");
242+
}
219243
return buff.toString();
220244
}
221245

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
/*
2+
* © 2009-2015 T-Systems International GmbH. All rights reserved
3+
* _______________UTF-8 checked via this umlaut: ü
4+
*/
5+
package com.sample.utils;
6+
7+
import java.io.File;
8+
import java.io.IOException;
9+
import java.net.URI;
10+
import java.util.Arrays;
11+
import java.util.Enumeration;
12+
import java.util.HashMap;
13+
import java.util.List;
14+
import java.util.Map;
15+
import java.util.jar.JarEntry;
16+
import java.util.jar.JarFile;
17+
18+
import org.apache.bcel.classfile.ClassParser;
19+
import org.apache.bcel.classfile.Field;
20+
import org.apache.bcel.classfile.JavaClass;
21+
import org.apache.bcel.classfile.Method;
22+
import org.apache.bcel.classfile.Utility;
23+
import org.apache.bcel.generic.ClassGen;
24+
import org.apache.commons.io.FileUtils;
25+
import org.apache.commons.lang.RandomStringUtils;
26+
27+
import com.sample.base.ClassOrInterfaceStruct2;
28+
import com.sample.base.MethodStruct2;
29+
import com.sample.base.VariableStruct2;
30+
import com.sample.containers.ClassStructContainer2;
31+
32+
/**
33+
* TODO Small and simple description of the type
34+
*
35+
* @copyright © 2009-2015 T-Systems International GmbH. All rights reserved
36+
* @author 122305
37+
*
38+
* @changes May 25, 2015: Created
39+
*
40+
*/
41+
public class ClassFileReader {
42+
43+
public static Map<String, ClassGen> classes = new HashMap<String, ClassGen>();
44+
45+
public static void parseJarClasses()
46+
{
47+
try {
48+
List<String> libJars = FileUtils.readLines(new File("libjars.txt"));
49+
50+
if ( libJars != null && !libJars.isEmpty() ) {
51+
for ( String jarFile : libJars ) {
52+
parse(jarFile);
53+
}
54+
}
55+
}
56+
catch ( IOException e ) {
57+
e.printStackTrace();
58+
}
59+
}
60+
61+
public static void parse(String jarFilePath)
62+
{
63+
try {
64+
System.out.println("Parsing jar file " + jarFilePath);
65+
JarFile theJar = new JarFile(new File(new URI(jarFilePath)));
66+
67+
// it's a jar file.
68+
Enumeration<?> en = theJar.entries();
69+
70+
// This will enumerate over the files in the jar
71+
while ( en.hasMoreElements() ) {
72+
JarEntry entry = (JarEntry)en.nextElement();
73+
74+
// get next entry
75+
if ( entry.getName().endsWith(".class") ) {
76+
parseClassFile(theJar, entry, true);
77+
}
78+
}
79+
theJar.close();
80+
}
81+
catch ( Exception e ) {
82+
e.printStackTrace();
83+
}
84+
}
85+
86+
public static void parseClassFile(JarFile theJar, JarEntry entry, boolean storeCompiled) throws IOException {
87+
88+
System.out.println("***********Parsing start for class " + entry.getName() + "**************");
89+
// check if entry is a class file and parse it using a class parser.
90+
ClassParser cp = new ClassParser(
91+
theJar.getInputStream(entry), entry.getName());
92+
JavaClass jc = cp.parse();
93+
94+
// gets the bcel classgen of the class.
95+
ClassGen cg = new ClassGen(jc);
96+
parseClassGen(cg);
97+
98+
// put our classes in a hashmap
99+
if(storeCompiled) {
100+
classes.put(cg.getClassName(), cg);
101+
}
102+
System.out.println("***********Parsing complete for class " + entry.getName() + "**************");
103+
104+
}
105+
106+
public static void parseClassGen(ClassGen cg)
107+
{
108+
ClassOrInterfaceStruct2 clazz = new ClassOrInterfaceStruct2();
109+
String classFullName = cg.getClassName();
110+
String[] classNameParts = resolveClassFullNameToParts(classFullName);
111+
clazz.setPkg(classNameParts[0]);
112+
clazz.setName(classNameParts[1]);
113+
114+
clazz.setAbstractClazz(cg.isAbstract());
115+
String superClazzFullName = cg.getSuperclassName();
116+
117+
// Parse super class.
118+
if ( superClazzFullName != null ) {
119+
Map<String, String> superClassMap = new HashMap<String, String>();
120+
String[] superClassNameParts = resolveClassFullNameToParts(superClazzFullName);
121+
superClassMap.put(superClassNameParts[1], superClazzFullName);
122+
clazz.setSuperClasses(superClassMap);
123+
}
124+
125+
// parse interfaces.
126+
String[] interfaceFullNamesArr = cg.getInterfaceNames();
127+
128+
if ( interfaceFullNamesArr != null && interfaceFullNamesArr.length > 0 ) {
129+
Map<String, String> interfacesMap = new HashMap<String, String>();
130+
131+
for ( String interfaceFullName : interfaceFullNamesArr ) {
132+
String[] interfaceNameParts = resolveClassFullNameToParts(interfaceFullName);
133+
interfacesMap.put(interfaceNameParts[1], interfaceFullName);
134+
}
135+
clazz.setInterfacesImplemented(interfacesMap);
136+
}
137+
138+
// parse fields.
139+
Field[] fields = cg.getFields();
140+
if ( fields != null && fields.length > 0 ) {
141+
142+
for ( Field field : fields ) {
143+
VariableStruct2 varStruct = new VariableStruct2();
144+
varStruct.setName(field.getName());
145+
146+
String signature = Utility.signatureToString(field.getSignature());
147+
String[] fieldNameParts = resolveClassFullNameToParts(signature);
148+
varStruct.setTypePkg(fieldNameParts[0]);
149+
varStruct.setType(fieldNameParts[1]);
150+
varStruct.setArrayVar(Boolean.valueOf(fieldNameParts[2]));
151+
clazz.getVariables().put(varStruct.getName(), varStruct);
152+
}
153+
}
154+
155+
// Parse methods.
156+
Method[] methods = cg.getMethods();
157+
158+
if ( methods != null && methods.length > 0 ) {
159+
160+
for ( Method method : methods ) {
161+
MethodStruct2 m_struct = new MethodStruct2();
162+
m_struct.setName(method.getName());
163+
m_struct.setPkg(clazz.getPkg());
164+
m_struct.setClazz(clazz.getName());
165+
m_struct.setParent(clazz);
166+
String m_sig = method.getSignature();
167+
m_struct.setReturnType(Utility.methodSignatureReturnType(m_sig));
168+
String[] m_args = Utility.methodSignatureArgumentTypes(m_sig);
169+
170+
if ( m_args != null && m_args.length > 0 ) {
171+
172+
for ( String m_arg : m_args ) {
173+
VariableStruct2 m_var_struct = new VariableStruct2();
174+
String[] mvarParts = resolveClassFullNameToParts(m_arg);
175+
m_var_struct.setTypePkg(mvarParts[0]);
176+
m_var_struct.setType(mvarParts[1]);
177+
m_var_struct.setArrayVar(Boolean.valueOf(mvarParts[2]));
178+
String randomVarName = RandomStringUtils.randomAlphanumeric(6);
179+
m_var_struct.setName(randomVarName);
180+
m_struct.getCallArgs().put(randomVarName, m_var_struct);
181+
}
182+
}
183+
clazz.getMethods().put(m_struct.getQualifiedNameWithArgs(), m_struct);
184+
}
185+
}
186+
ClassStructContainer2.getInstance().getClasses().put(clazz.getQualifiedName(), clazz);
187+
}
188+
189+
public static String[] resolveClassFullNameToParts(String classFullName)
190+
{
191+
boolean isArray = false;
192+
System.out.println("Resolve classfull name " + classFullName + " into pkg, class name.");
193+
String className = "";
194+
String pkg = "";
195+
196+
if ( LangUtils.isPrimitiveType(classFullName) ) {
197+
className = classFullName;
198+
} else if(LangUtils.isArray(classFullName)) {
199+
200+
className = classFullName;
201+
isArray = true;
202+
//remove array symbol and resolve again
203+
String arrayElem = classFullName.replaceAll("\\[\\]", "");
204+
String temp[] = resolveClassFullNameToParts(arrayElem);
205+
pkg = temp[0];
206+
className = temp[1];
207+
} else if ( classFullName.indexOf(".") > 0 ) {
208+
className = classFullName.substring(classFullName.lastIndexOf(".") + 1, classFullName.length()).trim();
209+
pkg = classFullName.substring(0, classFullName.lastIndexOf("."));
210+
} else {
211+
className = classFullName;
212+
pkg = "java.lang";
213+
}
214+
return new String[] { pkg, className, String.valueOf(isArray) };
215+
}
216+
217+
public static void printInfoOnClass(String className)
218+
{
219+
ClassGen javaClass = classes.get(className);
220+
221+
System.out.println("*******Fields*********");
222+
System.out.println(Arrays.toString(javaClass.getFields()));
223+
System.out.println();
224+
225+
System.out.println("*******Methods*********");
226+
System.out.println(Arrays.toString(javaClass.getMethods()));
227+
228+
for ( Method method : javaClass.getMethods() ) {
229+
System.out.println(method);
230+
System.out.println(method.getCode());
231+
}
232+
233+
System.out.println("******* Interfaces *********");
234+
for ( String interf : javaClass.getInterfaceNames() ) {
235+
System.out.println(interf);
236+
}
237+
238+
System.out.println("******* Superclass *********");
239+
System.out.println(javaClass.getSuperclassName());
240+
241+
}
242+
243+
public static void main(String[] args)
244+
{
245+
246+
parseJarClasses();
247+
//printInfoOnClass("japa.parser.ast.ImportDeclaration");
248+
}
249+
250+
}

0 commit comments

Comments
 (0)