OSDN Git Service

update
[stigmata/stigmata-plugins.git] / wsp / src / main / java / jp / sourceforge / stigmata / birthmarks / wsp / StackPatternBasedBirthmarkElement.java
1 package jp.sourceforge.stigmata.birthmarks.wsp;
2
3 /*
4  * $Id$
5  */
6
7 import java.util.ArrayList;
8 import java.util.Collections;
9 import java.util.Iterator;
10 import java.util.List;
11
12 import jp.sourceforge.stigmata.BirthmarkElement;
13 import jp.sourceforge.stigmata.birthmarks.Opcode;
14 import jp.sourceforge.stigmata.birthmarks.OpcodeManager;
15
16 /**
17  *
18  * @author Haruaki TAMADA
19  * @version $Revision$
20  */
21 public class StackPatternBasedBirthmarkElement extends BirthmarkElement implements Iterable<CurrentDepth>{
22     private static final long serialVersionUID = 7965456413167854L;
23
24     private List<CurrentDepth> list = new ArrayList<CurrentDepth>();
25     private int weight = -1;
26
27     public StackPatternBasedBirthmarkElement(CurrentDepth[] depthArray){
28         super(getStringRepresentation(depthArray));
29         for(CurrentDepth depth: depthArray){
30             list.add(depth);
31         }
32     }
33     public StackPatternBasedBirthmarkElement(String value){
34         super(value);
35         String[] depthList = value.split(", ");
36         for(int i = 0; i < depthList.length; i++){
37             String[] depthStringArray = depthList[i].split(":");
38             if(depthStringArray.length == 4){
39                 int opcode = Integer.parseInt(depthStringArray[0]);
40                 int depth = Integer.parseInt(depthStringArray[1]);
41                 int weight = Integer.parseInt(depthStringArray[2]);
42                 int act = Integer.parseInt(depthStringArray[3]);
43
44                 WSPOpcode o = new WSPOpcode(OpcodeManager.getInstance().getOpcode(opcode), weight);
45                 if(o.getCategory() == Opcode.Category.OBJECT || o.getCategory() == Opcode.Category.INVOKE){
46                     o.setAct(act);
47                 }
48                 list.add(new CurrentDepth(depth, o));
49             }
50         }
51     }
52
53     public int getLength(){
54         return list.size();
55     }
56
57     public CurrentDepth getDepth(int index){
58         return list.get(index);
59     }
60
61     public Iterator<CurrentDepth> iterator(){
62         return Collections.unmodifiableList(list).iterator();
63     }
64
65     public int getWeight(StackPatternBasedBirthmarkElement element){
66         int[][] matrix = new int[element.getLength() + 1][getLength() + 1];
67
68         for(int i = 0; i <= element.getLength(); i++){
69             for(int j = 0; j <= getLength(); j++){
70                 if(i == 0 || j == 0){
71                     matrix[i][j] = 0;
72                 }
73                 else if(element.getDepth(i - 1).getOpcode().getOpcode() == getDepth(j - 1).getOpcode().getOpcode()){
74                     matrix[i][j] = (int)(matrix[i - 1][j - 1] + getDepth(j - 1).getOpcode().getWeight());
75                 }
76                 else{
77                     matrix[i][j] = Math.max(matrix[i - 1][j], matrix[i][j - 1]);
78                 }
79             }
80         }
81
82         int max = 0;
83         int last = element.getLength();
84         for(int i = 0; i < matrix[last].length; i++){
85             if(matrix[last][i] > max){
86                 max = matrix[last][i];
87             }
88         }
89         return max;
90     }
91
92     public int getWeight(){
93         if(weight < 0){
94             int w = 0;
95             for(CurrentDepth depth: this){
96                 w += depth.getOpcode().getWeight();
97             }
98             this.weight = w;
99         }
100         return weight;
101     }
102
103     private static String getStringRepresentation(CurrentDepth[] depth){
104         StringBuilder builder = new StringBuilder();
105         for(int i = 0; i < depth.length; i++){
106             if(i != 0){
107                 builder.append(", ");
108             }
109             builder.append(depth[i]);
110         }
111         return new String(builder);
112     }
113 }