view src/main/java/alice/test/reflection/DisposeManager.java @ 417:aadea6a59376 dispose

create MetaCodeSegment use reflection
author sugi
date Tue, 15 Jul 2014 00:06:10 +0900
parents b7a211b3f3e0
children 6e304a7a60e7
line wrap: on
line source

package alice.test.reflection;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import javassist.NotFoundException;
import javassist.bytecode.AccessFlag;

public class DisposeManager {
    private static DisposeManager instance = new DisposeManager(); 
    private ClassPool cp = ClassPool.getDefault();

    private DisposeManager(){}

    public static DisposeManager getInstance(){
        return instance;
    }

    public <T> void setCodeSegment(String managerKey, Class<T> clazz){
        CtClass cs = null;
        String metaName = "Meta"+clazz.getSimpleName();
        try {
            // if cannot get mataName Class go catch NotFoundException
            cs = cp.get(metaName);
            // already created
            Class<?> metaClazz = cp.getClassLoader().loadClass(metaName);
            metaClazz.newInstance();
        } catch (ClassNotFoundException e) {
            System.out.println("ClassLoder loadClass error");
            e.printStackTrace();
        } catch (InstantiationException e) {
            System.out.println("newInstance() error");
        } catch (IllegalAccessException e) {
            System.out.println("newInstance() error");
        } catch (NotFoundException e) {
            try {
                CtClass parent = cp.get(clazz.getName());

                // check super class is CS
                boolean checkSuperClass = parent.getSuperclass().getSimpleName().equals("CodeSegment");
                if (!checkSuperClass) {
                    // argument wrong
                    return;
                } else {

                    // create Meta Code Segment
                    cs = cp.makeClass("Meta"+clazz.getSimpleName());
                    parent.getClassFile().setAccessFlags(AccessFlag.ABSTRACT);
                    parent.setName("Abstract"+parent.getSimpleName());
                    cs.setSuperclass(parent);

                    // define meta inputDataSegment
                    CtClass receiver = cp.get("alice.datasegment.Receiver");

                    // need check exist name
                    String metaFieldName = "metaInfo";

                    CtField cf = new CtField(receiver ,metaFieldName, parent);
                    parent.addField(cf, "ids.create(alice.datasegment.CommandType.PEEK)");

                    cf.getFieldInfo().setAccessFlags(AccessFlag.PUBLIC);
                    for (CtField f : parent.getFields()){
                        int accessType = f.getFieldInfo().getAccessFlags();
                        if (accessType != AccessFlag.PUBLIC){
                            f.getFieldInfo().setAccessFlags(AccessFlag.PUBLIC);
                        }
                    }

                    CtMethod runMethod = parent.getMethod("run", "()V");
                    CtMethod copy = CtNewMethod.copy(runMethod, cs, null);
                    runMethod.setName("metaRun");
                    System.out.println(copy.getName());
                    cs.addMethod(copy);

                    String cnst = "public "+metaName+"(){"
                            + metaFieldName+".setKey(\"TEST\");"
                            + "}";

                    cs.addConstructor(CtNewConstructor.make(cnst, cs));

                    parent.toClass();
                    Class<?> metaClass = cs.toClass();
                    metaClass.newInstance();
                }
            } catch (NotFoundException e1) {
                System.out.println("not found super Class");
                return;
            } catch (CannotCompileException e1) {
                e1.printStackTrace();
            } catch (InstantiationException e1) {
                e1.printStackTrace();
            } catch (IllegalAccessException e1) {
                e1.printStackTrace();
            }
        }

    }
}