Clover coverage report - Code Coverage for hivemind release 1.0-beta-1
Coverage timestamp: Sat Jul 3 2004 09:41:37 EDT
file stats: LOC: 228   Methods: 17
NCLOC: 146   Classes: 2
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
PooledServiceModel.java 83.3% 97.9% 100% 95.1%
coverage coverage
 1   
 //  Copyright 2004 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;
 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.impl.ConstructableServicePoint;
 24   
 import org.apache.hivemind.impl.ProxyUtils;
 25   
 import org.apache.hivemind.internal.Module;
 26   
 import org.apache.hivemind.service.ThreadCleanupListener;
 27   
 import org.apache.hivemind.service.ThreadEventNotifier;
 28   
 
 29   
 /**
 30   
  * Similar to the {@link org.apache.hivemind.impl.ThreadedServiceModel threaded service model},
 31   
  * except that, once created, services are pooled for later use.
 32   
  *
 33   
  * @author Howard Lewis Ship
 34   
  */
 35   
 public class PooledServiceModel extends AbstractServiceModelImpl
 36   
 {
 37   
     /**
 38   
      * Name of a method in the deferred proxy that is used to obtain
 39   
      * the constructed service.
 40   
      */
 41   
     protected static final String SERVICE_ACCESSOR_METHOD_NAME = "_service";
 42   
 
 43   
     private Object _serviceProxy;
 44   
     private ThreadEventNotifier _notifier;
 45   
     private ThreadLocal _activeService;
 46   
     private List _servicePool;
 47   
 
 48   
     /**
 49   
      * Shared, null implementation of PoolManageable.
 50   
      */
 51   
     private static final PoolManageable NULL_MANAGEABLE = new PoolManageable()
 52   
     {
 53  3
         public void activateService()
 54   
         {
 55   
         }
 56   
 
 57  1
         public void passivateService()
 58   
         {
 59   
         }
 60   
     };
 61   
 
 62   
     private class PooledService implements ThreadCleanupListener
 63   
     {
 64   
         private Object _service;
 65   
         private PoolManageable _managed;
 66   
 
 67   
         /**
 68   
          * @param service the full service implementation, including any interceptors
 69   
          * @param core the core service implementation, which may optionally implement {@link PoolManageable}
 70   
          */
 71  3
         PooledService(Object service, Object core)
 72   
         {
 73  3
             _service = service;
 74   
 
 75  3
             if (core instanceof PoolManageable)
 76  1
                 _managed = (PoolManageable) core;
 77   
             else
 78  2
                 _managed = NULL_MANAGEABLE;
 79   
         }
 80   
 
 81  2
         public void threadDidCleanup()
 82   
         {
 83  2
             unbindPooledServiceFromCurrentThread(this);
 84   
         }
 85   
 
 86  5
         void activate()
 87   
         {
 88  5
             _managed.activateService();
 89   
         }
 90   
 
 91  2
         void passivate()
 92   
         {
 93  2
             _managed.passivateService();
 94   
         }
 95   
 
 96   
         /**
 97   
          * Returns the configured, interceptor service implementation.
 98   
          */
 99  9
         public Object getService()
 100   
         {
 101  9
             return _service;
 102   
         }
 103   
 
 104   
     }
 105   
 
 106  3
     public PooledServiceModel(ConstructableServicePoint servicePoint)
 107   
     {
 108  3
         super(servicePoint);
 109   
     }
 110   
 
 111  3
     public synchronized Object getService()
 112   
     {
 113  3
         if (_activeService == null)
 114   
         {
 115  3
             _activeService = new ThreadLocal();
 116   
 
 117  3
             Module module = getServicePoint().getModule();
 118   
 
 119  3
             _notifier =
 120   
                 (ThreadEventNotifier) module.getService(
 121   
                     HiveMind.THREAD_EVENT_NOTIFIER_SERVICE,
 122   
                     ThreadEventNotifier.class);
 123   
         }
 124   
 
 125  3
         if (_serviceProxy == null)
 126  3
             _serviceProxy = constructServiceProxy();
 127   
 
 128  3
         return _serviceProxy;
 129   
     }
 130   
 
 131  3
     private Object constructServiceProxy()
 132   
     {
 133  3
         if (_log.isDebugEnabled())
 134  1
             _log.debug(
 135   
                 "Creating PooledProxy for service " + getServicePoint().getExtensionPointId());
 136   
 
 137  3
         return ProxyUtils.createDelegatingProxy(
 138   
             "PooledProxy",
 139   
             this,
 140   
             "getServiceImplementationForCurrentThread",
 141   
             getServicePoint(),
 142   
             getServicePoint().getShutdownCoordinator());
 143   
     }
 144   
 
 145  9
     public Object getServiceImplementationForCurrentThread()
 146   
     {
 147  9
         PooledService pooled = (PooledService) _activeService.get();
 148   
 
 149  9
         if (pooled == null)
 150   
         {
 151  5
             pooled = obtainPooledService();
 152   
 
 153  5
             pooled.activate();
 154   
 
 155  5
             _notifier.addThreadCleanupListener(pooled);
 156  5
             _activeService.set(pooled);
 157   
         }
 158   
 
 159  9
         return pooled.getService();
 160   
     }
 161   
 
 162  5
     private PooledService obtainPooledService()
 163   
     {
 164  5
         PooledService result = getServiceFromPool();
 165   
 
 166  5
         if (result == null)
 167  3
             result = constructPooledService();
 168   
 
 169  5
         return result;
 170   
     }
 171   
 
 172  5
     private synchronized PooledService getServiceFromPool()
 173   
     {
 174  5
         int count = _servicePool == null ? 0 : _servicePool.size();
 175   
 
 176  5
         if (count == 0)
 177  3
             return null;
 178   
 
 179  2
         return (PooledService) _servicePool.remove(count - 1);
 180   
     }
 181   
 
 182  2
     private synchronized void returnServiceToPool(PooledService pooled)
 183   
     {
 184  2
         if (_servicePool == null)
 185  2
             _servicePool = new ArrayList();
 186   
 
 187  2
         _servicePool.add(pooled);
 188   
     }
 189   
 
 190  3
     private PooledService constructPooledService()
 191   
     {
 192  3
         try
 193   
         {
 194  3
             Object core = constructCoreServiceImplementation();
 195  3
             Object intercepted = addInterceptors(core);
 196   
 
 197  3
             return new PooledService(intercepted, core);
 198   
         }
 199   
         catch (Exception ex)
 200   
         {
 201  0
             throw new ApplicationRuntimeException(
 202   
                 ServiceModelMessages.unableToConstructService(getServicePoint(), ex),
 203   
                 ex);
 204   
         }
 205   
     }
 206   
 
 207  2
     private void unbindPooledServiceFromCurrentThread(PooledService pooled)
 208   
     {
 209  2
         _notifier.removeThreadCleanupListener(pooled);
 210   
 
 211  2
         _activeService.set(null);
 212   
 
 213  2
         pooled.passivate();
 214   
 
 215  2
         returnServiceToPool(pooled);
 216   
     }
 217   
 
 218   
     /**
 219   
      * Invokes {@link #getServiceImplementationForCurrentThread()} to instantiate an instance
 220   
      * of the service.
 221   
      */
 222  1
     public void instantiateService()
 223   
     {
 224  1
         getServiceImplementationForCurrentThread();
 225   
     }
 226   
 
 227   
 }
 228