OSDN Git Service

update
[stigmata/stigmata-plugins.git] / wsp / src / main / java / jp / sourceforge / stigmata / birthmarks / wsp / StackPatternBasedBirthmarkExtractor.java
index 8cb1f43..af08551 100644 (file)
@@ -6,99 +6,95 @@ package jp.sourceforge.stigmata.birthmarks.wsp;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import jp.sourceforge.stigmata.Birthmark;
+import jp.sourceforge.stigmata.BirthmarkContext;
 import jp.sourceforge.stigmata.BirthmarkElement;
-import jp.sourceforge.stigmata.BirthmarkEnvironment;
 import jp.sourceforge.stigmata.ExtractionUnit;
 import jp.sourceforge.stigmata.birthmarks.ASMBirthmarkExtractor;
+import jp.sourceforge.stigmata.birthmarks.BirthmarkElementBuilder;
 import jp.sourceforge.stigmata.birthmarks.BirthmarkExtractVisitor;
+import jp.sourceforge.stigmata.birthmarks.LabelOpcode;
+import jp.sourceforge.stigmata.birthmarks.Opcode;
+import jp.sourceforge.stigmata.birthmarks.OpcodeExtractVisitor;
 import jp.sourceforge.stigmata.spi.BirthmarkSpi;
 
 import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
 
 /**
- * 
+ *
  * @author Haruaki Tamada
  * @version $Revision$
  */
 public class StackPatternBasedBirthmarkExtractor extends ASMBirthmarkExtractor{
-
-    @Override
-    public BirthmarkExtractVisitor createExtractVisitor(ClassWriter writer, Birthmark birthmark, BirthmarkEnvironment environment){
-        return new Visitor(writer, birthmark, environment);
-    }
-
     public StackPatternBasedBirthmarkExtractor(BirthmarkSpi service){
         super(service);
     }
 
     @Override
+    public BirthmarkExtractVisitor createExtractVisitor(ClassVisitor visitor, Birthmark birthmark, BirthmarkContext context){
+        return new OpcodeExtractVisitor(visitor, birthmark, context, new WSPBirthmarkElementBuilder());
+    }
+
+    @Override
     public ExtractionUnit[] getAcceptableUnits(){
         return new ExtractionUnit[] {
-            ExtractionUnit.ARCHIVE, ExtractionUnit.PACKAGE, ExtractionUnit.CLASS,
+            ExtractionUnit.CLASS,
         };
     }
 
-    private BirthmarkElement[] buildElement(List<Opcode> opcodes){
-        List<BirthmarkElement> elements = new ArrayList<BirthmarkElement>();
-        Map<Label, Integer> tableMap = new HashMap<Label, Integer>();
-
-        int currentDepth = 0;
-        for(Opcode opcode: opcodes){
-            Integer forwardedStatus = null;
-            if(opcode.getCategory() != Opcode.Category.TARGETER){
-                forwardedStatus = tableMap.get(((LabelOpcode)opcode).getLabel());
-            }
-            if(forwardedStatus == null){
-                currentDepth += opcode.getAct();
-            }
-            else{
-                currentDepth = forwardedStatus + opcode.getAct(); 
-            }
-            if(opcode.getCategory() == Opcode.Category.BRANCH){
-                for(Iterator<Label> i = opcode.labels(); i.hasNext(); ){
-                    Label label = i.next();
-                    tableMap.put(label, currentDepth);
+    private static class WSPBirthmarkElementBuilder implements BirthmarkElementBuilder{
+        public BirthmarkElement[] buildElements(List<Opcode> opcodes, BirthmarkContext context){
+            List<CurrentDepth> pattern = buildStackPattern(opcodes, context);
+            List<BirthmarkElement> elements = new ArrayList<BirthmarkElement>();
+
+            List<CurrentDepth> subPattern = new ArrayList<CurrentDepth>();
+            for(CurrentDepth depth: pattern){
+                subPattern.add(depth);
+                if(depth.getDepth() == 0){
+                    elements.add(new StackPatternBasedBirthmarkElement(subPattern.toArray(new CurrentDepth[subPattern.size()])));
+                    subPattern.clear();
                 }
             }
-        }
-
-        return elements.toArray(new BirthmarkElement[elements.size()]);
-    }
+            elements.add(new StackPatternBasedBirthmarkElement(subPattern.toArray(new CurrentDepth[subPattern.size()])));
 
-    private class Visitor extends BirthmarkExtractVisitor{
-        public Visitor(ClassVisitor visitor, Birthmark birthmark, BirthmarkEnvironment environment){
-            super(visitor, birthmark, environment);
+            return elements.toArray(new BirthmarkElement[elements.size()]);
         }
 
-        public void visitEnd(){
-        }
+        @SuppressWarnings("unchecked")
+        private List<CurrentDepth> buildStackPattern(List<Opcode> opcodes, BirthmarkContext context){
+            Map<Label, Integer> tableMap = new HashMap<Label, Integer>();
+            List<CurrentDepth> pattern = new ArrayList<CurrentDepth>();
+            Map<Integer, Integer> weights = (Map<Integer, Integer>)context.getProperty("birthmarks.wsp.weights");
 
-        @Override
-        public MethodVisitor visitMethod(int arg0, String arg1, String arg2, String arg3, String[] arg4){
-            MethodVisitor visitor = super.visitMethod(arg0, arg1, arg2, arg3, arg4);
-            OpcodeExtractionMethodVisitor opcodeVisitor = new OpcodeExtractionMethodVisitor(visitor);
-            opcodeVisitor.addOpcodeExtractionFinishListener(new OpcodeExtractionFinishListener(){
-                @Override
-                public void finishExtractionOpcodes(List<Opcode> opcodes){
-                    BirthmarkElement[] elements = buildElement(opcodes);
+            int currentDepth = 0;
+            Integer forwardedStatus = null;
+            for(Opcode opcode: opcodes){
+                if(opcode.getCategory() == Opcode.Category.TARGETER){
+                    forwardedStatus = tableMap.get(((LabelOpcode)opcode).getLabel());
+                }
+                else{
+                    WSPOpcode wspOpcode = new WSPOpcode(opcode, weights.get(opcode.getOpcode()));
+                    if(forwardedStatus == null){
+                        currentDepth += opcode.getAct();
+                    }
+                    else{
+                        currentDepth = forwardedStatus + opcode.getAct();
+                    }
+                    forwardedStatus = null;
 
-                    for(BirthmarkElement be: elements){
-                        addElement(be);
+                    pattern.add(new CurrentDepth(currentDepth, wspOpcode));
+                    if(opcode.getCategory() == Opcode.Category.BRANCH){
+                        for(Label label: opcode.getLabels()){
+                            tableMap.put(label, currentDepth);
+                        }
                     }
                 }
-            });
-
-            return opcodeVisitor;
+            }
+            return pattern;
         }
     };
-
-
 }