2009/04/15 - Apache HiveMind has been retired.

For more information, please explore the Attic.

Clover coverage report - Code Coverage for hivemind release 1.2.1
Coverage timestamp: Fri Feb 10 2006 16:33:43 PST
file stats: LOC: 333   Methods: 25
NCLOC: 215   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ServicePointImpl.java 90% 97.4% 100% 96.2%
coverage coverage
 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;
 16   
 17    import java.util.ArrayList;
 18    import java.util.Iterator;
 19    import java.util.List;
 20   
 21    import org.apache.commons.logging.Log;
 22    import org.apache.commons.logging.LogFactory;
 23    import org.apache.hivemind.ApplicationRuntimeException;
 24    import org.apache.hivemind.HiveMind;
 25    import org.apache.hivemind.Occurances;
 26    import org.apache.hivemind.ShutdownCoordinator;
 27    import org.apache.hivemind.events.RegistryShutdownListener;
 28    import org.apache.hivemind.internal.ServiceImplementationConstructor;
 29    import org.apache.hivemind.internal.ServiceInterceptorContribution;
 30    import org.apache.hivemind.internal.ServiceModel;
 31    import org.apache.hivemind.internal.ServiceModelFactory;
 32    import org.apache.hivemind.order.Orderer;
 33    import org.apache.hivemind.schema.Schema;
 34    import org.apache.hivemind.service.InterfaceSynthesizer;
 35    import org.apache.hivemind.util.ToStringBuilder;
 36   
 37    /**
 38    * Abstract implementation of {@link org.apache.hivemind.internal.ServicePoint}. Provides some of
 39    * the machinery for creating new service instances, delegating most of it to the
 40    * {@link org.apache.hivemind.internal.ServiceModel} instace for the service.
 41    *
 42    * @author Howard Lewis Ship
 43    */
 44    public final class ServicePointImpl extends AbstractExtensionPoint implements
 45    ConstructableServicePoint
 46    {
 47    private Object _service;
 48   
 49    private boolean _building;
 50   
 51    private String _serviceInterfaceName;
 52   
 53    private Class _serviceInterface;
 54   
 55    private Class _declaredInterface;
 56   
 57    private ServiceImplementationConstructor _defaultServiceConstructor;
 58   
 59    private ServiceImplementationConstructor _serviceConstructor;
 60   
 61    private List _interceptorContributions;
 62   
 63    private boolean _interceptorsOrdered;
 64   
 65    private Schema _parametersSchema;
 66   
 67    private Occurances _parametersCount;
 68   
 69    private String _serviceModel;
 70   
 71    private ShutdownCoordinator _shutdownCoordinator;
 72   
 73    private ServiceModel _serviceModelObject;
 74   
 75  1 protected void extendDescription(ToStringBuilder builder)
 76    {
 77  1 if (_service != null)
 78  0 builder.append("service", _service);
 79   
 80  1 builder.append("serviceInterfaceName", _serviceInterfaceName);
 81  1 builder.append("defaultServiceConstructor", _defaultServiceConstructor);
 82  1 builder.append("serviceConstructor", _serviceConstructor);
 83  1 builder.append("interceptorContributions", _interceptorContributions);
 84  1 builder.append("parametersSchema", _parametersSchema);
 85  1 builder.append("parametersCount", _parametersCount);
 86  1 builder.append("serviceModel", _serviceModel);
 87   
 88  1 if (_building)
 89  0 builder.append("building", _building);
 90    }
 91   
 92  36 public void addInterceptorContribution(ServiceInterceptorContribution contribution)
 93    {
 94  36 if (_interceptorContributions == null)
 95  31 _interceptorContributions = new ArrayList();
 96   
 97  36 _interceptorContributions.add(contribution);
 98    }
 99   
 100  17876 public synchronized Class getServiceInterface()
 101    {
 102  17876 if (_serviceInterface == null)
 103  1418 _serviceInterface = lookupServiceInterface();
 104   
 105  17875 return _serviceInterface;
 106    }
 107   
 108  16690 public synchronized Class getDeclaredInterface()
 109    {
 110  16690 if (_declaredInterface == null)
 111  1418 _declaredInterface = lookupDeclaredInterface();
 112   
 113  16689 return _declaredInterface;
 114    }
 115   
 116    /** @since 1.1 */
 117   
 118  2580 public String getServiceInterfaceClassName()
 119    {
 120  2580 return _serviceInterfaceName;
 121    }
 122   
 123  1418 private Class lookupDeclaredInterface()
 124    {
 125  1418 Class result = null;
 126   
 127  1418 try
 128    {
 129  1418 result = getModule().resolveType(_serviceInterfaceName);
 130    }
 131    catch (Exception ex)
 132    {
 133  1 throw new ApplicationRuntimeException(ImplMessages.badInterface(
 134    _serviceInterfaceName,
 135    getExtensionPointId()), getLocation(), ex);
 136    }
 137   
 138  1417 return result;
 139    }
 140   
 141  1418 private Class lookupServiceInterface()
 142    {
 143  1418 Class declaredInterface = getDeclaredInterface();
 144   
 145  1417 if (declaredInterface.isInterface())
 146  1406 return declaredInterface;
 147   
 148    // Not an interface ... a class. Synthesize an interface from the class itself.
 149   
 150  11 InterfaceSynthesizer is = (InterfaceSynthesizer) getModule().getService(
 151    HiveMind.INTERFACE_SYNTHESIZER_SERVICE,
 152    InterfaceSynthesizer.class);
 153   
 154  11 return is.synthesizeInterface(declaredInterface);
 155    }
 156   
 157  2561 public void setServiceConstructor(ServiceImplementationConstructor contribution,
 158    boolean defaultConstructor)
 159    {
 160  2561 if (defaultConstructor)
 161  2560 _defaultServiceConstructor = contribution;
 162    else
 163  1 _serviceConstructor = contribution;
 164    }
 165   
 166  2576 public void setServiceInterfaceName(String string)
 167    {
 168  2576 _serviceInterfaceName = string;
 169    }
 170   
 171  2564 public void setParametersSchema(Schema schema)
 172    {
 173  2564 _parametersSchema = schema;
 174    }
 175   
 176  503 public Schema getParametersSchema()
 177    {
 178  503 return _parametersSchema;
 179    }
 180   
 181  2561 public ServiceImplementationConstructor getServiceConstructor(boolean defaultConstructor)
 182    {
 183  2561 return defaultConstructor ? _defaultServiceConstructor : _serviceConstructor;
 184    }
 185   
 186    /**
 187    * Invoked by {@link #getService(Class)} to get a service implementation from the
 188    * {@link ServiceModel}.
 189    * <p>
 190    * TODO: I'm concerned that this synchronized method could cause a deadlock. It would take a LOT
 191    * (mutually dependent services in multiple threads being realized at the same time).
 192    */
 193  4695 private synchronized Object getService()
 194    {
 195  4695 if (_service == null)
 196    {
 197   
 198  1416 if (_building)
 199  1 throw new ApplicationRuntimeException(ImplMessages.recursiveServiceBuild(this));
 200   
 201  1415 _building = true;
 202   
 203  1415 try
 204    {
 205   
 206  1415 ServiceModelFactory factory = getModule().getServiceModelFactory(getServiceModel());
 207   
 208  1415 _serviceModelObject = factory.createServiceModelForService(this);
 209   
 210  1415 _service = _serviceModelObject.getService();
 211    }
 212    finally
 213    {
 214  1415 _building = false;
 215    }
 216    }
 217   
 218  4690 return _service;
 219    }
 220   
 221  4690 public Object getService(Class serviceInterface)
 222    {
 223  4691 Object result = getService();
 224   
 225  4687 if (!serviceInterface.isAssignableFrom(result.getClass()))
 226    {
 227  1 throw new ApplicationRuntimeException(ImplMessages.serviceWrongInterface(
 228    this,
 229    serviceInterface), getLocation(), null);
 230    }
 231   
 232  4686 return result;
 233    }
 234   
 235  1415 public String getServiceModel()
 236    {
 237  1415 return _serviceModel;
 238    }
 239   
 240  2562 public void setServiceModel(String model)
 241    {
 242  2562 _serviceModel = model;
 243    }
 244   
 245  878 public void clearConstructorInformation()
 246    {
 247  878 _serviceConstructor = null;
 248  878 _interceptorContributions = null;
 249    }
 250   
 251    // Hm. Does this need to be synchronized?
 252   
 253  917 public List getOrderedInterceptorContributions()
 254    {
 255  917 if (!_interceptorsOrdered)
 256    {
 257  917 _interceptorContributions = orderInterceptors();
 258  917 _interceptorsOrdered = true;
 259    }
 260   
 261  917 return _interceptorContributions;
 262    }
 263   
 264  917 private List orderInterceptors()
 265    {
 266  917 if (HiveMind.isEmpty(_interceptorContributions))
 267  898 return null;
 268   
 269    // Any error logging should go to the extension point
 270    // we're constructing.
 271   
 272  19 Log log = LogFactory.getLog(getExtensionPointId());
 273   
 274  19 Orderer orderer = new Orderer(log, getModule().getErrorHandler(), ImplMessages
 275    .interceptorContribution());
 276   
 277  19 Iterator i = _interceptorContributions.iterator();
 278  19 while (i.hasNext())
 279    {
 280  24 ServiceInterceptorContribution sic = (ServiceInterceptorContribution) i.next();
 281   
 282    // Sort them into runtime excecution order. When we build
 283    // the interceptor stack we'll apply them in reverse order,
 284    // building outward from the core service implementation.
 285   
 286  24 orderer.add(sic, sic.getName(), sic.getPrecedingInterceptorIds(), sic
 287    .getFollowingInterceptorIds());
 288    }
 289   
 290  19 return orderer.getOrderedObjects();
 291    }
 292   
 293  2564 public void setShutdownCoordinator(ShutdownCoordinator coordinator)
 294    {
 295  2564 _shutdownCoordinator = coordinator;
 296    }
 297   
 298  1028 public void addRegistryShutdownListener(RegistryShutdownListener listener)
 299    {
 300  1028 _shutdownCoordinator.addRegistryShutdownListener(listener);
 301    }
 302   
 303    /**
 304    * Forces the service into existence.
 305    */
 306  4 public void forceServiceInstantiation()
 307    {
 308  4 getService();
 309   
 310  4 _serviceModelObject.instantiateService();
 311    }
 312   
 313  488 public Occurances getParametersCount()
 314    {
 315  488 return _parametersCount;
 316    }
 317   
 318  2564 public void setParametersCount(Occurances occurances)
 319    {
 320  2564 _parametersCount = occurances;
 321    }
 322   
 323    /**
 324    * Returns the service constructor, if defined, or the default service constructor. The default
 325    * service constructor comes from the &lt;service-point&gt; itself; other modules can override
 326    * this default using an &lt;implementation&gt; element.
 327    */
 328   
 329  15767 public ServiceImplementationConstructor getServiceConstructor()
 330    {
 331  15767 return _serviceConstructor == null ? _defaultServiceConstructor : _serviceConstructor;
 332    }
 333    }