00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.core.component.gen;
00032
00033 import java.lang.reflect.Method;
00034 import java.lang.reflect.ParameterizedType;
00035 import java.util.List;
00036
00037 import javassist.ClassPool;
00038 import javassist.CtClass;
00039 import javassist.CtMethod;
00040 import javassist.CtNewMethod;
00041
00042 import org.apache.log4j.Logger;
00043 import org.objectweb.proactive.core.component.exceptions.InterfaceGenerationFailedException;
00044 import org.objectweb.proactive.core.component.type.ProActiveInterfaceType;
00045 import org.objectweb.proactive.core.util.ClassDataCache;
00046 import org.objectweb.proactive.core.util.log.Loggers;
00047 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00048
00049 public class GatherInterfaceGenerator {
00050
00051 protected static final transient ClassPool pool = ClassPool.getDefault();
00052 private static Logger gatherLogger = ProActiveLogger.getLogger(Loggers.COMPONENTS_GATHERCAST);
00053
00054 public static Class generateInterface(ProActiveInterfaceType itfType) throws InterfaceGenerationFailedException {
00055 Class generated = null;
00056 String gatherProxyItfName = Utils.getGatherProxyItfClassName(itfType);
00057 try {
00058
00059
00060 generated = Thread.currentThread().getContextClassLoader().loadClass(gatherProxyItfName);
00061 } catch (ClassNotFoundException cnfe) {
00062 byte[] bytecode = generateInterfaceByteCode(gatherProxyItfName);
00063
00064 try {
00065
00066 generated = Utils.defineClass(gatherProxyItfName, bytecode);
00067 } catch (Exception e) {
00068 e.printStackTrace();
00069 return null;
00070 }
00071 }
00072
00073 return generated;
00074 }
00075
00076
00077
00078
00079 static byte[] generateInterfaceByteCode(String gatherProxyItfName) {
00080 if (ClassDataCache.instance().getClassData(gatherProxyItfName) != null) {
00081 return ClassDataCache.instance().getClassData(gatherProxyItfName);
00082 }
00083 try {
00084 Class serverItfClass = Class.forName(Utils.getInterfaceSignatureFromGathercastProxyClassName(gatherProxyItfName));
00085 CtClass repGatherItfClass = pool.makeInterface(gatherProxyItfName);
00086 Method[] serverItfMethods = serverItfClass.getMethods();
00087
00088 CtMethod[] repServerItfMethods = new CtMethod[serverItfMethods.length];
00089
00090 for (int i = 0; i < serverItfMethods.length; i++) {
00091
00092 CtClass repReturnType = null;
00093 java.lang.reflect.Type returnType = serverItfMethods[i].getGenericReturnType();
00094 CtClass[] repParameterTypes = new CtClass[serverItfMethods[i].getParameterTypes().length];
00095
00096 if (Void.TYPE == returnType) {
00097 repReturnType = CtClass.voidType;
00098 } else {
00099 if (!(returnType instanceof ParameterizedType)) {
00100 throw new InterfaceGenerationFailedException("gather method " + serverItfMethods[i].toGenericString() + " in gather interface of signature " + serverItfClass.getName() + " must return a parameterized list or void");
00101 }
00102
00103 if (!(List.class.isAssignableFrom((Class)((ParameterizedType)returnType).getRawType()))) {
00104 throw new InterfaceGenerationFailedException("gather method " + serverItfMethods[i].toGenericString() + " in gather interface " + serverItfClass.getName() + " must return a parameterized list or void");
00105 }
00106 java.lang.reflect.Type[] actualTypeArguments = ((ParameterizedType)returnType).getActualTypeArguments();
00107 if (actualTypeArguments.length != 1) {
00108 throw new InterfaceGenerationFailedException("gather method " + serverItfMethods[i].toGenericString() + " in gather interface " + serverItfClass.getName() + " must return a parameterized type with one parameter");
00109 }
00110 repReturnType = pool.get(((Class)(((ParameterizedType)returnType).getActualTypeArguments()[0])).getName());
00111 }
00112
00113 java.lang.reflect.Type[] paramTypes = serverItfMethods[i].getGenericParameterTypes();
00114 for (int j = 0; j < paramTypes.length; j++) {
00115 java.lang.reflect.Type paramType = paramTypes[j];
00116 if (!(paramType instanceof ParameterizedType)) {
00117 throw new InterfaceGenerationFailedException("gather method " + serverItfMethods[i].toGenericString() + " in gather interface " + serverItfClass.getName() + " must have type-parameterized parameter types");
00118 }
00119 java.lang.reflect.Type[] actualTypeArguments = ((ParameterizedType)paramType).getActualTypeArguments();
00120 if (actualTypeArguments.length != 1) {
00121 throw new InterfaceGenerationFailedException("gather method " + serverItfMethods[i].toGenericString() + " in gather interface " + serverItfClass.getName() + " must have type-parameterized parameters with only one parameterizing element");
00122 }
00123 repParameterTypes[j] = pool.get(((Class)actualTypeArguments[0]).getName());
00124 }
00125
00126
00127 Class[] exceptions = serverItfMethods[i].getExceptionTypes();
00128 CtClass[] repExceptions = new CtClass[exceptions.length];
00129 for (int j = 0; j < exceptions.length; j++) {
00130 repExceptions[j] = pool.get(exceptions[j].getName());
00131 }
00132
00133
00134 repServerItfMethods[i] = CtNewMethod.abstractMethod(repReturnType, serverItfMethods[i].getName(), repParameterTypes, repExceptions, repGatherItfClass);
00135
00136 repGatherItfClass.addMethod(repServerItfMethods[i]);
00137
00138
00139 }
00140
00141
00142
00143
00144
00145 byte[] bytecode = repGatherItfClass.toBytecode();
00146 ClassDataCache.instance().addClassData(gatherProxyItfName,
00147 repGatherItfClass.toBytecode());
00148
00149
00150
00151
00152
00153
00154
00155
00156 return bytecode;
00157 } catch (Exception e) {
00158 e.printStackTrace();
00159 gatherLogger.error("cannot generate gather proxy interface class " + gatherProxyItfName );
00160 return null;
00161 }
00162
00163 }
00164
00165 }