1 package org.ozoneDB.tools.OPP.srcgen.direct; 9 10 import org.ozoneDB.tools.OPP.srcgen.MethodResolver; 11 import org.ozoneDB.tools.OPP.srcgen.ResolverException; 12 import org.ozoneDB.tools.OPP.srcgen.ClassBuilder; 13 import org.ozoneDB.tools.OPP.srcgen.BuilderException; 14 import org.ozoneDB.tools.OPP.srcgen.ClassDirector; 15 import org.ozoneDB.tools.OPP.srcgen.resolve.UpdateMethodBagMapAdapter; 16 import org.ozoneDB.tools.OPP.message.MessageWriter; 17 import org.ozoneDB.core.Lock; 18 import org.ozoneDB.OzoneRemote; 19 import org.ozoneDB.OzoneCompatible; 20 21 import java.util.Set ; 22 import java.util.HashSet ; 23 import java.util.Map ; 24 import java.util.HashMap ; 25 import java.lang.reflect.Method ; 26 import java.lang.reflect.Constructor ; 27 28 34 public class ReflectionClassDirector implements ClassDirector { 35 private MethodResolver resolver; 36 private Class filterInterface; 37 private Set processedMethods; 38 private MessageWriter msgWriter; 39 40 public ReflectionClassDirector(MessageWriter msgListener, MethodResolver resolver) { 41 this(msgListener, resolver, OzoneRemote.class); 42 } 43 44 public ReflectionClassDirector(MessageWriter msgListener, MethodResolver resolver, Class filterInterface) { 45 this.msgWriter = msgListener; 46 this.resolver = resolver; 47 this.filterInterface = filterInterface; 48 this.processedMethods = new HashSet (); 49 } 50 51 public void build(String fullClassName, ClassBuilder builder) throws BuilderException { 52 msgWriter.startGeneration("Processing " + fullClassName); 53 try { 54 Map updateMethods = new HashMap (); 55 processedMethods.clear(); 56 msgWriter.startGeneration("Resolving update methods"); 57 MethodResolver.UpdateMethodBag methodBag = new UpdateMethodBagMapAdapter(updateMethods); 58 try { 59 resolver.resolveMethods(fullClassName, methodBag); 60 } catch (ResolverException e) { 61 throw new BuilderException(e); 62 } finally { 63 msgWriter.endGeneration(); 64 } 65 Class sourceClass; 66 try { 67 sourceClass = Class.forName(fullClassName); 68 if (sourceClass.isInterface()) { 69 throw new BuilderException(fullClassName + " is an interface, should be a class"); 70 } 71 if (!OzoneCompatible.class.isAssignableFrom(sourceClass)) { 72 throw new BuilderException("The class " + fullClassName + " must extend OzoneObject or implement OzoneCompatible"); 73 } 74 } catch (ClassNotFoundException e) { 75 throw new BuilderException(e); 76 } 77 Class clazz = sourceClass.getSuperclass(); 78 String superClassName; 79 if (clazz == null) { 80 throw new BuilderException("No superclass exist for " + fullClassName); 81 } else { 82 superClassName = clazz.getName(); 83 } 85 86 String interfaces[] = getClassNames(sourceClass.getInterfaces()); 87 88 builder.init(msgWriter); 90 91 builder.beginClass(sourceClass.getModifiers(), fullClassName, superClassName, interfaces); 93 94 Constructor constructors[] = sourceClass.getConstructors(); 96 for (int i = 0; i < constructors.length; ++i) { 97 Constructor constructor = constructors[i]; 98 ClassBuilder.Parameter parameters[] = getParameters(constructor.getParameterTypes()); 99 String exceptions[] = getClassNames(constructor.getExceptionTypes()); 100 builder.makeConstructor(constructor.getModifiers(), parameters, exceptions); 101 } 102 Class itfs[] = sourceClass.getInterfaces(); 103 for (int i = 0; i < itfs.length; i++) { 104 Class itf = itfs[i]; 105 if (!filterInterface.isAssignableFrom(itf)) 107 continue; 108 buildMethodsDeep(itf, builder, updateMethods); 109 } 110 111 112 builder.endClass(); 114 } finally { 115 msgWriter.endGeneration(); 116 } 117 } 118 119 private void buildMethodsDeep(Class itf, ClassBuilder builder, Map updateMethods) throws BuilderException { 120 Method methods[] = itf.getMethods(); 122 for (int j = 0; j < methods.length; ++j) { 123 Method method = methods[j]; 124 if (isProcessedAndMarkMethod(method)) 127 continue; 128 ClassBuilder.Parameter parameters[] = getParameters(method.getParameterTypes()); 129 String exceptions[] = getClassNames(method.getExceptionTypes()); 130 Integer lockLevel = updateMethods.keySet().contains(method.getName()) ? (Integer ) updateMethods.get(method.getName()) : new Integer (Lock.LEVEL_READ); 131 int iLevel = lockLevel.intValue(); 132 if (iLevel > Lock.LEVEL_READ) 133 msgWriter.info("update method [" + lockLevel + "]: " + method.getName()); 134 135 String retType = typecodeForClass(method.getReturnType()); 136 if (retType.equals("void")) 137 retType = null; 138 builder.makeMethod(method.getModifiers(), method.getName(), parameters, retType 139 , exceptions, lockLevel.intValue()); 140 } 141 } 142 143 private boolean isProcessedAndMarkMethod(Method method) { 144 StringBuffer signatureBuf = new StringBuffer (); 145 signatureBuf.append(" public " + typecodeForClass(method.getReturnType()) + " " + method.getName() + "("); 146 Class [] args = method.getParameterTypes(); 147 for (int i = 0; i < args.length; i++) { 148 if (i != 0) { 149 signatureBuf.append(", "); 150 } 151 signatureBuf.append(typecodeForClass(args[i]) + " arg" + i); 152 } 153 signatureBuf.append(")"); 154 String signatureStr = signatureBuf.toString(); 155 if (!processedMethods.contains(signatureStr)) { 156 msgWriter.debug("Processing method: " + signatureStr); 157 processedMethods.add(signatureStr); 158 return false; 159 } else { 160 return true; 161 } 162 } 163 164 169 private String getSourcecodeClassName(String cl) { 170 return cl.replace('$', '.'); 171 } 172 173 private String [] getClassNames(Class types[]) { 174 String classNames[] = new String [types.length]; 175 for (int i = 0; i < types.length; ++i) { 176 classNames[i] = getSourcecodeClassName(types[i].getName()); 177 } 178 return classNames; 179 } 180 181 protected String typecodeForClass(Class cl) { 182 String ret; 183 185 if (cl.isArray()) { 186 StringBuffer b = new StringBuffer (); 187 while (cl.isArray()) { 188 b.append("[]"); 189 cl = cl.getComponentType(); 190 } 191 b.insert(0, getSourcecodeClassName(cl.getName())); 192 ret = b.toString(); 193 } else { 194 196 ret = getSourcecodeClassName(cl.getName()); 197 } 198 return ret; 199 } 200 201 private ClassBuilder.Parameter[] getParameters(Class parameterTypes[]) { 202 ClassBuilder.Parameter parameters[] = new ClassBuilder.Parameter[parameterTypes.length]; 203 for (int j = 0; j < parameters.length; ++j) { 204 parameters[j] = new ClassBuilder.Parameter(typecodeForClass(parameterTypes[j]), "arg" + j, parameterTypes[j].getName(), 0); 205 } 206 return parameters; 207 } 208 } 209 | Popular Tags |