1 15 package org.apache.hivemind.impl.servicemodel; 16 17 import java.util.ArrayList ; 18 import java.util.List ; 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 37 public class PooledServiceModel extends AbstractServiceModelImpl 38 { 39 42 protected static final String SERVICE_ACCESSOR_METHOD_NAME = "_service"; 43 44 private final Object _serviceProxy; 45 46 private final ThreadEventNotifier _notifier; 47 48 private final ThreadLocal _activeService = new ThreadLocal (); 49 50 private final List _servicePool = new ArrayList (); 51 52 53 54 private Class _serviceInterface; 55 56 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 _core; 73 74 private PoolManageable _managed; 75 76 81 PooledService(Object 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 109 public Object 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 getService() 132 { 133 return _serviceProxy; 134 } 135 136 139 private Object constructServiceProxy() 140 { 141 ConstructableServicePoint servicePoint = getServicePoint(); 142 143 if (_log.isDebugEnabled()) 144 _log.debug("Creating PooledProxy for service " + servicePoint.getExtensionPointId()); 145 146 Object proxy = ProxyUtils.createDelegatingProxy( 147 "PooledProxy", 148 this, 149 "getServiceImplementationForCurrentThread", 150 servicePoint); 151 152 Object 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 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 core = constructCoreServiceImplementation(); 209 210 212 if (!_serviceInterface.isInstance(core)) 213 core = constructBridgeProxy(core); 214 215 registerWithShutdownCoordinator(core); 216 217 return new PooledService(core); 218 } 219 catch (Exception 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 240 public void instantiateService() 241 { 242 getServiceImplementationForCurrentThread(); 243 } 244 245 } | Popular Tags |