de.jiac.micro.reflect.ServiceContextGenerator.java Source code

Java tutorial

Introduction

Here is the source code for de.jiac.micro.reflect.ServiceContextGenerator.java

Source

/*
 * MicroJIAC - A Lightweight Agent Framework
 * This file is part of MicroJIAC MIDlet-Maven-Plugin.
 *
 * Copyright (c) 2007-2012 DAI-Labor, Technische Universitt Berlin
 *
 * This library includes software developed at DAI-Labor, Technische
 * Universitt 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("}");
    }
}