1 29 30 package com.caucho.loader.enhancer; 31 32 import com.caucho.bytecode.ByteCodeParser; 33 import com.caucho.bytecode.JavaClass; 34 import com.caucho.bytecode.JavaField; 35 import com.caucho.bytecode.JavaMethod; 36 import com.caucho.java.WorkDir; 37 import com.caucho.java.gen.JavaClassGenerator; 38 import com.caucho.util.L10N; 39 import com.caucho.vfs.JarPath; 40 import com.caucho.vfs.Path; 41 import com.caucho.vfs.ReadStream; 42 import com.caucho.vfs.Vfs; 43 import com.caucho.vfs.WriteStream; 44 45 import java.net.URL ; 46 import java.util.ArrayList ; 47 import java.util.logging.Level ; 48 import java.util.logging.Logger ; 49 50 53 public class EnhancerPrepare { 54 private static final L10N L = new L10N(EnhancerPrepare.class); 55 private static final Logger log = 56 Logger.getLogger(EnhancerPrepare.class.getName()); 57 58 private static final int ACC_PUBLIC = 0x1; 59 private static final int ACC_PRIVATE = 0x2; 60 private static final int ACC_PROTECTED = 0x4; 61 62 private JavaClassGenerator _javaGen = new JavaClassGenerator(); 63 64 private ClassLoader _loader; 65 66 private Path _workPath; 67 68 private ArrayList <ClassEnhancer> _enhancerList = 69 new ArrayList <ClassEnhancer>(); 70 71 private String _baseSuffix = ""; 72 private String _extSuffix = "__ResinExt"; 73 74 private boolean _isParentStarted; 75 76 79 public void setClassLoader(ClassLoader loader) 80 { 81 _loader = loader; 82 } 83 84 87 public Path getWorkPath() 88 { 89 if (_workPath != null) 90 return _workPath; 91 else 92 return WorkDir.getLocalWorkDir(_loader); 93 } 94 95 98 public void setWorkPath(Path workPath) 99 { 100 _workPath = workPath; 101 } 102 103 106 public final Path getPreWorkPath() 107 { 108 return getWorkPath().lookup("pre-enhance"); 109 } 110 111 114 public final Path getPostWorkPath() 115 { 116 return getWorkPath().lookup("post-enhance"); 117 } 118 119 122 public void addEnhancer(ClassEnhancer enhancer) 123 { 124 _enhancerList.add(enhancer); 125 } 126 127 130 public void renameClass(String sourceClass, String targetClass) 131 { 132 Path source = getSource(sourceClass); 133 134 if (source == null || source.getLastModified() <= 0) 135 return; 136 137 Path path = getPreWorkPath(); 138 Path target = path.lookup(targetClass.replace('.', '/') + ".class"); 139 140 if (target.getLastModified() <= 0 || 141 target.getLastModified() < source.getLastModified()) { 142 try { 143 target.remove(); 144 } catch (Throwable e) { 145 log.log(Level.WARNING, e.toString(), e); 146 } 147 148 try { 149 ByteCodeParser parser = new ByteCodeParser(); 150 ReadStream is = source.openRead(); 151 WriteStream os = null; 152 153 try { 154 JavaClass cl = parser.parse(is); 155 156 String cpOldName = sourceClass.replace('.', '/'); 157 String cpClassName = targetClass.replace('.', '/'); 158 159 int utf8Index = cl.getConstantPool().addUTF8(cpClassName).getIndex(); 160 cl.getConstantPool().getClass(cpOldName).setNameIndex(utf8Index); 161 162 cl.setThisClass(cpClassName); 163 164 166 ArrayList <JavaField> fields = cl.getFieldList(); 168 for (int i = 0; i < fields.size(); i++) { 169 JavaField field = fields.get(i); 170 171 int accessFlags = field.getAccessFlags(); 172 173 if ((accessFlags & ACC_PRIVATE) != 0) { 174 accessFlags = (accessFlags & ~ ACC_PRIVATE) | ACC_PROTECTED; 175 field.setAccessFlags(accessFlags); 176 } 177 } 178 179 ArrayList <JavaMethod> methods = cl.getMethodList(); 181 for (int i = 0; i < methods.size(); i++) { 182 JavaMethod method = methods.get(i); 183 184 int accessFlags = method.getAccessFlags(); 185 186 if ((accessFlags & ACC_PRIVATE) != 0) { 187 accessFlags = (accessFlags & ~ ACC_PRIVATE) | ACC_PROTECTED; 188 method.setAccessFlags(accessFlags); 189 } 190 } 191 192 for (int i = 0; i < _enhancerList.size(); i++) { 193 _enhancerList.get(i).preEnhance(cl); 194 } 195 196 target.getParent().mkdirs(); 197 198 os = target.openWrite(); 199 200 cl.write(os); 201 } finally { 202 if (is != null) 203 is.close(); 204 205 if (os != null) 206 os.close(); 207 } 208 } catch (Exception e) { 209 log.log(Level.WARNING, e.toString(), e); 210 211 } 212 } 213 } 214 215 private Path getSource(String className) 216 { 217 ClassLoader loader = _loader; 218 if (loader == null) 219 loader = Thread.currentThread().getContextClassLoader(); 220 221 URL url = loader.getResource(className.replace('.', '/') + ".class"); 222 223 String s = url.toString(); 225 int index = s.indexOf("jar!/"); 226 if (index > 0) { 227 s = s.substring(9, index+3); 228 Path path = JarPath.create(Vfs.lookup(s)); 229 path = path.lookup(className.replace('.', '/') + ".class"); 230 return path; 231 } 232 233 if (url != null) 234 return Vfs.lookup(url.toString()); 235 else 236 return null; 237 } 238 239 242 protected JavaClass renameClass(JavaClass jClass, String targetClass) 243 { 244 String cpOldName = jClass.getThisClass(); 245 String cpClassName = targetClass.replace('.', '/'); 246 247 int utf8Index = jClass.getConstantPool().addUTF8(cpClassName).getIndex(); 248 jClass.getConstantPool().getClass(cpOldName).setNameIndex(utf8Index); 249 250 jClass.setThisClass(cpClassName); 251 252 254 ArrayList <JavaField> fields = jClass.getFieldList(); 256 for (int i = 0; i < fields.size(); i++) { 257 JavaField field = fields.get(i); 258 259 int accessFlags = field.getAccessFlags(); 260 261 if ((accessFlags & ACC_PRIVATE) != 0) { 262 accessFlags = (accessFlags & ~ ACC_PRIVATE) | ACC_PROTECTED; 263 field.setAccessFlags(accessFlags); 264 } 265 } 266 267 ArrayList <JavaMethod> methods = jClass.getMethodList(); 269 for (int i = 0; i < methods.size(); i++) { 270 JavaMethod method = methods.get(i); 271 272 int accessFlags = method.getAccessFlags(); 273 274 if ((accessFlags & ACC_PRIVATE) != 0) { 275 accessFlags = (accessFlags & ~ ACC_PRIVATE) | ACC_PROTECTED; 276 method.setAccessFlags(accessFlags); 277 } 278 } 279 280 return jClass; 281 } 282 } 283 | Popular Tags |