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: 147   Methods: 5
NCLOC: 79   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ProxyBuilder.java 100% 100% 100% 100%
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.io.Serializable;
 18    import java.lang.reflect.Modifier;
 19   
 20    import org.apache.hivemind.internal.Module;
 21    import org.apache.hivemind.internal.ServicePoint;
 22    import org.apache.hivemind.internal.ser.ServiceSerializationHelper;
 23    import org.apache.hivemind.service.BodyBuilder;
 24    import org.apache.hivemind.service.ClassFab;
 25    import org.apache.hivemind.service.ClassFabUtils;
 26    import org.apache.hivemind.service.ClassFactory;
 27    import org.apache.hivemind.service.MethodIterator;
 28    import org.apache.hivemind.service.MethodSignature;
 29   
 30    /**
 31    * Class used to assist service extension points in creating proxies.
 32    *
 33    * @author Howard Lewis Ship
 34    */
 35    public final class ProxyBuilder
 36    {
 37    private ServicePoint _point;
 38   
 39    private Class _serviceInterface;
 40   
 41    private ClassFab _classFab;
 42   
 43    private String _type;
 44   
 45  1038 public ProxyBuilder(String type, ServicePoint point)
 46    {
 47  1038 this(type, point, false);
 48    }
 49   
 50    /**
 51    * Constructs a new builder. The type will be incorporated into value returned by the
 52    * <code>toString()</code> method. The service extension point is used to identify the service
 53    * interface and service id.
 54    *
 55    * @param type
 56    * used as part of the <code>toString()</code> method's return value
 57    * @param point
 58    * the service point for which this proxy is being constructed
 59    * @param outerProxy
 60    * if false, then the proxy can extend the service points service interface always.
 61    * If true and the service point's declared interface is actually a bean class (not
 62    * an interface), then the proxy will be a subclass of that bean.
 63    */
 64  2066 public ProxyBuilder(String type, ServicePoint point, boolean outerProxy)
 65    {
 66  2066 _point = point;
 67  2066 _type = type;
 68  2066 _serviceInterface = point.getServiceInterface();
 69   
 70  2066 Class declaredInterface = point.getDeclaredInterface();
 71   
 72  2066 Module module = point.getModule();
 73  2066 ClassFactory factory = (ClassFactory) module.getService(
 74    "hivemind.ClassFactory",
 75    ClassFactory.class);
 76   
 77  2066 boolean extendBeanClass = outerProxy && !declaredInterface.isInterface();
 78  2066 Class baseClass = extendBeanClass ? declaredInterface : Object.class;
 79   
 80  2066 _classFab = factory.newClass(ClassFabUtils.generateClassName(_serviceInterface), baseClass);
 81   
 82  2066 if (!extendBeanClass)
 83  2056 _classFab.addInterface(_serviceInterface);
 84   
 85    // Not exactly certain this will work with non-interface beans that already
 86    // are serializable!
 87   
 88  2066 if (outerProxy)
 89  1028 addSerializable(point.getExtensionPointId());
 90    }
 91   
 92    /** @since 1.1 */
 93  1028 private void addSerializable(String pointId)
 94    {
 95  1028 _classFab.addInterface(Serializable.class);
 96   
 97  1028 BodyBuilder bb = new BodyBuilder();
 98   
 99  1028 bb.add(
 100    "return {0}.getServiceSerializationSupport().getServiceTokenForService(\"{1}\");",
 101    ServiceSerializationHelper.class.getName(),
 102    pointId);
 103   
 104  1028 MethodSignature sig = new MethodSignature(Object.class, "writeReplace", null, null);
 105   
 106  1028 _classFab.addMethod(Modifier.PRIVATE, sig, bb.toString());
 107    }
 108   
 109  2066 public ClassFab getClassFab()
 110    {
 111  2066 return _classFab;
 112    }
 113   
 114    /**
 115    * Creates the service methods for the class.
 116    *
 117    * @param indirection
 118    * the name of a variable, or a method invocation snippet, used to redirect the
 119    * invocation on the proxy to the actual service implementation.
 120    */
 121  2066 public void addServiceMethods(String indirection)
 122    {
 123  2066 BodyBuilder builder = new BodyBuilder();
 124   
 125  2066 MethodIterator mi = new MethodIterator(_serviceInterface);
 126  2066 while (mi.hasNext())
 127    {
 128  2441 MethodSignature m = mi.next();
 129  2441 if( !_classFab.containsMethod( m ) )
 130    {
 131  2439 builder.clear();
 132  2439 builder.begin();
 133  2439 builder.add("return ($r) ");
 134  2439 builder.add(indirection);
 135  2439 builder.add(".");
 136  2439 builder.add(m.getName());
 137  2439 builder.addln("($$);");
 138  2439 builder.end();
 139  2439 _classFab.addMethod(Modifier.PUBLIC, m, builder.toString());
 140    }
 141    }
 142   
 143  2066 if (!mi.getToString())
 144  2064 ClassFabUtils.addToStringMethod(_classFab, "<" + _type + " for "
 145    + _point.getExtensionPointId() + "(" + _serviceInterface.getName() + ")>");
 146    }
 147    }