1 2 12 package com.versant.core.jdo.tools.enhancer; 13 14 import com.versant.core.jdo.tools.enhancer.utils.*; 15 16 import java.util.*; 17 import java.io.*; 18 import java.net.URL ; 19 20 import com.versant.lib.bcel.classfile.*; 21 import com.versant.lib.bcel.generic.*; 22 import com.versant.lib.bcel.Constants; 23 import com.versant.lib.bcel.*; 24 27 public class FieldRefEnhancer { 28 private ClassLoader loader; 29 private HashMap fieldToEnhanceMap; 30 private ClassGen classGen; 31 private ConstantPoolGen constantPoolGen; 32 private InstructionFactory instructionFactory; 33 private File outputDir; 34 private ArrayList pcList = new ArrayList(); 35 private boolean hasChanges; 36 private static final String GET_FIELD = com.versant.lib.bcel.generic.GETFIELD.class.getName(); 37 private static final String PUT_FIELD = com.versant.lib.bcel.generic.PUTFIELD.class.getName(); 38 private static final String A_LOAD = com.versant.lib.bcel.generic.ALOAD.class.getName(); 39 private static final String D_U_P = com.versant.lib.bcel.generic.DUP.class.getName(); 40 private int aware; 41 private String fileSeparator; 42 private char charfileSeparator; 43 private File currentOutputFile; 44 45 46 public FieldRefEnhancer(File outputDir,ClassLoader loader) { 47 this.outputDir = outputDir; 48 this.loader = loader; 49 fileSeparator = System.getProperty("file.separator"); 50 charfileSeparator = fileSeparator.charAt(0); 51 } 52 53 public void setFieldsToEnhanceMap(HashMap map){ 54 fieldToEnhanceMap = map; 55 } 56 57 public int getAwareNum(){ 58 return aware; 59 } 60 public void setPersistentCapable(String pcClassName){ 61 pcList.add(pcClassName); 62 } 63 64 public void enhance(Set scopeFiles){ 65 if (fieldToEnhanceMap.isEmpty())return; 66 Iterator iter = scopeFiles.iterator(); 67 while (iter.hasNext()){ 68 String fileName = (String )iter.next(); 69 try { 70 hasChanges = false; 71 JavaClass javaClass = getJavaClass(fileName); 72 classGen = new ClassGen(javaClass); 73 if (!pcList.contains(classGen.getClassName())) { 74 constantPoolGen = classGen.getConstantPool(); 76 instructionFactory = new InstructionFactory(constantPoolGen); 78 swapGetterAndSetter(); 79 if (hasChanges){ 80 dumpClass(); 81 aware++; 82 System.out.println("Persistent Aware = " + classGen.getClassName()); 83 } 84 } 85 } catch (Exception e){ 86 e.printStackTrace(); } 88 } 89 } 90 91 92 private JavaClass getJavaClass(String className) throws IOException { 93 InputStream inputStream = loader.getResourceAsStream(className); 94 if (inputStream == null) { 95 if (inputStream == null) { 96 throw new javax.jdo.JDOFatalUserException("Class not found: " + className); 97 } 98 } 99 ClassParser parser = new ClassParser(inputStream, className); 100 return parser.parse(); 101 } 102 103 private void dumpClass() throws VerifyException { 104 String fileName = classGen.getClassName().replace('.', charfileSeparator) + ".class"; 105 File dumpFile; 106 if (outputDir != null) { 107 dumpFile = new File(outputDir, fileName); 108 } else { 109 URL currentFileURL = loader.getResource(fileName); 110 if (currentFileURL.toString().startsWith("jar:")) { 111 throw new javax.jdo.JDOFatalUserException("Can not write file " + fileName + " into a jar. Please specify a output directory."); 112 } 113 currentOutputFile = new File(currentFileURL.getFile()); 114 dumpFile = currentOutputFile; 115 } 116 try { 117 classGen.getJavaClass().dump(dumpFile); 118 } catch (IOException e) { 119 throw new VerifyException(e); 120 } 121 122 } 123 124 125 private void swapGetterAndSetter() { 126 127 Method[] methods = classGen.getMethods(); 129 for (int i = 0; i < methods.length; i++) { 130 Method m = methods[i]; 131 132 if (m.isNative() || m.isAbstract()) { 135 continue; 136 } 137 if (m.getName().startsWith("jdo") || m.getName().startsWith("<c")) { 139 continue; 140 } 141 142 boolean changed = false; 143 144 MethodGen mg = new MethodGen(m, classGen.getClassName(), constantPoolGen); 145 146 InstructionList il = mg.getInstructionList(); 148 149 InstructionHandle ih = il.getStart(); 151 while (ih != null) { 152 Instruction ins = ih.getInstruction(); 153 if (ins.getClass().getName().equals(GET_FIELD)) { GETFIELD is = (GETFIELD) ins; 155 if (!is.getFieldName(constantPoolGen).startsWith("jdo")) { 156 String key = is.getClassName(constantPoolGen) + "|" + is.getFieldName(constantPoolGen); 157 if (fieldToEnhanceMap.containsKey(key)) { 158 SwapFieldHelper helper = (SwapFieldHelper) fieldToEnhanceMap.get(key); 159 ih.setInstruction(instructionFactory.createInvoke( 161 helper.className, 162 helper.jdoGetName, 163 helper.type, 164 new Type[]{ 165 new ObjectType(helper.className) 166 }, 167 Constants.INVOKESTATIC)); 168 il.setPositions(); 169 il.update(); 170 171 changed = true; 172 InstructionHandle prevIhDUP = ih.getPrev(); 173 Instruction iffyDup = prevIhDUP.getInstruction(); 174 if (iffyDup.getClass().getName().equals(D_U_P)) { ih = ih.getPrev(); 176 InstructionHandle prevIhALOAD = ih.getPrev(); 177 Instruction iffyAload = prevIhALOAD.getInstruction(); 178 if (iffyAload.getClass().getName().equals(A_LOAD)) { ALOAD aLoad = (ALOAD) iffyAload; 180 ih.setInstruction(aLoad); il.setPositions(); 182 il.update(); 183 } else { 184 ih = ih.getNext(); 185 } 186 } 187 } 188 } 189 } else if (ins.getClass().getName().equals(PUT_FIELD)) { 190 PUTFIELD is = (PUTFIELD) ins; 191 if (!is.getFieldName(constantPoolGen).startsWith("jdo")) { 192 String key = is.getClassName(constantPoolGen) + "|" + is.getFieldName(constantPoolGen); 193 if (fieldToEnhanceMap.containsKey(key)) { 194 SwapFieldHelper helper = (SwapFieldHelper) fieldToEnhanceMap.get(key); 195 ih.setInstruction(instructionFactory.createInvoke( 197 helper.className, 198 helper.jdoSetName, 199 Type.VOID, 200 new Type[]{ 201 new ObjectType(helper.className), 202 helper.type 203 }, 204 Constants.INVOKESTATIC)); 205 il.setPositions(); 206 il.update(); 207 changed = true; 208 } 209 } 210 } 211 ih = ih.getNext(); 213 } 214 if (changed) { 215 hasChanges = true; 216 il.setPositions(); 217 il.update(); 218 mg.setMaxLocals(); 219 mg.setMaxStack(); 220 Method method = mg.getMethod(); 221 classGen.replaceMethod(m, method); 222 } 223 } 224 } 225 } 226 | Popular Tags |