Clover coverage report - Code Coverage for hivemind-lib release 1.0
Coverage timestamp: Wed Sep 22 2004 08:05:53 EDT
file stats: LOC: 265   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%
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.Modifier;
 19   
 import java.rmi.RemoteException;
 20   
 import java.util.List;
 21   
 
 22   
 import org.apache.commons.logging.Log;
 23   
 import org.apache.hivemind.ApplicationRuntimeException;
 24   
 import org.apache.hivemind.ServiceImplementationFactory;
 25   
 import org.apache.hivemind.impl.BaseLocatable;
 26   
 import org.apache.hivemind.internal.Module;
 27   
 import org.apache.hivemind.lib.NameLookup;
 28   
 import org.apache.hivemind.lib.RemoteExceptionCoordinator;
 29   
 import org.apache.hivemind.service.BodyBuilder;
 30   
 import org.apache.hivemind.service.ClassFab;
 31   
 import org.apache.hivemind.service.ClassFabUtils;
 32   
 import org.apache.hivemind.service.ClassFactory;
 33   
 import org.apache.hivemind.service.MethodIterator;
 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(
 74   
                 proxyClassName,
 75   
                 AbstractEJBProxy.class,
 76   
                 invokingModule.getClassResolver().getClassLoader());
 77   
 
 78  3
         classFab.addInterface(serviceInterface);
 79   
 
 80  3
         classFab.addField("_remote", serviceInterface);
 81   
 
 82  3
         addClearCachedMethod(classFab);
 83   
 
 84  3
         addLookupMethod(classFab, homeInterface, serviceInterface, jndiName);
 85   
 
 86  3
         addServiceMethods(classFab, serviceInterface, serviceId, jndiName);
 87   
 
 88  3
         addConstructor(classFab);
 89   
 
 90  3
         Class proxyClass = classFab.createClass();
 91   
 
 92  3
         return invokeConstructor(proxyClass, proxyParameters.getNameLookup(_nameLookup));
 93   
     }
 94   
 
 95  3
     private void addClearCachedMethod(ClassFab classFab)
 96   
     {
 97  3
         classFab.addMethod(
 98   
             Modifier.PROTECTED,
 99   
             new MethodSignature(void.class, "_clearCachedReferences", null, null),
 100   
             "_remote = null;");
 101   
     }
 102   
 
 103  3
     private void addLookupMethod(
 104   
         ClassFab classFab,
 105   
         Class homeInterface,
 106   
         Class remoteInterface,
 107   
         String jndiName)
 108   
     {
 109  3
         String homeInterfaceName = homeInterface.getName();
 110   
 
 111  3
         BodyBuilder builder = new BodyBuilder();
 112   
 
 113  3
         builder.begin();
 114   
 
 115  3
         builder.addln("if (_remote != null)");
 116  3
         builder.addln("  return _remote;");
 117   
 
 118  3
         builder.add(homeInterfaceName);
 119  3
         builder.add(" home = (");
 120  3
         builder.add(homeInterfaceName);
 121  3
         builder.add(") _lookup(");
 122  3
         builder.addQuoted(jndiName);
 123  3
         builder.addln(");");
 124   
 
 125  3
         builder.add("try");
 126  3
         builder.begin();
 127  3
         builder.add("_remote = home.create();");
 128  3
         builder.end();
 129  3
         builder.add("catch (javax.ejb.CreateException ex)");
 130  3
         builder.begin();
 131  3
         builder.add("throw new java.rmi.RemoteException(ex.getMessage(), ex);");
 132  3
         builder.end();
 133   
 
 134  3
         builder.add("return _remote;");
 135   
 
 136  3
         builder.end();
 137   
 
 138  3
         classFab.addMethod(
 139   
             Modifier.SYNCHRONIZED + Modifier.PRIVATE,
 140   
             new MethodSignature(
 141   
                 remoteInterface,
 142   
                 "_lookupRemote",
 143   
                 null,
 144   
                 new Class[] { RemoteException.class }),
 145   
             builder.toString());
 146   
 
 147   
     }
 148   
 
 149  3
     private void addServiceMethods(
 150   
         ClassFab classFab,
 151   
         Class serviceInterface,
 152   
         String serviceId,
 153   
         String jndiName)
 154   
     {
 155  3
         MethodIterator mi = new MethodIterator(serviceInterface);
 156   
 
 157  3
         while (mi.hasNext())
 158   
         {
 159  18
             addServiceMethod(classFab, mi.next());
 160   
         }
 161   
 
 162  3
         if (!mi.getToString())
 163  3
             addToStringMethod(classFab, serviceInterface, serviceId, jndiName);
 164   
     }
 165   
 
 166  18
     private void addServiceMethod(ClassFab classFab, MethodSignature sig)
 167   
     {
 168  18
         String methodName = sig.getName();
 169   
 
 170  18
         boolean isVoid = sig.getReturnType().equals(Void.TYPE);
 171   
 
 172  18
         BodyBuilder builder = new BodyBuilder();
 173   
 
 174  18
         builder.begin();
 175   
 
 176  18
         builder.addln("boolean first = true;");
 177  18
         builder.add("while (true)");
 178  18
         builder.begin();
 179   
 
 180  18
         builder.add("try");
 181  18
         builder.begin();
 182   
 
 183  18
         if (!isVoid)
 184  15
             builder.add("return ");
 185   
 
 186  18
         builder.add("_lookupRemote().");
 187  18
         builder.add(methodName);
 188  18
         builder.addln("($$);");
 189   
 
 190  18
         if (isVoid)
 191  3
             builder.addln("return;");
 192   
 
 193  18
         builder.end(); // try
 194   
 
 195  18
         builder.add("catch (java.rmi.RemoteException ex)");
 196  18
         builder.begin();
 197   
 
 198  18
         builder.addln("if (first)");
 199  18
         builder.begin();
 200   
 
 201  18
         builder.addln("_handleRemoteException(ex);");
 202  18
         builder.addln("first = false;");
 203   
 
 204  18
         builder.end(); // if
 205  18
         builder.addln("else");
 206  18
         builder.add("  throw ex;");
 207  18
         builder.end(); // catch
 208  18
         builder.end(); // while
 209  18
         builder.end();
 210   
 
 211  18
         classFab.addMethod(Modifier.PUBLIC, sig, builder.toString());
 212   
     }
 213   
 
 214  3
     private void addToStringMethod(
 215   
         ClassFab classFab,
 216   
         Class serviceInterface,
 217   
         String serviceId,
 218   
         String jndiName)
 219   
     {
 220  3
         ClassFabUtils.addToStringMethod(
 221   
             classFab,
 222   
             ImplMessages.ejbProxyDescription(serviceId, serviceInterface, jndiName));
 223   
     }
 224   
 
 225  3
     private void addConstructor(ClassFab classFab)
 226   
     {
 227  3
         classFab.addConstructor(
 228   
             new Class[] { NameLookup.class, RemoteExceptionCoordinator.class },
 229   
             null,
 230   
             "super($1, $2);");
 231   
     }
 232   
 
 233  3
     private Object invokeConstructor(Class proxyClass, NameLookup nameLookup)
 234   
     {
 235  3
         try
 236   
         {
 237  3
             Constructor c =
 238   
                 proxyClass.getConstructor(
 239   
                     new Class[] { NameLookup.class, RemoteExceptionCoordinator.class });
 240   
 
 241  3
             return c.newInstance(new Object[] { nameLookup, _coordinator });
 242   
         }
 243   
         catch (Exception ex)
 244   
         {
 245  0
             throw new ApplicationRuntimeException(ex);
 246   
         }
 247   
     }
 248   
 
 249  3
     public void setClassFactory(ClassFactory factory)
 250   
     {
 251  3
         _classFactory = factory;
 252   
     }
 253   
 
 254  3
     public void setCoordinator(RemoteExceptionCoordinator coordinator)
 255   
     {
 256  3
         _coordinator = coordinator;
 257   
     }
 258   
 
 259  3
     public void setNameLookup(NameLookup lookup)
 260   
     {
 261  3
         _nameLookup = lookup;
 262   
     }
 263   
 
 264   
 }
 265