View Javadoc
1 package attrib4j.cfparse; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.DataOutputStream; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.ObjectOutputStream; 9 import java.net.URLClassLoader; 10 import java.util.Arrays; 11 12 import attrib4j.AttributeException; 13 import attrib4j.ClassAnnotator; 14 15 import com.ibm.toad.cfparse.ClassFile; 16 import com.ibm.toad.cfparse.FieldInfo; 17 import com.ibm.toad.cfparse.FieldInfoList; 18 import com.ibm.toad.cfparse.MethodInfo; 19 import com.ibm.toad.cfparse.MethodInfoList; 20 import com.ibm.toad.cfparse.attributes.AttrInfoList; 21 import com.ibm.toad.cfparse.utils.CFUtils; 22 import com.sun.javadoc.MethodDoc; 23 24 /*** 25 * The CFParse implementation of a ClassAnnotator. This class will use 26 * the CFParse API to insert attributes into .class files. 27 * 28 * @author <a href="mailto:mpollack@speakeasy.net">Mark Pollack</a> 29 * @author Ted Neward 30 * @version $Revision: 1.5 $ $Date: 2003/09/01 19:56:16 $ 31 * 32 */ 33 public class CFParseClassAnnotator implements ClassAnnotator { 34 35 ClassFile _cf; 36 MethodInfoList _mil; 37 FieldInfoList _fil; 38 39 /*** 40 * Create the instance using an InputStream initialized to the 41 * class file that will be modified/annotated. 42 * 43 * @param InputStream initialized with .class file. 44 * @exception AttributeException if an error occurs 45 */ 46 public CFParseClassAnnotator(InputStream classFile) 47 throws AttributeException { 48 49 try { 50 _cf = new ClassFile(classFile); 51 _mil = _cf.getMethods(); 52 _fil = _cf.getFields(); 53 } catch (IOException e) { 54 new AttributeException("Could not create CFParseClassAnnotator", e); 55 } 56 } 57 58 /*** 59 * Insert a custom class attribute into the bytecode. 60 * 61 * @param attribute The attribute to be inserted. 62 */ 63 public void insertClassAttribute(Object attribute) { 64 byte[] data = serialize(attribute); 65 66 AttrInfoList ail = _cf.getAttrs(); 67 CFCustomAttrInfo cai = 68 (CFCustomAttrInfo) ail.add("attrib4j.cfparse.CFCustom"); 69 70 cai.setSerializedData(data); 71 } 72 73 /*** 74 * Insert a custom field attribute into the bytecode. 75 * 76 * @param field The name of the field to apply the attribute. 77 * @param attribute The attribute to be inserted. 78 */ 79 public void insertFieldAttribute(String field, Object attribute) { 80 81 byte[] data = serialize(attribute); 82 83 for (int i = 0; i < _fil.length(); i++) { 84 if (_fil.getFieldName(i).equals(field)) { 85 FieldInfo fld = _fil.get(i); 86 AttrInfoList ail = fld.getAttrs(); 87 CFCustomAttrInfo cai = 88 (CFCustomAttrInfo) ail.add("attrib4j.cfparse.CFCustom"); 89 90 cai.setSerializedData(data); 91 92 break; 93 } 94 } 95 } 96 97 /*** 98 * Insert a custom method attribute into the bytecode. 99 * 100 * @param methodDoc The Javadoc metadata class defining the method to 101 * annotate. 102 * @param attribute The attribute to be inserted. 103 */ 104 public void insertMethodAttribute(MethodDoc methodDoc, Object attribute) { 105 String methodName = methodDoc.name(); 106 String[] methodParamTypes = new String[methodDoc.parameters().length]; 107 for (int i = 0; i < methodParamTypes.length; i++) { 108 //TODO: MLP should be qualifiedTypeName in order to accept 109 //params other than from the java.lang package? 110 //what about dimension info? 111 methodParamTypes[i] = methodDoc.parameters()[i].typeName(); 112 } 113 114 byte[] data = serialize(attribute); 115 116 MethodInfo mi = null; 117 for (int i = 0; i < _mil.length(); i++) { 118 mi = _mil.get(i); 119 if (_mil.getMethodName(i).equals(methodName) 120 && Arrays.equals(methodParamTypes, mi.getParams())) { 121 AttrInfoList ail = mi.getAttrs(); 122 CFCustomAttrInfo cai = 123 (CFCustomAttrInfo) ail.add("attrib4j.cfparse.CFCustom"); 124 cai.setSerializedData(data); 125 break; 126 } 127 } 128 } 129 130 /*** 131 * Write out the modified classfile. 132 * 133 * @param destDir The directory where the modified class fiel should be 134 * written. 135 */ 136 public void write(String destDir) { 137 try { 138 String path = destDir + "/" + CFUtils.canonicalize(_cf.getName()); 139 //MLP: TODO: directory needs to exist before... 140 FileOutputStream fout = new FileOutputStream(path); 141 DataOutputStream out = new DataOutputStream(fout); 142 _cf.write(out); 143 fout.close(); 144 } catch (IOException ioEx) { 145 ioEx.printStackTrace(); 146 } 147 } 148 149 /*** 150 * Helper method to serialize an object. 151 * 152 * @param obj The object to serialize. 153 * @return The serialized objects byte representation. 154 */ 155 private byte[] serialize(Object obj) { 156 try { 157 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 158 ObjectOutputStream oos = new ObjectOutputStream(baos); 159 oos.writeObject(obj); 160 return baos.toByteArray(); 161 } catch (IOException ioEx) { 162 return null; 163 } 164 } 165 166 /*** 167 * Just added to avoid compilation error. Will remove CFParse support soon. 168 * @see attrib4j.ClassAnnotator#createAttributeInstance(java.lang.String, java.net.URLClassLoader, java.lang.String[]) 169 */ 170 public Object createAttributeInstance(String text, URLClassLoader classLoader, String[] attributePackages) { 171 // TODO Auto-generated method stub 172 return null; 173 } 174 175 176 }

This page was automatically generated by Maven