KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > impl > servicemodel > PooledServiceModel


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.impl.servicemodel;
16
17 import java.util.ArrayList JavaDoc;
18 import java.util.List JavaDoc;
19
20 import org.apache.hivemind.ApplicationRuntimeException;
21 import org.apache.hivemind.HiveMind;
22 import org.apache.hivemind.PoolManageable;
23 import org.apache.hivemind.events.RegistryShutdownListener;
24 import org.apache.hivemind.impl.ConstructableServicePoint;
25 import org.apache.hivemind.impl.ProxyUtils;
26 import org.apache.hivemind.internal.Module;
27 import org.apache.hivemind.service.ThreadCleanupListener;
28 import org.apache.hivemind.service.ThreadEventNotifier;
29
30 /**
31  * Similar to the
32  * {@link org.apache.hivemind.impl.servicemodel.ThreadedServiceModel threaded service model},
33  * except that, once created, services are pooled for later use.
34  *
35  * @author Howard Lewis Ship
36  */

37 public class PooledServiceModel extends AbstractServiceModelImpl
38 {
39     /**
40      * Name of a method in the deferred proxy that is used to obtain the constructed service.
41      */

42     protected static final String JavaDoc SERVICE_ACCESSOR_METHOD_NAME = "_service";
43
44     private final Object JavaDoc _serviceProxy;
45
46     private final ThreadEventNotifier _notifier;
47
48     private final ThreadLocal JavaDoc _activeService = new ThreadLocal JavaDoc();
49
50     private final List JavaDoc _servicePool = new ArrayList JavaDoc();
51
52     /** @since 1.1 */
53
54     private Class JavaDoc _serviceInterface;
55
56     /**
57      * Shared, null implementation of PoolManageable.
58      */

59     private static final PoolManageable NULL_MANAGEABLE = new PoolManageable()
60     {
61         public void activateService()
62         {
63         }
64
65         public void passivateService()
66         {
67         }
68     };
69
70     private class PooledService implements ThreadCleanupListener
71     {
72         private Object JavaDoc _core;
73
74         private PoolManageable _managed;
75
76         /**
77          * @param core
78          * the core service implementation, which may optionally implement
79          * {@link PoolManageable}
80          */

81         PooledService(Object JavaDoc core)
82         {
83             _core = core;
84
85             if (core instanceof PoolManageable)
86                 _managed = (PoolManageable) core;
87             else
88                 _managed = NULL_MANAGEABLE;
89         }
90
91         public void threadDidCleanup()
92         {
93             unbindPooledServiceFromCurrentThread(this);
94         }
95
96         void activate()
97         {
98             _managed.activateService();
99         }
100
101         void passivate()
102         {
103             _managed.passivateService();
104         }
105
106         /**
107          * Returns the configured service implementation.
108          */

109         public Object JavaDoc getService()
110         {
111             return _core;
112         }
113
114     }
115
116     public PooledServiceModel(ConstructableServicePoint servicePoint)
117     {
118         super(servicePoint);
119
120         _serviceInterface = servicePoint.getServiceInterface();
121
122         Module module = getServicePoint().getModule();
123
124         _notifier = (ThreadEventNotifier) module.getService(
125                 HiveMind.THREAD_EVENT_NOTIFIER_SERVICE,
126                 ThreadEventNotifier.class);
127
128         _serviceProxy = constructServiceProxy();
129     }
130
131     public Object JavaDoc getService()
132     {
133         return _serviceProxy;
134     }
135
136     /**
137      * Constructs the service proxy and returns it, wrapped in any interceptors.
138      */

139     private Object JavaDoc constructServiceProxy()
140     {
141         ConstructableServicePoint servicePoint = getServicePoint();
142
143         if (_log.isDebugEnabled())
144             _log.debug("Creating PooledProxy for service " + servicePoint.getExtensionPointId());
145
146         Object JavaDoc proxy = ProxyUtils.createDelegatingProxy(
147                 "PooledProxy",
148                 this,
149                 "getServiceImplementationForCurrentThread",
150                 servicePoint);
151
152         Object JavaDoc intercepted = addInterceptors(proxy);
153
154         RegistryShutdownListener outerProxy = ProxyUtils
155                 .createOuterProxy(intercepted, servicePoint);
156
157         servicePoint.addRegistryShutdownListener(outerProxy);
158
159         return outerProxy;
160     }
161
162     public Object JavaDoc getServiceImplementationForCurrentThread()
163     {
164         PooledService pooled = (PooledService) _activeService.get();
165
166         if (pooled == null)
167         {
168             pooled = obtainPooledService();
169
170             pooled.activate();
171
172             _notifier.addThreadCleanupListener(pooled);
173             _activeService.set(pooled);
174         }
175
176         return pooled.getService();
177     }
178
179     private PooledService obtainPooledService()
180     {
181         PooledService result = getServiceFromPool();
182
183         if (result == null)
184             result = constructPooledService();
185
186         return result;
187     }
188
189     private synchronized PooledService getServiceFromPool()
190     {
191         int count = _servicePool.size();
192
193         if (count == 0)
194             return null;
195
196         return (PooledService) _servicePool.remove(count - 1);
197     }
198
199     private synchronized void returnServiceToPool(PooledService pooled)
200     {
201         _servicePool.add(pooled);
202     }
203
204     private PooledService constructPooledService()
205     {
206         try
207         {
208             Object JavaDoc core = constructCoreServiceImplementation();
209
210             // This is related to bean services.
211

212             if (!_serviceInterface.isInstance(core))
213                 core = constructBridgeProxy(core);
214
215             registerWithShutdownCoordinator(core);
216
217             return new PooledService(core);
218         }
219         catch (Exception JavaDoc ex)
220         {
221             throw new ApplicationRuntimeException(ServiceModelMessages.unableToConstructService(
222                     getServicePoint(),
223                     ex), ex);
224         }
225     }
226
227     private void unbindPooledServiceFromCurrentThread(PooledService pooled)
228     {
229         _activeService.set(null);
230
231         pooled.passivate();
232
233         returnServiceToPool(pooled);
234     }
235
236     /**
237      * Invokes {@link #getServiceImplementationForCurrentThread()} to instantiate an instance of the
238      * service.
239      */

240     public void instantiateService()
241     {
242         getServiceImplementationForCurrentThread();
243     }
244
245 }
Popular Tags