org/objectweb/proactive/core/component/gen/GatherInterfaceGenerator.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
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 //          try to fetch the class from the default class loader
00060             generated = Thread.currentThread().getContextClassLoader().loadClass(gatherProxyItfName);
00061         } catch (ClassNotFoundException cnfe) {
00062             byte[] bytecode = generateInterfaceByteCode(gatherProxyItfName);
00063 
00064             try {
00065             // convert the bytes into a Class
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 //        CtMethod[] resultingServerItfMethods = new CtMethod[serverItfMethods.length];
00088         CtMethod[] repServerItfMethods = new CtMethod[serverItfMethods.length];
00089 
00090         for (int i = 0; i < serverItfMethods.length; i++) {
00091             // get parameterizing types for return type and parameters
00092             CtClass repReturnType = null;
00093             java.lang.reflect.Type returnType = serverItfMethods[i].getGenericReturnType();
00094             CtClass[] repParameterTypes = new CtClass[serverItfMethods[i].getParameterTypes().length];
00095             // return type
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             // parameters types
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             // exceptions
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 //            System.out.println("[GATHER_ITF_GEN] added method " + repServerItfMethods[i] + " matching method " + serverItfMethods[i]);
00138             
00139         }
00140 
00141 //        repGatherItfClass.writeFile("generated/");
00142 //        System.out.println("[JAVASSIST] generated gather interface : " +
00143 //                      gatherProxyItfName);
00144         
00145         byte[] bytecode = repGatherItfClass.toBytecode();
00146         ClassDataCache.instance().addClassData(gatherProxyItfName,
00147                         repGatherItfClass.toBytecode());
00148         
00149 //            System.out.println("added " + gatherProxyItfName + " to cache");
00150 //            System.out.println("cache is now " + ClassDataCache.instance().toString());
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 }

Generated on Mon Jan 22 15:16:06 2007 for ProActive by  doxygen 1.5.1