/* * Created on Oct 14, 2005 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package fr.lifl.stc.stan.classAnnoter; import java.io.IOException; import org.apache.bcel.classfile.Attribute; import org.apache.bcel.classfile.ExactLinkAttribute; import org.apache.bcel.classfile.GlobalLinkAttribute; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; import org.apache.bcel.generic.ConstantPoolGen; import fr.lifl.stc.stan.analyser.Config; import fr.lifl.stc.stan.samples.flow.FlowAnnotation; import fr.lifl.stc.stan.samples.flow.FlowPartialSignature; import fr.lifl.stc.stan.samples.flow.FlowPartialSignatureData; import fr.lifl.stc.stan.signature.Signature; import fr.lifl.stc.stan.signature.SignatureDictionary; /** * @author dorina * * Annotates a .class file with its exact and global signatures. */ public class LinkMapClassAnnoter { private JavaClass cl; private String classfile = null; private SignatureDictionary dict = null; private ConstantPoolGen cpg = null; private int link_index; private int global_link_index; private String output = null; public LinkMapClassAnnoter(JavaClass cl, SignatureDictionary dict) { this.cl = cl; this.classfile = cl.getFileName(); //cl. this.output = Config.annotationRep()+cl.getClassName().replace('.','/')+".class"; //+ this.classfile; this.dict = dict; this.prepareConstantPool(); } private void prepareConstantPool() { cpg = new ConstantPoolGen(cl.getConstantPool()); link_index = cpg.addUtf8("LinkMap"); global_link_index = cpg.addUtf8("GlobalLinkMap"); cl.setConstantPool(cpg.getFinalConstantPool()); } public void annotateClass() throws IOException { Method[] methods = cl.getMethods(); for(int i = 0; i < methods.length; i++) { //if(methods[i].isAbstract() || methods[i].isNative()) // continue; //Printer.println(SignatureDictionary.key(cl,methods[i])); Signature sign = dict.findExactSignature(SignatureDictionary.key(cl,methods[i])); if (sign == null) { System.err.println("Unknown method in " + cl.getClassName() + ": " + methods[i]); //continue; } else annotateExactLink (methods[i], sign); sign = dict.findGlobalSignature(SignatureDictionary.key(cl,methods[i])); if (sign == null) { System.err.println("Unknown method in " + cl.getClassName() + ": " + methods[i]); //continue; } else { annotateGlobalLink (methods[i], sign); } } String newname = (output == null)?classfile:output; //Printer.println("dump to "+newname); System.out.println("dump to "+newname); cl.dump(newname); } /** * * @param cl * @param meth * @param sign */ private void annotateExactLink(Method meth, Signature sign) { FlowPartialSignature link = (FlowPartialSignature) sign .getPartialSignature(FlowAnnotation.class.getName()); //System.out.println("annotate sign = "+sign); if (link == null) { //System.err.println("Unsigned exact Link method in " + cl.getClassName()+ ": " + meth); return; } //short[] offsets = ((FlowPartialSignatureData)esc.getComponent()).getData(); byte[] byteStream = ((FlowPartialSignatureData) link.getComponent()) .getDataAsBytes(); if (byteStream == null) { //Printer.println("No links in " + meth); return; } Attribute[] orig = null; orig = meth.getAttributes(); if (byteStream.length > 0) { ExactLinkAttribute linkAttr = new ExactLinkAttribute(link_index, byteStream.length, byteStream, cl.getConstantPool()); int j = 0; while (j < orig.length) { if (orig[j] instanceof ExactLinkAttribute) break; j++; } if (j < orig.length) { orig[j] = linkAttr; meth.setAttributes(orig); } else { Attribute[] new_attr = new Attribute[orig.length + 1]; new_attr[0] = linkAttr; System.arraycopy(orig, 0, new_attr, 1, orig.length); meth.setAttributes(new_attr); } } else { //maybe suppress the attribute int j = 0; while (j < orig.length) { if (orig[j] instanceof ExactLinkAttribute) { break; } j++; } if (j < orig.length) { Attribute[] new_attr = new Attribute[orig.length - 1]; if (j > 0) System.arraycopy(orig, 0, new_attr, 0, j); if (j < orig.length - 1) System.arraycopy(orig, j + 1, new_attr, j, orig.length - j - 1); meth.setAttributes(new_attr); } } } /** * * @param cl * @param meth * @param sign */ private void annotateGlobalLink(Method meth, Signature sign) { FlowPartialSignature link = (FlowPartialSignature) sign .getPartialSignature(FlowAnnotation.class.getName()); if (link == null) { //System.err.println("Unsigned global Link method in " + cl.getClassName()+ ": " + meth); return; } //short[] offsets = ((FlowPartialSignatureData)esc.getComponent()).getData(); byte[] byteStream = ((FlowPartialSignatureData) link.getComponent()) .getDataAsBytes(); if (byteStream == null) { //Printer.println("No links in " + meth); return; } Attribute[] orig = null; // if (meth.getCode() != null) // orig = meth.getCode().getAttributes(); // else orig = meth.getAttributes(); if (byteStream.length > 0) { GlobalLinkAttribute linkAttr = new GlobalLinkAttribute(global_link_index, byteStream.length, byteStream, cl.getConstantPool()); // LinkAttribute ea = new LinkAttribute(link_index,2 * offsets.length, offsets, cl.getConstantPool()); int j = 0; while (j < orig.length) { if (orig[j] instanceof GlobalLinkAttribute) break; j++; } if (j < orig.length) { orig[j] = linkAttr; // if (meth.getCode() != null) // meth.getCode().setAttributes(orig); // else meth.setAttributes(orig); } else { Attribute[] new_attr = new Attribute[orig.length + 1]; new_attr[0] = linkAttr; System.arraycopy(orig, 0, new_attr, 1, orig.length); // if (meth.getCode() != null) // meth.getCode().setAttributes(new_attr); // else meth.setAttributes(new_attr); } } else { //maybe suppress the attribute int j = 0; while (j < orig.length) { if (orig[j] instanceof GlobalLinkAttribute) { break; } j++; } if (j < orig.length) { Attribute[] new_attr = new Attribute[orig.length - 1]; if (j > 0) System.arraycopy(orig, 0, new_attr, 0, j); if (j < orig.length - 1) System.arraycopy(orig, j + 1, new_attr, j, orig.length - j - 1); // if (meth.getCode() != null) // meth.getCode().setAttributes(new_attr); // else meth.setAttributes(new_attr); } } } }