Clover coverage report - Code Coverage for hivemind-lib release 1.1-beta-1
Coverage timestamp: Thu Apr 28 2005 19:55:00 EDT
file stats: LOC: 157   Methods: 4
NCLOC: 102   Classes: 1
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
ServicePropertyFactory.java 87.5% 97.6% 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.lib.impl;
 16   
 
 17   
 import java.lang.reflect.Modifier;
 18   
 
 19   
 import org.apache.hivemind.ApplicationRuntimeException;
 20   
 import org.apache.hivemind.ServiceImplementationFactory;
 21   
 import org.apache.hivemind.ServiceImplementationFactoryParameters;
 22   
 import org.apache.hivemind.service.BodyBuilder;
 23   
 import org.apache.hivemind.service.ClassFab;
 24   
 import org.apache.hivemind.service.ClassFabUtils;
 25   
 import org.apache.hivemind.service.ClassFactory;
 26   
 import org.apache.hivemind.service.MethodIterator;
 27   
 import org.apache.hivemind.service.MethodSignature;
 28   
 import org.apache.hivemind.util.ConstructorUtils;
 29   
 import org.apache.hivemind.util.PropertyAdaptor;
 30   
 import org.apache.hivemind.util.PropertyUtils;
 31   
 
 32   
 /**
 33   
  * Factory that dynamically exposes a property of another service. A proxy is constructed that
 34   
  * accesses the target service and obtains a property from that. The service interface of the
 35   
  * constructed service must match the type of the exposed property.
 36   
  * 
 37   
  * @author Howard Lewis Ship
 38   
  */
 39   
 public class ServicePropertyFactory implements ServiceImplementationFactory
 40   
 {
 41   
     private ClassFactory _classFactory;
 42   
 
 43  8
     public Object createCoreServiceImplementation(
 44   
             ServiceImplementationFactoryParameters factoryParameters)
 45   
     {
 46  8
         ServicePropertyFactoryParameter p = (ServicePropertyFactoryParameter) factoryParameters
 47   
                 .getParameters().get(0);
 48   
 
 49  8
         Object targetService = p.getService();
 50  8
         String propertyName = p.getPropertyName();
 51   
 
 52  8
         PropertyAdaptor pa = PropertyUtils.getPropertyAdaptor(targetService, propertyName);
 53   
 
 54  8
         String readMethodName = pa.getReadMethodName();
 55   
 
 56  8
         if (readMethodName == null)
 57  1
             throw new ApplicationRuntimeException(ImplMessages.servicePropertyNotReadable(
 58   
                     propertyName,
 59   
                     targetService), null, p.getLocation(), null);
 60  7
         Class serviceInterface = factoryParameters.getServiceInterface();
 61   
 
 62  7
         if (!(serviceInterface.isAssignableFrom(pa.getPropertyType())))
 63  1
             throw new ApplicationRuntimeException(ImplMessages.servicePropertyWrongType(
 64   
                     propertyName,
 65   
                     targetService,
 66   
                     pa.getPropertyType(),
 67   
                     serviceInterface), p.getLocation(), null);
 68   
 
 69   
         // Now we're good to go.
 70   
 
 71  6
         String name = ClassFabUtils.generateClassName(serviceInterface);
 72   
 
 73  6
         ClassFab cf = _classFactory.newClass(name, Object.class);
 74   
 
 75  6
         addInfrastructure(cf, targetService, serviceInterface, propertyName, readMethodName);
 76   
 
 77  6
         addMethods(
 78   
                 cf,
 79   
                 factoryParameters.getServiceId(),
 80   
                 serviceInterface,
 81   
                 propertyName,
 82   
                 targetService);
 83   
 
 84  6
         Class proxyClass = cf.createClass();
 85   
 
 86  6
         try
 87   
         {
 88  6
             return ConstructorUtils.invokeConstructor(proxyClass, new Object[]
 89   
             { targetService });
 90   
         }
 91   
         catch (Throwable ex)
 92   
         {
 93  0
             throw new ApplicationRuntimeException(ex.getMessage(), p.getLocation(), ex);
 94   
         }
 95   
     }
 96   
 
 97  6
     private void addInfrastructure(ClassFab cf, Object targetService, Class serviceInterface,
 98   
             String propertyName, String readPropertyMethodName)
 99   
     {
 100  6
         cf.addInterface(serviceInterface);
 101   
 
 102  6
         Class targetServiceClass = ClassFabUtils.getInstanceClass(targetService, serviceInterface);
 103   
 
 104  6
         cf.addField("_targetService", targetServiceClass);
 105   
 
 106  6
         cf.addConstructor(new Class[]
 107   
         { targetServiceClass }, null, "{ super(); _targetService = $1; }");
 108   
 
 109  6
         BodyBuilder b = new BodyBuilder();
 110   
 
 111  6
         b.begin();
 112  6
         b.addln(
 113   
                 "{0} property = _targetService.{1}();",
 114   
                 serviceInterface.getName(),
 115   
                 readPropertyMethodName);
 116   
 
 117  6
         b.addln("if (property == null)");
 118  6
         b.add("  throw new java.lang.NullPointerException(");
 119  6
         b.addQuoted(ImplMessages.servicePropertyWasNull(propertyName, targetService));
 120  6
         b.addln(");");
 121   
 
 122  6
         b.addln("return property;");
 123   
 
 124  6
         b.end();
 125   
 
 126  6
         MethodSignature sig = new MethodSignature(serviceInterface, "_targetServiceProperty", null,
 127   
                 null);
 128  6
         cf.addMethod(Modifier.FINAL | Modifier.PRIVATE, sig, b.toString());
 129   
     }
 130   
 
 131  6
     private void addMethods(ClassFab cf, String serviceId, Class serviceInterface,
 132   
             String propertyName, Object targetService)
 133   
     {
 134  6
         MethodIterator mi = new MethodIterator(serviceInterface);
 135   
 
 136  6
         while (mi.hasNext())
 137   
         {
 138  18
             MethodSignature sig = mi.next();
 139   
 
 140  18
             String body = "return ($r) _targetServiceProperty()." + sig.getName() + "($$);";
 141   
 
 142  18
             cf.addMethod(Modifier.PUBLIC, sig, body);
 143   
         }
 144   
 
 145  6
         if (!mi.getToString())
 146  6
             ClassFabUtils.addToStringMethod(cf, ImplMessages.servicePropertyToString(
 147   
                     serviceId,
 148   
                     serviceInterface,
 149   
                     propertyName,
 150   
                     targetService));
 151   
     }
 152   
 
 153  8
     public void setClassFactory(ClassFactory factory)
 154   
     {
 155  8
         _classFactory = factory;
 156   
     }
 157   
 }