OSDN Git Service

move test case to new opcode extraction library
[stigmata/stigmata-plugins.git] / wsp / src / main / java / jp / sourceforge / stigmata / birthmarks / wsp / OpcodeWeightCalculatePreprocessor.java
1 package jp.sourceforge.stigmata.birthmarks.wsp;
2
3 /*
4  * $Id$
5  */
6
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15
16 import jp.sourceforge.stigmata.BirthmarkContext;
17 import jp.sourceforge.stigmata.birthmarks.AbstractBirthmarkPreprocessor;
18 import jp.sourceforge.stigmata.digger.ClassFileArchive;
19 import jp.sourceforge.stigmata.digger.ClassFileEntry;
20 import jp.sourceforge.stigmata.plugins.Opcode;
21 import jp.sourceforge.stigmata.plugins.OpcodeExtractMethodVisitor;
22 import jp.sourceforge.stigmata.spi.BirthmarkSpi;
23
24 import org.objectweb.asm.ClassAdapter;
25 import org.objectweb.asm.ClassReader;
26 import org.objectweb.asm.ClassWriter;
27 import org.objectweb.asm.MethodVisitor;
28
29 /**
30  *
31  * @author Haruaki Tamada
32  * @version $Revision$
33  */
34 public class OpcodeWeightCalculatePreprocessor extends AbstractBirthmarkPreprocessor{
35     public OpcodeWeightCalculatePreprocessor(BirthmarkSpi spi){
36         super(spi);
37     }
38
39     @Override
40     public void preprocess(ClassFileArchive[] targets, BirthmarkContext context){
41         Map<Integer, Integer> targetMap = new HashMap<Integer, Integer>();
42
43         int classCount = 0;
44         for(ClassFileArchive archive: targets){
45             classCount += readOpcodes(archive, targetMap);
46         }
47
48         Map<Integer, Integer> weights = new HashMap<Integer, Integer>();
49         for(Map.Entry<Integer, Integer> entry: targetMap.entrySet()){
50             int opcode = entry.getKey();
51             Integer count = entry.getValue();
52             int c = 0;
53             if(count != null){
54                 c = count;
55             }
56
57             weights.put(opcode, (int)Math.round(Math.log(classCount / c)));
58         }
59
60         context.putProperty("birthmarks.wsp.weights", weights);
61     }
62
63     private int readOpcodes(ClassFileArchive archive, Map<Integer, Integer> targetMap){
64         int count = 0;
65         for(ClassFileEntry entry: archive){
66             count++;
67             final List<Opcode> opcodes = new ArrayList<Opcode>();
68             try{
69                 InputStream in = entry.getLocation().openStream();
70
71                 ClassReader reader = new ClassReader(in);
72                 ClassWriter writer = new ClassWriter(0);
73                 ClassAdapter opcodeExtractVisitor = new ClassAdapter(writer){
74                     @Override
75                     public MethodVisitor visitMethod(int arg0, String arg1, String arg2, String arg3, String[] arg4){
76                         OpcodeExtractMethodVisitor visitor =
77                             new OpcodeExtractMethodVisitor(super.visitMethod(arg0, arg1, arg2, arg3, arg4), opcodes);
78                         return visitor;
79                     }
80                 };
81                 reader.accept(opcodeExtractVisitor, 0);
82
83                 Set<Integer> set = new HashSet<Integer>();
84                 for(Opcode opcode: opcodes){
85                     if(opcode.getCategory() != Opcode.Category.TARGETER){
86                         set.add(opcode.getOpcode());
87                     }
88                 }
89
90                 for(Integer i: set){
91                     Integer v = targetMap.get(i);
92                     if(v == null){
93                         v = 0;
94                     }
95                     v = v + 1;
96                     targetMap.put(i, v);
97                 }
98             } catch(IOException e){
99             }
100         }
101         return count;
102     }
103 }