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