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: 203   Methods: 6
NCLOC: 112   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ProxyUtils.java 100% 95.7% 83.3% 94.5%
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.lang.reflect.Constructor;
 18    import java.lang.reflect.Modifier;
 19   
 20    import org.apache.hivemind.ApplicationRuntimeException;
 21    import org.apache.hivemind.events.RegistryShutdownListener;
 22    import org.apache.hivemind.internal.ServiceModel;
 23    import org.apache.hivemind.internal.ServicePoint;
 24    import org.apache.hivemind.service.BodyBuilder;
 25    import org.apache.hivemind.service.ClassFab;
 26    import org.apache.hivemind.service.ClassFabUtils;
 27    import org.apache.hivemind.service.MethodSignature;
 28    import org.apache.hivemind.util.ConstructorUtils;
 29   
 30    /**
 31    * Contains some common code used to create proxies that defer to a service model method for thier
 32    * service.
 33    *
 34    * @author Howard Lewis Ship
 35    */
 36    public final class ProxyUtils
 37    {
 38    public static final String SERVICE_ACCESSOR_METHOD_NAME = "_service";
 39   
 40    public static final String DELEGATE_ACCESSOR_METHOD_NAME = "_delegate";
 41   
 42  0 private ProxyUtils()
 43    {
 44    // Prevent instantiation
 45    }
 46   
 47    /**
 48    * Creates a class that implements the service interface. Implements a private synchronized
 49    * method, _service(), that constructs the service as needed, and has each service interface
 50    * method re-invoke on _service(). Adds a toString() method if the service interface does not
 51    * define toString().
 52    */
 53  33 public static Object createDelegatingProxy(String type, ServiceModel serviceModel,
 54    String delegationMethodName, ServicePoint servicePoint)
 55    {
 56  33 ProxyBuilder builder = new ProxyBuilder(type, servicePoint);
 57   
 58  33 ClassFab classFab = builder.getClassFab();
 59   
 60  33 addConstructor(classFab, serviceModel);
 61   
 62  33 addServiceAccessor(classFab, delegationMethodName, servicePoint);
 63   
 64  33 builder.addServiceMethods(SERVICE_ACCESSOR_METHOD_NAME + "()");
 65   
 66  33 Class proxyClass = classFab.createClass();
 67   
 68  33 try
 69    {
 70  33 Constructor c = proxyClass.getConstructor(new Class[]
 71    { serviceModel.getClass() });
 72   
 73  33 return c.newInstance(new Object[]
 74    { serviceModel });
 75    }
 76    catch (Exception ex)
 77    {
 78  0 throw new ApplicationRuntimeException(ex);
 79    }
 80    }
 81   
 82    /**
 83    * Constructs an outer proxy (for the threaded or pooled service). The outer proxy listens to
 84    * the shutdown coordinator, and delegates from the declared interface (which may in fact be a
 85    * bean) to the service interface.
 86    * <p>
 87    * The outer proxy is a {@link RegistryShutdownListener}; it can be registered for
 88    * notifications and will respond by throwing an exception when service methods are invoked.
 89    *
 90    * @param delegate
 91    * An object, implementing the service interface, that the proxy should delegate to.
 92    * @param servicePoint
 93    * for which the proxy is being constructed
 94    * @since 1.1
 95    */
 96   
 97  33 public static RegistryShutdownListener createOuterProxy(Object delegate,
 98    ServicePoint servicePoint)
 99    {
 100  33 ProxyBuilder builder = new ProxyBuilder("OuterProxy", servicePoint, true);
 101   
 102  33 ClassFab classFab = builder.getClassFab();
 103   
 104  33 addDelegateAccessor(classFab, servicePoint, delegate);
 105   
 106  33 builder.addServiceMethods(DELEGATE_ACCESSOR_METHOD_NAME + "()");
 107   
 108  33 Class proxyClass = classFab.createClass();
 109   
 110  33 try
 111    {
 112  33 return (RegistryShutdownListener) ConstructorUtils.invokeConstructor(
 113    proxyClass,
 114    new Object[]
 115    { delegate });
 116    }
 117    catch (Exception ex)
 118    {
 119  0 throw new ApplicationRuntimeException(ex);
 120    }
 121    }
 122   
 123    /** @since 1.1 */
 124   
 125  33 private static void addDelegateAccessor(ClassFab classFab, ServicePoint servicePoint,
 126    Object delegate)
 127    {
 128  33 classFab.addField("_shutdown", boolean.class);
 129   
 130  33 Class delegateClass = ClassFabUtils.getInstanceClass(delegate, servicePoint
 131    .getServiceInterface());
 132   
 133  33 classFab.addField("_delegate", delegateClass);
 134   
 135  33 classFab.addConstructor(new Class[]
 136    { delegateClass }, null, "{ super(); _delegate = $1; }");
 137   
 138  33 classFab.addInterface(RegistryShutdownListener.class);
 139  33 if( RegistryShutdownListener.class.isAssignableFrom( delegateClass ) )
 140    {
 141  2 classFab.addMethod(Modifier.PUBLIC | Modifier.FINAL, new MethodSignature(void.class,
 142    "registryDidShutdown", null, null), "{ _delegate.registryDidShutdown(); _delegate = null; _shutdown = true; }");
 143    }
 144    else
 145    {
 146  31 classFab.addMethod(Modifier.PUBLIC | Modifier.FINAL, new MethodSignature(void.class,
 147    "registryDidShutdown", null, null), "{ _delegate = null; _shutdown = true; }");
 148    }
 149  33 BodyBuilder builder = new BodyBuilder();
 150   
 151  33 builder.begin();
 152   
 153  33 builder.addln("if (_shutdown)");
 154  33 builder.addln(" throw org.apache.hivemind.HiveMind#createRegistryShutdownException();");
 155   
 156  33 builder.add("return _delegate;");
 157   
 158  33 builder.end();
 159   
 160  33 classFab.addMethod(Modifier.FINAL | Modifier.PRIVATE, new MethodSignature(delegateClass,
 161    DELEGATE_ACCESSOR_METHOD_NAME, null, null), builder.toString());
 162    }
 163   
 164    /**
 165    * Adds a field, _serviceExtensionPoint, whose type matches this class, and a constructor which
 166    * sets the field.
 167    */
 168  33 private static void addConstructor(ClassFab classFab, ServiceModel model)
 169    {
 170  33 Class modelClass = model.getClass();
 171   
 172  33 classFab.addField("_serviceModel", modelClass);
 173   
 174  33 classFab.addConstructor(new Class[]
 175    { modelClass }, null, "{ super(); _serviceModel = $1; }");
 176    }
 177   
 178    /**
 179    * We construct a method that always goes through this service model's
 180    * {@link #getServiceImplementationForCurrentThread())} method.
 181    */
 182  33 private static void addServiceAccessor(ClassFab classFab, String serviceModelMethodName,
 183    ServicePoint servicePoint)
 184    {
 185  33 Class serviceInterface = servicePoint.getServiceInterface();
 186   
 187  33 classFab.addField(SERVICE_ACCESSOR_METHOD_NAME, serviceInterface);
 188   
 189  33 BodyBuilder builder = new BodyBuilder();
 190  33 builder.begin();
 191   
 192  33 builder.add("return (");
 193  33 builder.add(serviceInterface.getName());
 194  33 builder.add(") _serviceModel.");
 195  33 builder.add(serviceModelMethodName);
 196  33 builder.add("();");
 197   
 198  33 builder.end();
 199   
 200  33 classFab.addMethod(Modifier.PRIVATE | Modifier.FINAL, new MethodSignature(serviceInterface,
 201    SERVICE_ACCESSOR_METHOD_NAME, null, null), builder.toString());
 202    }
 203    }