1 15 16 package javassist.rmi; 17 18 import javassist.*; 19 import java.lang.reflect.Method ; 20 import java.util.Hashtable ; 21 import javassist.CtMethod.ConstParameter; 22 23 42 public class StubGenerator implements Translator { 43 private static final String fieldImporter = "importer"; 44 private static final String fieldObjectId = "objectId"; 45 private static final String accessorObjectId = "_getObjectId"; 46 private static final String sampleClass = "javassist.rmi.Sample"; 47 48 private ClassPool classPool; 49 private Hashtable proxyClasses; 50 private CtMethod forwardMethod; 51 private CtMethod forwardStaticMethod; 52 53 private CtClass[] proxyConstructorParamTypes; 54 private CtClass[] interfacesForProxy; 55 private CtClass[] exceptionForProxy; 56 57 60 public StubGenerator() { 61 proxyClasses = new Hashtable (); 62 } 63 64 70 public void start(ClassPool pool) throws NotFoundException { 71 classPool = pool; 72 CtClass c = pool.get(sampleClass); 73 forwardMethod = c.getDeclaredMethod("forward"); 74 forwardStaticMethod = c.getDeclaredMethod("forwardStatic"); 75 76 proxyConstructorParamTypes 77 = pool.get(new String [] { "javassist.rmi.ObjectImporter", 78 "int" }); 79 interfacesForProxy 80 = pool.get(new String [] { "java.io.Serializable", 81 "javassist.rmi.Proxy" }); 82 exceptionForProxy 83 = new CtClass[] { pool.get("javassist.rmi.RemoteException") }; 84 } 85 86 91 public void onLoad(ClassPool pool, String classname) {} 92 93 99 public boolean isProxyClass(String name) { 100 return proxyClasses.get(name) != null; 101 } 102 103 112 public synchronized boolean makeProxyClass(Class clazz) 113 throws CannotCompileException, NotFoundException 114 { 115 String classname = clazz.getName(); 116 if (proxyClasses.get(classname) != null) 117 return false; 118 else { 119 CtClass ctclazz = produceProxyClass(classPool.get(classname), 120 clazz); 121 proxyClasses.put(classname, ctclazz); 122 modifySuperclass(ctclazz); 123 return true; 124 } 125 } 126 127 private CtClass produceProxyClass(CtClass orgclass, Class orgRtClass) 128 throws CannotCompileException, NotFoundException 129 { 130 int modify = orgclass.getModifiers(); 131 if (Modifier.isAbstract(modify) || Modifier.isNative(modify) 132 || !Modifier.isPublic(modify)) 133 throw new CannotCompileException(orgclass.getName() 134 + " must be public, non-native, and non-abstract."); 135 136 CtClass proxy = classPool.makeClass(orgclass.getName(), 137 orgclass.getSuperclass()); 138 139 proxy.setInterfaces(interfacesForProxy); 140 141 CtField f 142 = new CtField(classPool.get("javassist.rmi.ObjectImporter"), 143 fieldImporter, proxy); 144 f.setModifiers(Modifier.PRIVATE); 145 proxy.addField(f, CtField.Initializer.byParameter(0)); 146 147 f = new CtField(CtClass.intType, fieldObjectId, proxy); 148 f.setModifiers(Modifier.PRIVATE); 149 proxy.addField(f, CtField.Initializer.byParameter(1)); 150 151 proxy.addMethod(CtNewMethod.getter(accessorObjectId, f)); 152 153 proxy.addConstructor(CtNewConstructor.defaultConstructor(proxy)); 154 CtConstructor cons 155 = CtNewConstructor.skeleton(proxyConstructorParamTypes, 156 null, proxy); 157 proxy.addConstructor(cons); 158 159 try { 160 addMethods(proxy, orgRtClass.getMethods()); 161 return proxy; 162 } 163 catch (SecurityException e) { 164 throw new CannotCompileException(e); 165 } 166 } 167 168 private CtClass toCtClass(Class rtclass) throws NotFoundException { 169 String name; 170 if (!rtclass.isArray()) 171 name = rtclass.getName(); 172 else { 173 StringBuffer sbuf = new StringBuffer (); 174 do { 175 sbuf.append("[]"); 176 rtclass = rtclass.getComponentType(); 177 } while(rtclass.isArray()); 178 sbuf.insert(0, rtclass.getName()); 179 name = sbuf.toString(); 180 } 181 182 return classPool.get(name); 183 } 184 185 private CtClass[] toCtClass(Class [] rtclasses) throws NotFoundException { 186 int n = rtclasses.length; 187 CtClass[] ctclasses = new CtClass[n]; 188 for (int i = 0; i < n; ++i) 189 ctclasses[i] = toCtClass(rtclasses[i]); 190 191 return ctclasses; 192 } 193 194 197 private void addMethods(CtClass proxy, Method [] ms) 198 throws CannotCompileException, NotFoundException 199 { 200 CtMethod wmethod; 201 for (int i = 0; i < ms.length; ++i) { 202 Method m = ms[i]; 203 int mod = m.getModifiers(); 204 if (m.getDeclaringClass() != Object .class 205 && !Modifier.isFinal(mod)) 206 if (Modifier.isPublic(mod)) { 207 CtMethod body; 208 if (Modifier.isStatic(mod)) 209 body = forwardStaticMethod; 210 else 211 body = forwardMethod; 212 213 wmethod 214 = CtNewMethod.wrapped(toCtClass(m.getReturnType()), 215 m.getName(), 216 toCtClass(m.getParameterTypes()), 217 exceptionForProxy, 218 body, 219 ConstParameter.integer(i), 220 proxy); 221 wmethod.setModifiers(mod); 222 proxy.addMethod(wmethod); 223 } 224 else if (!Modifier.isProtected(mod) 225 && !Modifier.isPrivate(mod)) 226 throw new CannotCompileException( 228 "the methods must be public, protected, or private."); 229 } 230 } 231 232 235 private void modifySuperclass(CtClass orgclass) 236 throws CannotCompileException, NotFoundException 237 { 238 CtClass superclazz; 239 for (;; orgclass = superclazz) { 240 superclazz = orgclass.getSuperclass(); 241 if (superclazz == null) 242 break; 243 244 String name = superclazz.getName(); 245 try { 246 superclazz.getDeclaredConstructor(null); 247 break; } 249 catch (NotFoundException e) { 250 } 251 252 superclazz.addConstructor( 253 CtNewConstructor.defaultConstructor(superclazz)); 254 } 255 } 256 } 257 | Popular Tags |