KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > lib > impl > EJBProxyFactory


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.hivemind.lib.impl;
16
17 import java.lang.reflect.Constructor JavaDoc;
18 import java.lang.reflect.Modifier JavaDoc;
19 import java.rmi.RemoteException JavaDoc;
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  * An implementation of {@link org.apache.hivemind.ServiceImplementationFactory}
37  * that can create a proxy to a stateless session EJB. Using this factory, it is
38  * easy to create a HiveMind service wrapper around the actual EJB.
39  *
40  * <p>
41  * The parameters for the factory are used to identify the JNDI name of the
42  * session EJB's home interface.
43  *
44  * @author Howard Lewis Ship
45  */

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 JavaDoc createCoreServiceImplementation(ServiceImplementationFactoryParameters factoryParameters)
53     {
54         EJBProxyParameters proxyParameters = (EJBProxyParameters) factoryParameters.getFirstParameter();
55         String JavaDoc jndiName = proxyParameters.getJndiName();
56         String JavaDoc homeInterfaceClassName = proxyParameters.getHomeInterfaceClassName();
57
58         // The service interface is the remote interface.
59

60         Module module = factoryParameters.getInvokingModule();
61         Class JavaDoc serviceInterface = factoryParameters.getServiceInterface();
62         
63         Class JavaDoc homeInterface = module.resolveType(homeInterfaceClassName);
64
65         String JavaDoc 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 JavaDoc 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 JavaDoc homeInterface,
100         Class JavaDoc remoteInterface,
101         String JavaDoc jndiName)
102     {
103         String JavaDoc 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 JavaDoc[] { RemoteException JavaDoc.class }),
139             builder.toString());
140
141     }
142
143     private void addServiceMethods(
144         ClassFab classFab,
145         Class JavaDoc serviceInterface,
146         String JavaDoc serviceId,
147         String JavaDoc 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 JavaDoc 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(); // try
188

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(); // if
199
builder.addln("else");
200         builder.add(" throw ex;");
201         builder.end(); // catch
202
builder.end(); // while
203
builder.end();
204
205         classFab.addMethod(Modifier.PUBLIC, sig, builder.toString());
206     }
207
208     private void addToStringMethod(
209         ClassFab classFab,
210         Class JavaDoc serviceInterface,
211         String JavaDoc serviceId,
212         String JavaDoc 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 JavaDoc[] { NameLookup.class, RemoteExceptionCoordinator.class },
223             null,
224             "super($1, $2);");
225     }
226
227     private Object JavaDoc invokeConstructor(Class JavaDoc proxyClass, NameLookup nameLookup)
228     {
229         try
230         {
231             Constructor JavaDoc c =
232                 proxyClass.getConstructor(
233                     new Class JavaDoc[] { NameLookup.class, RemoteExceptionCoordinator.class });
234
235             return c.newInstance(new Object JavaDoc[] { nameLookup, _coordinator });
236         }
237         catch (Exception JavaDoc 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