1 15 package org.apache.hivemind.lib.impl; 16 17 import java.lang.reflect.Constructor ; 18 import java.lang.reflect.Modifier ; 19 import java.rmi.RemoteException ; 20 21 import org.apache.hivemind.ApplicationRuntimeException; 22 import org.apache.hivemind.ServiceImplementationFactory; 23 import org.apache.hivemind.ServiceImplementationFactoryParameters; 24 import org.apache.hivemind.impl.BaseLocatable; 25 import org.apache.hivemind.internal.Module; 26 import org.apache.hivemind.lib.NameLookup; 27 import org.apache.hivemind.lib.RemoteExceptionCoordinator; 28 import org.apache.hivemind.service.BodyBuilder; 29 import org.apache.hivemind.service.ClassFab; 30 import org.apache.hivemind.service.ClassFabUtils; 31 import org.apache.hivemind.service.ClassFactory; 32 import org.apache.hivemind.service.MethodIterator; 33 import org.apache.hivemind.service.MethodSignature; 34 35 46 public class EJBProxyFactory extends BaseLocatable implements ServiceImplementationFactory 47 { 48 private NameLookup _nameLookup; 49 private RemoteExceptionCoordinator _coordinator; 50 private ClassFactory _classFactory; 51 52 public Object createCoreServiceImplementation(ServiceImplementationFactoryParameters factoryParameters) 53 { 54 EJBProxyParameters proxyParameters = (EJBProxyParameters) factoryParameters.getFirstParameter(); 55 String jndiName = proxyParameters.getJndiName(); 56 String homeInterfaceClassName = proxyParameters.getHomeInterfaceClassName(); 57 58 60 Module module = factoryParameters.getInvokingModule(); 61 Class serviceInterface = factoryParameters.getServiceInterface(); 62 63 Class homeInterface = module.resolveType(homeInterfaceClassName); 64 65 String proxyClassName = ClassFabUtils.generateClassName(serviceInterface); 66 67 ClassFab classFab = 68 _classFactory.newClass( 69 proxyClassName, 70 AbstractEJBProxy.class); 71 72 classFab.addInterface(serviceInterface); 73 74 classFab.addField("_remote", serviceInterface); 75 76 addClearCachedMethod(classFab); 77 78 addLookupMethod(classFab, homeInterface, serviceInterface, jndiName); 79 80 addServiceMethods(classFab, serviceInterface, factoryParameters.getServiceId(), jndiName); 81 82 addConstructor(classFab); 83 84 Class proxyClass = classFab.createClass(); 85 86 return invokeConstructor(proxyClass, proxyParameters.getNameLookup(_nameLookup)); 87 } 88 89 private void addClearCachedMethod(ClassFab classFab) 90 { 91 classFab.addMethod( 92 Modifier.PROTECTED, 93 new MethodSignature(void.class, "_clearCachedReferences", null, null), 94 "_remote = null;"); 95 } 96 97 private void addLookupMethod( 98 ClassFab classFab, 99 Class homeInterface, 100 Class remoteInterface, 101 String jndiName) 102 { 103 String homeInterfaceName = homeInterface.getName(); 104 105 BodyBuilder builder = new BodyBuilder(); 106 107 builder.begin(); 108 109 builder.addln("if (_remote != null)"); 110 builder.addln(" return _remote;"); 111 112 builder.add(homeInterfaceName); 113 builder.add(" home = ("); 114 builder.add(homeInterfaceName); 115 builder.add(") _lookup("); 116 builder.addQuoted(jndiName); 117 builder.addln(");"); 118 119 builder.add("try"); 120 builder.begin(); 121 builder.add("_remote = home.create();"); 122 builder.end(); 123 builder.add("catch (javax.ejb.CreateException ex)"); 124 builder.begin(); 125 builder.add("throw new java.rmi.RemoteException(ex.getMessage(), ex);"); 126 builder.end(); 127 128 builder.add("return _remote;"); 129 130 builder.end(); 131 132 classFab.addMethod( 133 Modifier.SYNCHRONIZED + Modifier.PRIVATE, 134 new MethodSignature( 135 remoteInterface, 136 "_lookupRemote", 137 null, 138 new Class [] { RemoteException .class }), 139 builder.toString()); 140 141 } 142 143 private void addServiceMethods( 144 ClassFab classFab, 145 Class serviceInterface, 146 String serviceId, 147 String jndiName) 148 { 149 MethodIterator mi = new MethodIterator(serviceInterface); 150 151 while (mi.hasNext()) 152 { 153 addServiceMethod(classFab, mi.next()); 154 } 155 156 if (!mi.getToString()) 157 addToStringMethod(classFab, serviceInterface, serviceId, jndiName); 158 } 159 160 private void addServiceMethod(ClassFab classFab, MethodSignature sig) 161 { 162 String methodName = sig.getName(); 163 164 boolean isVoid = sig.getReturnType().equals(Void.TYPE); 165 166 BodyBuilder builder = new BodyBuilder(); 167 168 builder.begin(); 169 170 builder.addln("boolean first = true;"); 171 builder.add("while (true)"); 172 builder.begin(); 173 174 builder.add("try"); 175 builder.begin(); 176 177 if (!isVoid) 178 builder.add("return "); 179 180 builder.add("_lookupRemote()."); 181 builder.add(methodName); 182 builder.addln("($$);"); 183 184 if (isVoid) 185 builder.addln("return;"); 186 187 builder.end(); 189 builder.add("catch (java.rmi.RemoteException ex)"); 190 builder.begin(); 191 192 builder.addln("if (first)"); 193 builder.begin(); 194 195 builder.addln("_handleRemoteException(ex);"); 196 builder.addln("first = false;"); 197 198 builder.end(); builder.addln("else"); 200 builder.add(" throw ex;"); 201 builder.end(); builder.end(); builder.end(); 204 205 classFab.addMethod(Modifier.PUBLIC, sig, builder.toString()); 206 } 207 208 private void addToStringMethod( 209 ClassFab classFab, 210 Class serviceInterface, 211 String serviceId, 212 String jndiName) 213 { 214 ClassFabUtils.addToStringMethod( 215 classFab, 216 ImplMessages.ejbProxyDescription(serviceId, serviceInterface, jndiName)); 217 } 218 219 private void addConstructor(ClassFab classFab) 220 { 221 classFab.addConstructor( 222 new Class [] { NameLookup.class, RemoteExceptionCoordinator.class }, 223 null, 224 "super($1, $2);"); 225 } 226 227 private Object invokeConstructor(Class proxyClass, NameLookup nameLookup) 228 { 229 try 230 { 231 Constructor c = 232 proxyClass.getConstructor( 233 new Class [] { NameLookup.class, RemoteExceptionCoordinator.class }); 234 235 return c.newInstance(new Object [] { nameLookup, _coordinator }); 236 } 237 catch (Exception ex) 238 { 239 throw new ApplicationRuntimeException(ex); 240 } 241 } 242 243 public void setClassFactory(ClassFactory factory) 244 { 245 _classFactory = factory; 246 } 247 248 public void setCoordinator(RemoteExceptionCoordinator coordinator) 249 { 250 _coordinator = coordinator; 251 } 252 253 public void setNameLookup(NameLookup lookup) 254 { 255 _nameLookup = lookup; 256 } 257 258 } 259 | Popular Tags |