1 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 42 public class ClassFabImpl extends AbstractFab implements ClassFab 43 { 44 49 50 private class AddedConstructor 51 { 52 private Class [] _parameterTypes; 53 54 private Class [] _exceptionTypes; 55 56 private String _body; 57 58 AddedConstructor(Class [] parameterTypes, Class [] exceptionTypes, String body) 59 { 60 _parameterTypes = parameterTypes; 61 _exceptionTypes = exceptionTypes; 62 _body = body; 63 } 64 65 public String toString() 66 { 67 StringBuffer buffer = new StringBuffer (); 68 69 buffer.append("public "); 70 buffer.append(getCtClass().getName()); 71 72 buffer.append("("); 73 74 int count = size(_parameterTypes); 75 for (int i = 0; i < count; i++) 76 { 77 if (i > 0) 78 buffer.append(", "); 79 80 buffer.append(_parameterTypes[i].getName()); 81 82 buffer.append(" $"); 83 buffer.append(i + 1); 84 } 85 86 buffer.append(")"); 87 88 count = size(_exceptionTypes); 89 for (int i = 0; i < count; i++) 90 { 91 if (i == 0) 92 buffer.append("\n throws "); 93 else 94 buffer.append(", "); 95 96 buffer.append(_exceptionTypes[i].getName()); 97 } 98 99 buffer.append("\n"); 100 buffer.append(_body); 101 102 buffer.append("\n"); 103 104 return buffer.toString(); 105 } 106 107 private int size(Object [] array) 108 { 109 return array == null ? 0 : array.length; 110 } 111 } 112 113 116 private Map _methods = new HashMap (); 117 118 123 124 private List _constructors = new ArrayList (); 125 126 public ClassFabImpl(CtClassSource source, CtClass ctClass) 127 { 128 super(source, ctClass); 129 } 130 131 137 public String toString() 138 { 139 StringBuffer buffer = new StringBuffer ("ClassFab[\n"); 140 141 try 142 { 143 buildClassAndInheritance(buffer); 144 145 buildFields(buffer); 146 147 buildConstructors(buffer); 148 149 buildMethods(buffer); 150 151 } 152 catch (Exception ex) 153 { 154 buffer.append(" *** "); 155 buffer.append(ex); 156 } 157 158 buffer.append("\n]"); 159 160 return buffer.toString(); 161 } 162 163 164 private void buildMethods(StringBuffer buffer) 165 { 166 Iterator i = _methods.values().iterator(); 167 while (i.hasNext()) 168 { 169 170 MethodFab mf = (MethodFab) i.next(); 171 172 buffer.append("\n"); 173 buffer.append(mf); 174 buffer.append("\n"); 175 } 176 } 177 178 179 private void buildConstructors(StringBuffer buffer) 180 { 181 Iterator i = _constructors.iterator(); 182 183 while (i.hasNext()) 184 { 185 buffer.append("\n"); 186 buffer.append(i.next()); 187 } 188 } 189 190 191 private void buildFields(StringBuffer buffer) throws NotFoundException 192 { 193 CtField fields[] = getCtClass().getDeclaredFields(); 194 195 for (int i = 0; i < fields.length; i++) 196 { 197 buffer.append("\n"); 198 buffer.append(modifiers(fields[i].getModifiers())); 199 buffer.append(" "); 200 buffer.append(fields[i].getType().getName()); 201 buffer.append(" "); 202 buffer.append(fields[i].getName()); 203 buffer.append(";\n"); 204 } 205 } 206 207 208 private void buildClassAndInheritance(StringBuffer buffer) throws NotFoundException 209 { 210 buffer.append(modifiers(getCtClass().getModifiers())); 211 buffer.append(" class "); 212 buffer.append(getCtClass().getName()); 213 buffer.append(" extends "); 214 buffer.append(getCtClass().getSuperclass().getName()); 215 buffer.append("\n"); 216 217 CtClass[] interfaces = getCtClass().getInterfaces(); 218 219 if (interfaces.length > 0) 220 { 221 buffer.append(" implements "); 222 223 for (int i = 0; i < interfaces.length; i++) 224 { 225 if (i > 0) 226 buffer.append(", "); 227 228 buffer.append(interfaces[i].getName()); 229 } 230 231 buffer.append("\n"); 232 } 233 } 234 235 private String modifiers(int modifiers) 236 { 237 return Modifier.toString(modifiers); 238 } 239 240 243 String getName() 244 { 245 return getCtClass().getName(); 246 } 247 248 public void addField(String name, Class type) 249 { 250 CtClass ctType = convertClass(type); 251 252 try 253 { 254 CtField field = new CtField(ctType, name, getCtClass()); 255 field.setModifiers(Modifier.PRIVATE); 256 257 getCtClass().addField(field); 258 } 259 catch (CannotCompileException ex) 260 { 261 throw new ApplicationRuntimeException(ServiceMessages.unableToAddField( 262 name, 263 getCtClass(), 264 ex), ex); 265 } 266 } 267 268 public boolean containsMethod( MethodSignature ms ) 269 { 270 return _methods.get( ms ) != null; 271 } 272 273 public MethodFab addMethod(int modifiers, MethodSignature ms, String body) 274 { 275 if (_methods.get(ms) != null) 276 throw new ApplicationRuntimeException(ServiceMessages.duplicateMethodInClass(ms, this)); 277 278 CtClass ctReturnType = convertClass(ms.getReturnType()); 279 280 CtClass[] ctParameters = convertClasses(ms.getParameterTypes()); 281 CtClass[] ctExceptions = convertClasses(ms.getExceptionTypes()); 282 283 CtMethod method = new CtMethod(ctReturnType, ms.getName(), ctParameters, getCtClass()); 284 285 try 286 { 287 method.setModifiers(modifiers); 288 method.setBody(body); 289 method.setExceptionTypes(ctExceptions); 290 291 getCtClass().addMethod(method); 292 } 293 catch (Exception ex) 294 { 295 throw new ApplicationRuntimeException(ServiceMessages.unableToAddMethod( 296 ms, 297 getCtClass(), 298 ex), ex); 299 } 300 301 303 MethodFab result = new MethodFabImpl(getSource(), ms, method, body); 304 305 _methods.put(ms, result); 306 307 return result; 308 } 309 310 public MethodFab getMethodFab(MethodSignature ms) 311 { 312 return (MethodFab) _methods.get(ms); 313 } 314 315 public void addConstructor(Class [] parameterTypes, Class [] exceptions, String body) 316 { 317 CtClass[] ctParameters = convertClasses(parameterTypes); 318 CtClass[] ctExceptions = convertClasses(exceptions); 319 320 try 321 { 322 CtConstructor constructor = new CtConstructor(ctParameters, getCtClass()); 323 constructor.setExceptionTypes(ctExceptions); 324 constructor.setBody(body); 325 326 getCtClass().addConstructor(constructor); 327 328 _constructors.add(new AddedConstructor(parameterTypes, exceptions, body)); 329 } 330 catch (Exception ex) 331 { 332 throw new ApplicationRuntimeException(ServiceMessages.unableToAddConstructor( 333 getCtClass(), 334 ex), ex); 335 } 336 } 337 338 } | Popular Tags |