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