Clover coverage report - Code Coverage for hivemind-lib release 1.0-rc-1
Coverage timestamp: Wed Aug 25 2004 13:06:39 EDT
file stats: LOC: 267   Methods: 11
NCLOC: 183   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
EJBProxyFactory.java 87.5% 98.8% 100% 98.1%
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.Constructor;
 18   
 import java.lang.reflect.Method;
 19   
 import java.lang.reflect.Modifier;
 20   
 import java.rmi.RemoteException;
 21   
 import java.util.List;
 22   
 
 23   
 import org.apache.commons.logging.Log;
 24   
 import org.apache.hivemind.ApplicationRuntimeException;
 25   
 import org.apache.hivemind.ServiceImplementationFactory;
 26   
 import org.apache.hivemind.impl.BaseLocatable;
 27   
 import org.apache.hivemind.internal.Module;
 28   
 import org.apache.hivemind.lib.NameLookup;
 29   
 import org.apache.hivemind.lib.RemoteExceptionCoordinator;
 30   
 import org.apache.hivemind.service.BodyBuilder;
 31   
 import org.apache.hivemind.service.ClassFab;
 32   
 import org.apache.hivemind.service.ClassFabUtils;
 33   
 import org.apache.hivemind.service.ClassFactory;
 34   
 import org.apache.hivemind.service.MethodSignature;
 35   
 
 36   
 /**
 37   
  * An implementation of {@link org.apache.hivemind.ServiceImplementationFactory}
 38   
  * that can create a proxy to a stateless session EJB.  Using this factory, it is
 39   
  * easy to create a HiveMind service wrapper around the actual EJB.
 40   
  * 
 41   
  * <p>
 42   
  * The parameters for the factory are used to identify the JNDI name of the
 43   
  * session EJB's home interface.
 44   
  * 
 45   
  * 
 46   
  *
 47   
  * @author Howard Lewis Ship
 48   
  */
 49   
 public class EJBProxyFactory extends BaseLocatable implements ServiceImplementationFactory
 50   
 {
 51   
     private NameLookup _nameLookup;
 52   
     private RemoteExceptionCoordinator _coordinator;
 53   
     private ClassFactory _classFactory;
 54   
 
 55  3
     public Object createCoreServiceImplementation(
 56   
         String serviceId,
 57   
         Class serviceInterface,
 58   
         Log serviceLog,
 59   
         Module invokingModule,
 60   
         List parameters)
 61   
     {
 62  3
         EJBProxyParameters proxyParameters = (EJBProxyParameters) parameters.get(0);
 63  3
         String jndiName = proxyParameters.getJndiName();
 64  3
         String homeInterfaceClassName = proxyParameters.getHomeInterfaceClassName();
 65   
 
 66   
         // The service interface is the remote interface.
 67   
 
 68  3
         Class homeInterface = invokingModule.getClassResolver().findClass(homeInterfaceClassName);
 69   
 
 70  3
         String proxyClassName = ClassFabUtils.generateClassName("EJBProxy");
 71   
 
 72  3
         ClassFab classFab =
 73   
             _classFactory.newClass(proxyClassName, AbstractEJBProxy.class, invokingModule);
 74   
 
 75  3
         classFab.addInterface(serviceInterface);
 76   
 
 77  3
         classFab.addField("_remote", serviceInterface);
 78   
 
 79  3
         addClearCachedMethod(classFab);
 80   
 
 81  3
         addLookupMethod(classFab, homeInterface, serviceInterface, jndiName);
 82   
 
 83  3
         addServiceMethods(classFab, serviceInterface, serviceId, jndiName);
 84   
 
 85  3
         addConstructor(classFab);
 86   
 
 87  3
         Class proxyClass = classFab.createClass();
 88   
 
 89  3
         return invokeConstructor(proxyClass, proxyParameters.getNameLookup(_nameLookup));
 90   
     }
 91   
 
 92  3
     private void addClearCachedMethod(ClassFab classFab)
 93   
     {
 94  3
         classFab.addMethod(
 95   
             Modifier.PROTECTED,
 96   
             new MethodSignature(void.class, "_clearCachedReferences", null, null),
 97   
             "_remote = null;");
 98   
     }
 99   
 
 100  3
     private void addLookupMethod(
 101   
         ClassFab classFab,
 102   
         Class homeInterface,
 103   
         Class remoteInterface,
 104   
         String jndiName)
 105   
     {
 106  3
         String homeInterfaceName = homeInterface.getName();
 107   
 
 108  3
         BodyBuilder builder = new BodyBuilder();
 109   
 
 110  3
         builder.begin();
 111   
 
 112  3
         builder.addln("if (_remote != null)");
 113  3
         builder.addln("  return _remote;");
 114   
 
 115  3
         builder.add(homeInterfaceName);
 116  3
         builder.add(" home = (");
 117  3
         builder.add(homeInterfaceName);
 118  3
         builder.add(") _lookup(");
 119  3
         builder.addQuoted(jndiName);
 120  3
         builder.addln(");");
 121   
 
 122  3
         builder.add("try");
 123  3
         builder.begin();
 124  3
         builder.add("_remote = home.create();");
 125  3
         builder.end();
 126  3
         builder.add("catch (javax.ejb.CreateException ex)");
 127  3
         builder.begin();
 128  3
         builder.add("throw new java.rmi.RemoteException(ex.getMessage(), ex);");
 129  3
         builder.end();
 130   
 
 131  3
         builder.add("return _remote;");
 132   
 
 133  3
         builder.end();
 134   
 
 135  3
         classFab.addMethod(
 136   
             Modifier.SYNCHRONIZED + Modifier.PRIVATE,
 137   
             new MethodSignature(
 138   
                 remoteInterface,
 139   
                 "_lookupRemote",
 140   
                 null,
 141   
                 new Class[] { RemoteException.class }),
 142   
             builder.toString());
 143   
 
 144   
     }
 145   
 
 146  3
     private void addServiceMethods(
 147   
         ClassFab classFab,
 148   
         Class serviceInterface,
 149   
         String serviceId,
 150   
         String jndiName)
 151   
     {
 152  3
         Method[] methods = serviceInterface.getMethods();
 153  3
         boolean toString = false;
 154   
 
 155  3
         for (int i = 0; i < methods.length; i++)
 156   
         {
 157  18
             Method m = methods[i];
 158   
 
 159  18
             addServiceMethod(classFab, m);
 160   
 
 161  18
             toString |= ClassFabUtils.isToString(m);
 162   
         }
 163   
 
 164  3
         if (!toString)
 165  3
             addToStringMethod(classFab, serviceInterface, serviceId, jndiName);
 166   
     }
 167   
 
 168  18
     private void addServiceMethod(ClassFab classFab, Method m)
 169   
     {
 170  18
         String methodName = m.getName();
 171   
 
 172  18
         boolean isVoid = m.getReturnType().equals(Void.TYPE);
 173   
 
 174  18
         BodyBuilder builder = new BodyBuilder();
 175   
 
 176  18
         builder.begin();
 177   
 
 178  18
         builder.addln("boolean first = true;");
 179  18
         builder.add("while (true)");
 180  18
         builder.begin();
 181   
 
 182  18
         builder.add("try");
 183  18
         builder.begin();
 184   
 
 185  18
         if (!isVoid)
 186  15
             builder.add("return ");
 187   
 
 188  18
         builder.add("_lookupRemote().");
 189  18
         builder.add(methodName);
 190  18
         builder.addln("($$);");
 191   
 
 192  18
         if (isVoid)
 193  3
             builder.addln("return;");
 194   
 
 195  18
         builder.end(); // try
 196   
 
 197  18
         builder.add("catch (java.rmi.RemoteException ex)");
 198  18
         builder.begin();
 199   
 
 200  18
         builder.addln("if (first)");
 201  18
         builder.begin();
 202   
 
 203  18
         builder.addln("_handleRemoteException(ex);");
 204  18
         builder.addln("first = false;");
 205   
 
 206  18
         builder.end(); // if
 207  18
         builder.addln("else");
 208  18
         builder.add("  throw ex;");
 209  18
         builder.end(); // catch
 210  18
         builder.end(); // while
 211  18
         builder.end();
 212   
 
 213  18
         classFab.addMethod(Modifier.PUBLIC, new MethodSignature(m), builder.toString());
 214   
     }
 215   
 
 216  3
     private void addToStringMethod(
 217   
         ClassFab classFab,
 218   
         Class serviceInterface,
 219   
         String serviceId,
 220   
         String jndiName)
 221   
     {
 222  3
         ClassFabUtils.addToStringMethod(
 223   
             classFab,
 224   
             ImplMessages.ejbProxyDescription(serviceId, serviceInterface, jndiName));
 225   
     }
 226   
 
 227  3
     private void addConstructor(ClassFab classFab)
 228   
     {
 229  3
         classFab.addConstructor(
 230   
             new Class[] { NameLookup.class, RemoteExceptionCoordinator.class },
 231   
             null,
 232   
             "super($1, $2);");
 233   
     }
 234   
 
 235  3
     private Object invokeConstructor(Class proxyClass, NameLookup nameLookup)
 236   
     {
 237  3
         try
 238   
         {
 239  3
             Constructor c =
 240   
                 proxyClass.getConstructor(
 241   
                     new Class[] { NameLookup.class, RemoteExceptionCoordinator.class });
 242   
 
 243  3
             return c.newInstance(new Object[] { nameLookup, _coordinator });
 244   
         }
 245   
         catch (Exception ex)
 246   
         {
 247  0
             throw new ApplicationRuntimeException(ex);
 248   
         }
 249   
     }
 250   
 
 251  3
     public void setClassFactory(ClassFactory factory)
 252   
     {
 253  3
         _classFactory = factory;
 254   
     }
 255   
 
 256  3
     public void setCoordinator(RemoteExceptionCoordinator coordinator)
 257   
     {
 258  3
         _coordinator = coordinator;
 259   
     }
 260   
 
 261  3
     public void setNameLookup(NameLookup lookup)
 262   
     {
 263  3
         _nameLookup = lookup;
 264   
     }
 265   
 
 266   
 }
 267