2009/04/15 - Apache HiveMind has been retired.

For more information, please explore the Attic.

Clover coverage report - Code Coverage for hivemind release 1.2.1
Coverage timestamp: Fri Feb 10 2006 16:33:43 PST
file stats: LOC: 338   Methods: 16
NCLOC: 222   Classes: 2
 
 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  1086 AddedConstructor(Class[] parameterTypes, Class[] exceptionTypes, String body)
 59    {
 60  1086 _parameterTypes = parameterTypes;
 61  1086 _exceptionTypes = exceptionTypes;
 62  1086 _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  2096 public ClassFabImpl(CtClassSource source, CtClass ctClass)
 127    {
 128  2096 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  5148 public void addField(String name, Class type)
 249    {
 250  5148 CtClass ctType = convertClass(type);
 251   
 252  5148 try
 253    {
 254  5148 CtField field = new CtField(ctType, name, getCtClass());
 255  5148 field.setModifiers(Modifier.PRIVATE);
 256   
 257  5148 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  2441 public boolean containsMethod( MethodSignature ms )
 269    {
 270  2441 return _methods.get( ms ) != null;
 271    }
 272   
 273  10649 public MethodFab addMethod(int modifiers, MethodSignature ms, String body)
 274    {
 275  10649 if (_methods.get(ms) != null)
 276  1 throw new ApplicationRuntimeException(ServiceMessages.duplicateMethodInClass(ms, this));
 277   
 278  10648 CtClass ctReturnType = convertClass(ms.getReturnType());
 279   
 280  10648 CtClass[] ctParameters = convertClasses(ms.getParameterTypes());
 281  10648 CtClass[] ctExceptions = convertClasses(ms.getExceptionTypes());
 282   
 283  10648 CtMethod method = new CtMethod(ctReturnType, ms.getName(), ctParameters, getCtClass());
 284   
 285  10648 try
 286    {
 287  10648 method.setModifiers(modifiers);
 288  10648 method.setBody(body);
 289  10647 method.setExceptionTypes(ctExceptions);
 290   
 291  10647 getCtClass().addMethod(method);
 292    }
 293    catch (Exception ex)
 294    {
 295  1 throw new ApplicationRuntimeException(ServiceMessages.unableToAddMethod(
 296    ms,
 297    getCtClass(),
 298    ex), ex);
 299    }
 300   
 301    // Return a MethodFab so the caller can add catches.
 302   
 303  10647 MethodFab result = new MethodFabImpl(getSource(), ms, method, body);
 304   
 305  10647 _methods.put(ms, result);
 306   
 307  10647 return result;
 308    }
 309   
 310  2 public MethodFab getMethodFab(MethodSignature ms)
 311    {
 312  2 return (MethodFab) _methods.get(ms);
 313    }
 314   
 315  1087 public void addConstructor(Class[] parameterTypes, Class[] exceptions, String body)
 316    {
 317  1087 CtClass[] ctParameters = convertClasses(parameterTypes);
 318  1087 CtClass[] ctExceptions = convertClasses(exceptions);
 319   
 320  1087 try
 321    {
 322  1087 CtConstructor constructor = new CtConstructor(ctParameters, getCtClass());
 323  1087 constructor.setExceptionTypes(ctExceptions);
 324  1087 constructor.setBody(body);
 325   
 326  1086 getCtClass().addConstructor(constructor);
 327   
 328  1086 _constructors.add(new AddedConstructor(parameterTypes, exceptions, body));
 329    }
 330    catch (Exception ex)
 331    {
 332  1 throw new ApplicationRuntimeException(ServiceMessages.unableToAddConstructor(
 333    getCtClass(),
 334    ex), ex);
 335    }
 336    }
 337   
 338    }