1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.smartlab.web;
24
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.lang.reflect.Proxy;
29 import java.rmi.RemoteException;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.Map;
33 import java.util.TreeMap;
34
35 import javax.ejb.EJBHome;
36 import javax.naming.Context;
37 import javax.naming.InitialContext;
38 import javax.naming.NamingException;
39 import javax.rmi.PortableRemoteObject;
40
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43
44
45
46
47
48
49 public class EnterpriseDomainBuilder extends Domain {
50
51
52
53
54 private final static Log logger = LogFactory.getLog(EnterpriseDomainBuilder.class);
55
56 protected final static Map primitives = new TreeMap();
57 static {
58 primitives.put("boolean", boolean.class);
59 primitives.put("byte", byte.class);
60 primitives.put("short", short.class);
61 primitives.put("int", int.class);
62 primitives.put("long", long.class);
63 primitives.put("float", float.class);
64 primitives.put("double", double.class);
65 primitives.put("char", char.class);
66 }
67
68
69
70
71
72 private final static Map homes = Collections.synchronizedMap(new HashMap());
73
74
75
76
77
78
79
80
81 public static Object getInstance(String name, Class type) {
82 return EnterpriseDomainBuilder.getInstance(name, type, null, null);
83 }
84
85
86
87
88
89
90
91
92 public static Object getInstance(String name, Class type, Object[] params) {
93 return EnterpriseDomainBuilder.getInstance(name, type, null, params);
94 }
95
96
97
98
99
100
101
102
103
104 public static Object getInstance(String name, Class type, Context context) {
105 return EnterpriseDomainBuilder.getInstance(name, type, context, null);
106 }
107
108
109
110
111
112
113
114
115
116
117 public static Object getInstance(String name, Class type, Context context, Object[] params) {
118 HomeWrapper wrapper = (HomeWrapper)homes.get(name);
119 if (wrapper == null) {
120
121 try {
122 if (context == null) {
123 context = new InitialContext();
124 logger.debug("no context specified");
125 }
126 Object home = context.lookup(name);
127 if (home instanceof EJBHome) {
128 home = PortableRemoteObject.narrow(home, EJBHome.class);
129 }
130 wrapper = new HomeWrapper(home);
131 homes.put(name, wrapper);
132 } catch (NamingException ne) {
133 logger.error("lookup(" + name + ") - error", ne);
134 return null;
135 }
136 } else {
137 if (System.currentTimeMillis() - wrapper.getLastCheck() > 60000) {
138 homes.remove(name);
139 }
140 }
141 try {
142 Class[] paramTypes = null;
143 if (params != null) {
144 paramTypes = new Class[params.length];
145 for (int i = 0; i < paramTypes.length; i++) {
146 paramTypes[i] = params[i].getClass();
147 }
148 }
149 Object ejb = wrapper.getHome().getClass().getDeclaredMethod("create", paramTypes).invoke(wrapper.getHome(),
150 params);
151 return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {type},
152 new EnterpriseDomainWrapper(ejb));
153 } catch (Exception e) {
154 homes.remove(name);
155 logger.error("ejb home class instantiation failed", e);
156 return null;
157 }
158 }
159
160
161 private static class EnterpriseDomainWrapper implements InvocationHandler {
162
163
164
165
166 private static final Log logger = LogFactory.getLog(EnterpriseDomain.class);
167
168
169
170
171 private Object ejb;
172
173
174
175
176
177
178
179 private EnterpriseDomainWrapper(Object ejb) {
180 this.ejb = ejb;
181 }
182
183
184
185
186
187 public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
188 if (logger.isDebugEnabled()) {
189 logger.debug("invoke(" + ejb + ", " + method + ", " + params + ")");
190 }
191 Object result = null;
192 try {
193 if (ejb instanceof EnterpriseDomain.Remote) {
194 String[] types = EnterpriseDomainWrapper.getNames(method.getParameterTypes());
195 result = ((EnterpriseDomain.Remote)ejb).execute(method.getName(), params, types, EnterpriseDomain
196 .getContext());
197 } else {
198 result = method.invoke(ejb, params);
199 }
200 } catch (RemoteException re) {
201 if (re.detail instanceof InvocationTargetException) {
202
203 throw ((InvocationTargetException)re.detail).getTargetException();
204 } else {
205
206 throw re;
207 }
208 }
209 if (logger.isDebugEnabled()) {
210 logger.debug("invoke(" + ejb + ", " + method + ", " + params + ") - finish with result=" + result);
211 }
212 return result;
213 }
214
215
216
217
218
219
220
221 private static String[] getNames(Class[] paramTypes) {
222 String[] paramNames = new String[paramTypes.length];
223 for (int i = 0; i < paramTypes.length; i++) {
224 paramNames[i] = paramTypes[i].getName();
225 }
226 return paramNames;
227 }
228 }
229
230 protected static class HomeWrapper {
231
232 private Object home;
233
234 private long lastCheck;
235
236
237 private HomeWrapper(Object home) {
238 this.home = home;
239 this.lastCheck = System.currentTimeMillis();
240 }
241
242 public long getLastCheck() {
243 return lastCheck;
244 }
245
246 public Object getHome() {
247 return home;
248 }
249 }
250 }