/* * MicroJIAC - A Lightweight Agent Framework * This file is part of MicroJIAC MIDlet-Maven-Plugin. * * Copyright (c) 2007-2012 DAI-Labor, Technische Universität Berlin * * This library includes software developed at DAI-Labor, Technische * Universität Berlin (http://www.dai-labor.de) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ /* * $Id$ */ package de.jiac.micro.reflect; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.Method; import org.apache.maven.plugin.logging.Log; import org.objectweb.asm.Type; import de.dailab.jiac.common.aamm.beans.MethodDescriptor; import de.jiac.micro.reflect.ClassInfoReducer.ReducedClassInfo; import de.jiac.micro.reflect.filter.IFilter; import de.jiac.micro.reflect.filter.ServiceFilter; /** * @author Marcel Patzlaff * @version $Revision:$ */ public class ServiceContextGenerator extends GeneratorUtil { private static final String EMULATION_CLASS_PREFIX= "ContextFor_"; private static final String SUPER_CLASS= "de.jiac.micro.ext.service.impl.EmulatedProxyServiceContext"; public static void generateContexts(Log logger, File outputFolder, ReducedClassInfo[] classes) throws IOException { for(ReducedClassInfo rci : classes) { Class<?> cls= rci.getClassDescriptor().getClazz(); if((rci.mask & IFilter.CONTEXT) != 0 && !cls.getName().equals(ServiceFilter.ISERVICE_CLASS_NAME)) { StringBuilder contextName= new StringBuilder(cls.getName().replace('$', '_')); int dot= contextName.lastIndexOf("."); contextName.insert(dot < 0 ? 0 : dot + 1, EMULATION_CLASS_PREFIX); logger.info("generate context: " + contextName); File packageFolder= outputFolder; String packStr= null; if(dot > 0) { packStr= contextName.substring(0, dot); packageFolder= new File(outputFolder, packStr.replace('.', File.separatorChar)); } if(!packageFolder.exists()) { packageFolder.mkdirs(); } String clsName= contextName.substring(dot < 0 ? 0 : dot + 1); File contextFile= new File(packageFolder, clsName + ".java"); contextFile.createNewFile(); PrintStream out= new PrintStream(new FileOutputStream(contextFile)); generateContext(out, packStr, clsName, rci); out.flush(); out.close(); } } } private static void generateContext(PrintStream out, String pack, String name, ReducedClassInfo rci) { printHeader(out); if(pack != null) { out.println("package " + pack + ";"); } String serviceName= getJavaSourceClassName(rci.getClassDescriptor().getClazz()); out.println("public final class " + name + " extends " + SUPER_CLASS + " implements " + serviceName + " {"); // constructor out.println("\tpublic " + name + "() {"); out.println("\t\tsuper(" + serviceName + ".class);"); out.println("\t}"); // methods for(MethodDescriptor md : rci.originalInfo.getMethodDescriptors()) { Method m= md.getMethod(); String mDescr= Type.getMethodDescriptor(m); if(!m.getName().equals("doGetDescription") && !mDescr.equals("()Ljava/lang/String;")) { Type rType= Type.getReturnType(m); Class<?>[] aClasses= m.getParameterTypes(); Type[] aTypes= Type.getArgumentTypes(m); out.append("\tpublic " + rType.getClassName() + " " + m.getName() + "("); for(int i= 0; i < aTypes.length; ++i) { out.append(aTypes[i].getClassName() + " arg" + i); if(i < aTypes.length - 1) { out.append(", "); } } out.println(") {"); if(!m.getName().startsWith("do")) { out.println("\t\tthrow new RuntimeException(\"unsupported operation " + m.getName() + "\");"); } else { StringBuilder call= new StringBuilder(); call.append("searchAndInvoke(\"" + m.getName() + "\", \"" + mDescr + "\", "); if(aClasses.length <= 0) { call.append("null)"); } else { call.append("new Object[]{"); for(int i= 0; i < aClasses.length; ++i) { insertToObjectConversion(call, aClasses[i], "arg" + i); if(i < aClasses.length - 1) { call.append(", "); } } call.append("})"); } if(rType.getSort() != Type.VOID) { out.print("\t\treturn "); insertFromObjectConversion(out, m.getReturnType(), call); out.println(";"); } else { out.append("\t\t").append(call); out.println(";"); } } out.println("\t}"); } } out.println("}"); } }