1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.hivemind.impl.servicemodel; |
16 |
| |
17 |
| import java.lang.reflect.Constructor; |
18 |
| import java.lang.reflect.Modifier; |
19 |
| |
20 |
| import org.apache.hivemind.ApplicationRuntimeException; |
21 |
| import org.apache.hivemind.events.RegistryShutdownListener; |
22 |
| import org.apache.hivemind.impl.ConstructableServicePoint; |
23 |
| import org.apache.hivemind.impl.ProxyBuilder; |
24 |
| import org.apache.hivemind.internal.ServicePoint; |
25 |
| import org.apache.hivemind.service.BodyBuilder; |
26 |
| import org.apache.hivemind.service.ClassFab; |
27 |
| import org.apache.hivemind.service.MethodSignature; |
28 |
| |
29 |
| |
30 |
| |
31 |
| |
32 |
| |
33 |
| |
34 |
| |
35 |
| |
36 |
| public final class SingletonServiceModel extends AbstractServiceModelImpl |
37 |
| { |
38 |
| |
39 |
| |
40 |
| |
41 |
| protected static final String SERVICE_ACCESSOR_METHOD_NAME = "_service"; |
42 |
| |
43 |
| private Object _serviceProxy; |
44 |
| |
45 |
| private SingletonInnerProxy _innerProxy; |
46 |
| |
47 |
| private Object _constructedService; |
48 |
| |
49 |
992
| public SingletonServiceModel(ConstructableServicePoint servicePoint)
|
50 |
| { |
51 |
992
| super(servicePoint);
|
52 |
| } |
53 |
| |
54 |
993
| public synchronized Object getService()
|
55 |
| { |
56 |
993
| if (_serviceProxy == null)
|
57 |
992
| _serviceProxy = createSingletonProxy();
|
58 |
| |
59 |
993
| return _serviceProxy;
|
60 |
| } |
61 |
| |
62 |
| |
63 |
| |
64 |
| |
65 |
496
| public synchronized Object getActualServiceImplementation()
|
66 |
| { |
67 |
496
| if (_constructedService == null)
|
68 |
496
| _constructedService = constructServiceImplementation();
|
69 |
| |
70 |
496
| if( _constructedService instanceof RegistryShutdownListener )
|
71 |
| { |
72 |
4
| getShutdownCoordinatorService().addRegistryShutdownListener( ( RegistryShutdownListener )_constructedService );
|
73 |
| } |
74 |
| |
75 |
| |
76 |
| |
77 |
| |
78 |
| |
79 |
| |
80 |
496
| Class serviceInterface = getServicePoint().getServiceInterface();
|
81 |
| |
82 |
496
| if (!serviceInterface.isInstance(_constructedService))
|
83 |
6
| _constructedService = constructBridgeProxy(_constructedService);
|
84 |
| |
85 |
496
| return _constructedService;
|
86 |
| } |
87 |
| |
88 |
| |
89 |
| |
90 |
| |
91 |
992
| private Object createSingletonProxy()
|
92 |
| { |
93 |
992
| if (_log.isDebugEnabled())
|
94 |
4
| _log.debug("Creating SingletonProxy for service "
|
95 |
| + getServicePoint().getExtensionPointId()); |
96 |
| |
97 |
992
| try
|
98 |
| { |
99 |
| |
100 |
| |
101 |
| |
102 |
| |
103 |
992
| Class proxyClass = createSingletonProxyClass();
|
104 |
| |
105 |
| |
106 |
| |
107 |
| |
108 |
992
| Class innerProxyClass = createInnerProxyClass(proxyClass);
|
109 |
| |
110 |
| |
111 |
| |
112 |
992
| Object result = proxyClass.newInstance();
|
113 |
| |
114 |
| |
115 |
| |
116 |
| |
117 |
992
| Constructor c = innerProxyClass.getConstructor(new Class[]
|
118 |
| { proxyClass, getClass() }); |
119 |
| |
120 |
992
| _innerProxy = (SingletonInnerProxy) c.newInstance(new Object[]
|
121 |
| { result, this }); |
122 |
| |
123 |
992
| getServicePoint().getShutdownCoordinator().addRegistryShutdownListener(
|
124 |
| (RegistryShutdownListener) result); |
125 |
| |
126 |
992
| return result;
|
127 |
| } |
128 |
| catch (Exception ex) |
129 |
| { |
130 |
0
| throw new ApplicationRuntimeException(ex);
|
131 |
| } |
132 |
| |
133 |
| } |
134 |
| |
135 |
| |
136 |
| |
137 |
| |
138 |
| |
139 |
| |
140 |
| |
141 |
992
| private Class createSingletonProxyClass()
|
142 |
| { |
143 |
992
| ConstructableServicePoint servicePoint = getServicePoint();
|
144 |
| |
145 |
992
| ProxyBuilder proxyBuilder = new ProxyBuilder("SingletonProxy", servicePoint, true);
|
146 |
| |
147 |
992
| ClassFab classFab = proxyBuilder.getClassFab();
|
148 |
| |
149 |
992
| Class serviceInterface = servicePoint.getServiceInterface();
|
150 |
| |
151 |
| |
152 |
| |
153 |
| |
154 |
992
| classFab.addField("_inner", serviceInterface);
|
155 |
992
| classFab.addField("_shutdown", boolean.class);
|
156 |
992
| if( !RegistryShutdownListener.class.isAssignableFrom( serviceInterface ) )
|
157 |
| { |
158 |
991
| classFab.addInterface(RegistryShutdownListener.class);
|
159 |
| |
160 |
991
| classFab.addMethod(Modifier.PUBLIC | Modifier.FINAL, new MethodSignature(void.class,
|
161 |
| "registryDidShutdown", null, null), "{ _shutdown = true; }"); |
162 |
| } |
163 |
992
| classFab.addMethod(
|
164 |
| Modifier.PUBLIC | Modifier.SYNCHRONIZED | Modifier.FINAL, |
165 |
| new MethodSignature(void.class, "_setInner", new Class[] |
166 |
| { serviceInterface }, null), |
167 |
| "{ _inner = $1; }"); |
168 |
| |
169 |
992
| BodyBuilder builder = new BodyBuilder();
|
170 |
992
| builder.begin();
|
171 |
992
| builder.addln("if (_shutdown)");
|
172 |
992
| builder.begin();
|
173 |
992
| builder.addln("_inner = null;");
|
174 |
992
| builder.addln("throw org.apache.hivemind.HiveMind#createRegistryShutdownException();");
|
175 |
992
| builder.end();
|
176 |
| |
177 |
992
| builder.addln("return _inner;");
|
178 |
992
| builder.end();
|
179 |
| |
180 |
992
| classFab.addMethod(Modifier.PRIVATE, new MethodSignature(serviceInterface, "_getInner",
|
181 |
| null, null), builder.toString()); |
182 |
| |
183 |
992
| proxyBuilder.addServiceMethods("_getInner()");
|
184 |
| |
185 |
992
| return classFab.createClass();
|
186 |
| } |
187 |
| |
188 |
992
| private Class createInnerProxyClass(Class deferredProxyClass)
|
189 |
| { |
190 |
992
| ServicePoint servicePoint = getServicePoint();
|
191 |
| |
192 |
992
| Class serviceInterface = servicePoint.getServiceInterface();
|
193 |
992
| ProxyBuilder builder = new ProxyBuilder("InnerProxy", servicePoint);
|
194 |
| |
195 |
992
| ClassFab classFab = builder.getClassFab();
|
196 |
| |
197 |
992
| classFab.addField("_deferredProxy", deferredProxyClass);
|
198 |
992
| classFab.addField("_service", serviceInterface);
|
199 |
992
| classFab.addField("_serviceModel", getClass());
|
200 |
| |
201 |
992
| BodyBuilder body = new BodyBuilder();
|
202 |
| |
203 |
| |
204 |
| |
205 |
| |
206 |
992
| body.begin();
|
207 |
| |
208 |
992
| body.addln("super();");
|
209 |
992
| body.addln("_deferredProxy = $1;");
|
210 |
992
| body.addln("_serviceModel = $2;");
|
211 |
992
| body.addln("_deferredProxy._setInner(this);");
|
212 |
| |
213 |
992
| body.end();
|
214 |
| |
215 |
992
| classFab.addConstructor(new Class[]
|
216 |
| { deferredProxyClass, getClass() }, null, body.toString()); |
217 |
| |
218 |
| |
219 |
| |
220 |
| |
221 |
| |
222 |
992
| body.clear();
|
223 |
992
| body.begin();
|
224 |
| |
225 |
992
| body.add("if (_service == null)");
|
226 |
992
| body.begin();
|
227 |
| |
228 |
992
| body.add("_service = (");
|
229 |
992
| body.add(serviceInterface.getName());
|
230 |
992
| body.addln(") _serviceModel.getActualServiceImplementation();");
|
231 |
| |
232 |
992
| body.add("_deferredProxy._setInner(_service);");
|
233 |
| |
234 |
992
| body.end();
|
235 |
| |
236 |
992
| body.add("return _service;");
|
237 |
| |
238 |
992
| body.end();
|
239 |
| |
240 |
992
| classFab.addMethod(
|
241 |
| Modifier.PRIVATE | Modifier.FINAL | Modifier.SYNCHRONIZED, |
242 |
| new MethodSignature(serviceInterface, "_service", null, null), |
243 |
| body.toString()); |
244 |
| |
245 |
992
| builder.addServiceMethods("_service()");
|
246 |
| |
247 |
| |
248 |
| |
249 |
992
| body.clear();
|
250 |
992
| body.begin();
|
251 |
| |
252 |
992
| body.add("_service();");
|
253 |
| |
254 |
992
| body.end();
|
255 |
| |
256 |
992
| classFab.addMethod(Modifier.PUBLIC | Modifier.FINAL, new MethodSignature(void.class,
|
257 |
| "_instantiateServiceImplementation", null, null), body.toString()); |
258 |
| |
259 |
992
| classFab.addInterface(SingletonInnerProxy.class);
|
260 |
| |
261 |
992
| return classFab.createClass();
|
262 |
| } |
263 |
| |
264 |
1
| public void instantiateService()
|
265 |
| { |
266 |
| |
267 |
| |
268 |
1
| getService();
|
269 |
| |
270 |
| |
271 |
| |
272 |
| |
273 |
1
| _innerProxy._instantiateServiceImplementation();
|
274 |
| } |
275 |
| |
276 |
| } |