Clover coverage report - Code Coverage for hivemind release 1.1-alpha-2
Coverage timestamp: Wed Feb 23 2005 09:59:04 EST
file stats: LOC: 333   Methods: 15
NCLOC: 218   Classes: 2
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
ClassFabImpl.java 91.7% 97.1% 100% 96.5%
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.service.impl;
 16   
 
 17   
 import java.lang.reflect.Modifier;
 18   
 import java.util.ArrayList;
 19   
 import java.util.HashMap;
 20   
 import java.util.Iterator;
 21   
 import java.util.List;
 22   
 import java.util.Map;
 23   
 
 24   
 import javassist.CannotCompileException;
 25   
 import javassist.CtClass;
 26   
 import javassist.CtConstructor;
 27   
 import javassist.CtField;
 28   
 import javassist.CtMethod;
 29   
 import javassist.NotFoundException;
 30   
 
 31   
 import org.apache.hivemind.ApplicationRuntimeException;
 32   
 import org.apache.hivemind.service.ClassFab;
 33   
 import org.apache.hivemind.service.MethodFab;
 34   
 import org.apache.hivemind.service.MethodSignature;
 35   
 
 36   
 /**
 37   
  * Implementation of {@link org.apache.hivemind.service.ClassFab}. Hides, as much as possible, the
 38   
  * underlying library (Javassist).
 39   
  * 
 40   
  * @author Howard Lewis Ship
 41   
  */
 42   
 public class ClassFabImpl extends AbstractFab implements ClassFab
 43   
 {
 44   
     /**
 45   
      * Stores information about a constructor; used by toString().
 46   
      * 
 47   
      * @since 1.1
 48   
      */
 49   
 
 50   
     private class AddedConstructor
 51   
     {
 52   
         private Class[] _parameterTypes;
 53   
 
 54   
         private Class[] _exceptionTypes;
 55   
 
 56   
         private String _body;
 57   
 
 58  939
         AddedConstructor(Class[] parameterTypes, Class[] exceptionTypes, String body)
 59   
         {
 60  939
             _parameterTypes = parameterTypes;
 61  939
             _exceptionTypes = exceptionTypes;
 62  939
             _body = body;
 63   
         }
 64   
 
 65  1
         public String toString()
 66   
         {
 67  1
             StringBuffer buffer = new StringBuffer();
 68   
 
 69  1
             buffer.append("public ");
 70  1
             buffer.append(getCtClass().getName());
 71   
 
 72  1
             buffer.append("(");
 73   
 
 74  1
             int count = size(_parameterTypes);
 75  1
             for (int i = 0; i < count; i++)
 76   
             {
 77  2
                 if (i > 0)
 78  1
                     buffer.append(", ");
 79   
 
 80  2
                 buffer.append(_parameterTypes[i].getName());
 81   
 
 82  2
                 buffer.append(" $");
 83  2
                 buffer.append(i + 1);
 84   
             }
 85   
 
 86  1
             buffer.append(")");
 87   
 
 88  1
             count = size(_exceptionTypes);
 89  1
             for (int i = 0; i < count; i++)
 90   
             {
 91  2
                 if (i == 0)
 92  1
                     buffer.append("\n  throws ");
 93   
                 else
 94  1
                     buffer.append(", ");
 95   
 
 96  2
                 buffer.append(_exceptionTypes[i].getName());
 97   
             }
 98   
 
 99  1
             buffer.append("\n");
 100  1
             buffer.append(_body);
 101   
 
 102  1
             buffer.append("\n");
 103   
 
 104  1
             return buffer.toString();
 105   
         }
 106   
 
 107  2
         private int size(Object[] array)
 108   
         {
 109  2
             return array == null ? 0 : array.length;
 110   
         }
 111   
     }
 112   
 
 113   
     /**
 114   
      * Map of {@link MethodFab}keyed on {@link MethodSignature}.
 115   
      */
 116   
     private Map _methods = new HashMap();
 117   
 
 118   
     /**
 119   
      * List of {@link AddedConstructor}.
 120   
      * 
 121   
      * @since 1.1
 122   
      */
 123   
 
 124   
     private List _constructors = new ArrayList();
 125   
 
 126  1828
     public ClassFabImpl(CtClassSource source, CtClass ctClass)
 127   
     {
 128  1828
         super(source, ctClass);
 129   
     }
 130   
 
 131   
     /**
 132   
      * Returns a representation of the fabricated class, including inheritance, fields,
 133   
      * constructors, methods and method bodies.
 134   
      * 
 135   
      * @since 1.1
 136   
      */
 137  1
     public String toString()
 138   
     {
 139  1
         StringBuffer buffer = new StringBuffer("ClassFab[\n");
 140   
 
 141  1
         try
 142   
         {
 143  1
             buildClassAndInheritance(buffer);
 144   
 
 145  1
             buildFields(buffer);
 146   
 
 147  1
             buildConstructors(buffer);
 148   
 
 149  1
             buildMethods(buffer);
 150   
 
 151   
         }
 152   
         catch (Exception ex)
 153   
         {
 154  0
             buffer.append(" *** ");
 155  0
             buffer.append(ex);
 156   
         }
 157   
 
 158  1
         buffer.append("\n]");
 159   
 
 160  1
         return buffer.toString();
 161   
     }
 162   
 
 163   
     /** @since 1.1 */
 164  1
     private void buildMethods(StringBuffer buffer)
 165   
     {
 166  1
         Iterator i = _methods.values().iterator();
 167  1
         while (i.hasNext())
 168   
         {
 169   
 
 170  1
             MethodFab mf = (MethodFab) i.next();
 171   
 
 172  1
             buffer.append("\n");
 173  1
             buffer.append(mf);
 174  1
             buffer.append("\n");
 175   
         }
 176   
     }
 177   
 
 178   
     /** @since 1.1 */
 179  1
     private void buildConstructors(StringBuffer buffer)
 180   
     {
 181  1
         Iterator i = _constructors.iterator();
 182   
 
 183  1
         while (i.hasNext())
 184   
         {
 185  1
             buffer.append("\n");
 186  1
             buffer.append(i.next());
 187   
         }
 188   
     }
 189   
 
 190   
     /** @since 1.1 */
 191  1
     private void buildFields(StringBuffer buffer) throws NotFoundException
 192   
     {
 193  1
         CtField fields[] = getCtClass().getDeclaredFields();
 194   
 
 195  1
         for (int i = 0; i < fields.length; i++)
 196   
         {
 197  1
             buffer.append("\n");
 198  1
             buffer.append(modifiers(fields[i].getModifiers()));
 199  1
             buffer.append(" ");
 200  1
             buffer.append(fields[i].getType().getName());
 201  1
             buffer.append(" ");
 202  1
             buffer.append(fields[i].getName());
 203  1
             buffer.append(";\n");
 204   
         }
 205   
     }
 206   
 
 207   
     /** @since 1.1 */
 208  1
     private void buildClassAndInheritance(StringBuffer buffer) throws NotFoundException
 209   
     {
 210  1
         buffer.append(modifiers(getCtClass().getModifiers()));
 211  1
         buffer.append(" class ");
 212  1
         buffer.append(getCtClass().getName());
 213  1
         buffer.append(" extends ");
 214  1
         buffer.append(getCtClass().getSuperclass().getName());
 215  1
         buffer.append("\n");
 216   
 
 217  1
         CtClass[] interfaces = getCtClass().getInterfaces();
 218   
 
 219  1
         if (interfaces.length > 0)
 220   
         {
 221  1
             buffer.append("  implements ");
 222   
 
 223  1
             for (int i = 0; i < interfaces.length; i++)
 224   
             {
 225  2
                 if (i > 0)
 226  1
                     buffer.append(", ");
 227   
 
 228  2
                 buffer.append(interfaces[i].getName());
 229   
             }
 230   
 
 231  1
             buffer.append("\n");
 232   
         }
 233   
     }
 234   
 
 235  2
     private String modifiers(int modifiers)
 236   
     {
 237  2
         return Modifier.toString(modifiers);
 238   
     }
 239   
 
 240   
     /**
 241   
      * Returns the name of the class fabricated by this instance.
 242   
      */
 243  1
     String getName()
 244   
     {
 245  1
         return getCtClass().getName();
 246   
     }
 247   
 
 248  4497
     public void addField(String name, Class type)
 249   
     {
 250  4497
         CtClass ctType = convertClass(type);
 251   
 
 252  4497
         try
 253   
         {
 254  4497
             CtField field = new CtField(ctType, name, getCtClass());
 255  4497
             field.setModifiers(Modifier.PRIVATE);
 256   
 
 257  4497
             getCtClass().addField(field);
 258   
         }
 259   
         catch (CannotCompileException ex)
 260   
         {
 261  0
             throw new ApplicationRuntimeException(ServiceMessages.unableToAddField(
 262   
                     name,
 263   
                     getCtClass(),
 264   
                     ex), ex);
 265   
         }
 266   
     }
 267   
 
 268  9273
     public MethodFab addMethod(int modifiers, MethodSignature ms, String body)
 269   
     {
 270  9273
         if (_methods.get(ms) != null)
 271  1
             throw new ApplicationRuntimeException(ServiceMessages.duplicateMethodInClass(ms, this));
 272   
 
 273  9272
         CtClass ctReturnType = convertClass(ms.getReturnType());
 274   
 
 275  9272
         CtClass[] ctParameters = convertClasses(ms.getParameterTypes());
 276  9272
         CtClass[] ctExceptions = convertClasses(ms.getExceptionTypes());
 277   
 
 278  9272
         CtMethod method = new CtMethod(ctReturnType, ms.getName(), ctParameters, getCtClass());
 279   
 
 280  9272
         try
 281   
         {
 282  9272
             method.setModifiers(modifiers);
 283  9272
             method.setBody(body);
 284  9271
             method.setExceptionTypes(ctExceptions);
 285   
 
 286  9271
             getCtClass().addMethod(method);
 287   
         }
 288   
         catch (Exception ex)
 289   
         {
 290  1
             throw new ApplicationRuntimeException(ServiceMessages.unableToAddMethod(
 291   
                     ms,
 292   
                     getCtClass(),
 293   
                     ex), ex);
 294   
         }
 295   
 
 296   
         // Return a MethodFab so the caller can add catches.
 297   
 
 298  9271
         MethodFab result = new MethodFabImpl(getSource(), ms, method, body);
 299   
 
 300  9271
         _methods.put(ms, result);
 301   
 
 302  9271
         return result;
 303   
     }
 304   
 
 305  2
     public MethodFab getMethodFab(MethodSignature ms)
 306   
     {
 307  2
         return (MethodFab) _methods.get(ms);
 308   
     }
 309   
 
 310  940
     public void addConstructor(Class[] parameterTypes, Class[] exceptions, String body)
 311   
     {
 312  940
         CtClass[] ctParameters = convertClasses(parameterTypes);
 313  940
         CtClass[] ctExceptions = convertClasses(exceptions);
 314   
 
 315  940
         try
 316   
         {
 317  940
             CtConstructor constructor = new CtConstructor(ctParameters, getCtClass());
 318  940
             constructor.setExceptionTypes(ctExceptions);
 319  940
             constructor.setBody(body);
 320   
 
 321  939
             getCtClass().addConstructor(constructor);
 322   
 
 323  939
             _constructors.add(new AddedConstructor(parameterTypes, exceptions, body));
 324   
         }
 325   
         catch (Exception ex)
 326   
         {
 327  1
             throw new ApplicationRuntimeException(ServiceMessages.unableToAddConstructor(
 328   
                     getCtClass(),
 329   
                     ex), ex);
 330   
         }
 331   
     }
 332   
 
 333   
 }