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