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