All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.wensiqun.asmsupport.client.DummyModifiedClass Maven / Gradle / Ivy

/**    
 *  Asmsupport 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 .
 */
package cn.wensiqun.asmsupport.client;

import java.util.LinkedList;

import cn.wensiqun.asmsupport.client.block.BlockPostern;
import cn.wensiqun.asmsupport.client.block.ModifiedMethodBody;
import cn.wensiqun.asmsupport.client.block.StaticBlockBody;
import cn.wensiqun.asmsupport.core.builder.impl.ClassModifier;
import cn.wensiqun.asmsupport.core.loader.CachedThreadLocalClassLoader;
import cn.wensiqun.asmsupport.core.utils.log.LogFactory;
import cn.wensiqun.asmsupport.standard.error.ASMSupportException;
import cn.wensiqun.asmsupport.standard.utils.AsmsupportClassLoader;
import cn.wensiqun.asmsupport.utils.AsmsupportConstant;
import cn.wensiqun.asmsupport.utils.lang.StringUtils;

public class DummyModifiedClass extends AbstractDummy {

    private Class original;

    /** What's the class generate path of the class, use this for debug normally */
    private String classOutPutPath;
    
    /** Whether or not print log.*/
    private boolean printLog;
    
    /** The log file path.*/
    private String logFilePath;

    /** All constructors */
    private LinkedList constructorDummies = new LinkedList();
    
    /** All fields */
    private LinkedList fieldDummies = new LinkedList();
    
    /** All methods */
    private LinkedList methodDummies = new LinkedList();
    
    /** class static block */
    private StaticBlockBody staticBlock;
    
    /** All modify methods */
    private LinkedList modifyDummies = new LinkedList();
    
    public DummyModifiedClass(Class original) {
    	this(original, CachedThreadLocalClassLoader.getInstance());
    }
    
    public DummyModifiedClass(Class original, AsmsupportClassLoader classLoader) {
    	super(classLoader);
        this.original = original;
    }
    
    /**
     * Set the class out put path.
     * 
     * @param path
     * @return
     */
    public DummyModifiedClass setClassOutPutPath(String path) {
        this.classOutPutPath = path;
        return this;
    }
    
    /**
     * Get the class out put path.
     * 
     * @return
     */
    public String getClassOutPutPath() {
        return classOutPutPath;
    }
    
    /**
     * Whether or not print log information. if set {@code true} than print it to console.
     * Also you can print to file by method {@link DummyClass#setLogFilePath(String)}
     * 
     * @param print
     * @return
     */
    public DummyModifiedClass setPrintLog(boolean print) {
        printLog = print;
        return this;
    }

    /**
     * The log information out put path. call the method will set {@code printLog} to {@code true.}
     * 
     * @param logFile
     * @return
     */
    public DummyModifiedClass setLogFilePath(String logFile){
        logFilePath = logFile;
        printLog = true;
        return this;
    }

    /**
     * Create a field
     * 
     * @return
     */
    public DummyField newField() {
        fieldDummies.add(new DummyField(getClassLoader()));
        return fieldDummies.getLast();
    }

    /**
     * Create Constructor.
     * 
     * @return
     */
    public DummyConstructor newConstructor() {
        constructorDummies.add(new DummyConstructor(getClassLoader()));
        return constructorDummies.getLast();
    }

    /**
     * Create a method.
     * 
     * @return
     */
    public DummyMethod newMethod(String name) {
        DummyMethod method = new DummyMethod(getClassLoader());
        method.name(name);
        methodDummies.add(method);
        return method;
    }

    /**
     * Create a static block.
     * 
     * @return
     */
    public DummyModifiedClass newStaticBlock(StaticBlockBody staticBlock) {
        if(staticBlock != null) {
            throw new ASMSupportException("Static Block is already existes.");
        }
        this.staticBlock = staticBlock;
        return this;
    }
    
    /**
     * Modify common method.
     * 
     * @param method
     * @param argTypes
     * @param body
     * @return
     */
    public DummyModifiedClass modify(String method, Class[] argTypes, ModifiedMethodBody body){
        DummyModifiedMethod dmm = new DummyModifiedMethod(method, argTypes, body);
        this.modifyDummies.add(dmm);
        return this;
    }
    
    /**
     * Modify constructor
     * 
     * @param argTypes
     * @param body
     * @return
     */
    public DummyModifiedClass modifyConstructor(Class[] argTypes, ModifiedMethodBody body) {
        return this.modify(AsmsupportConstant.INIT, argTypes, body);
    }
    
    /**
     * Modify static block.
     * 
     * @param body
     * @return
     */
    public DummyModifiedClass modifyStaticBlock(ModifiedMethodBody body) {
        return this.modify(AsmsupportConstant.CLINIT, null, body);
    }

    /**
     * Build class. 
     * 
     * @return
     */
    public Class build() {
    	LogFactory.LOG_FACTORY_LOCAL.remove();
        if(StringUtils.isNotBlank(logFilePath)) {
        	LogFactory.LOG_FACTORY_LOCAL.set(new LogFactory(logFilePath)); 
        } else if(printLog) {
        	LogFactory.LOG_FACTORY_LOCAL.set(new LogFactory()); 
        }
        ClassModifier cmi = new ClassModifier(original, getClassLoader()) ;
        for(DummyConstructor dummy : constructorDummies) {
            if(dummy.getConstructorBody() != null) {
                cmi.createConstructor(dummy.getModifiers(), dummy.getArgumentTypes(), dummy.getArgumentNames(), dummy.getThrows(), 
                        BlockPostern.getTarget(dummy.getConstructorBody()));    
            } else {
                throw new ASMSupportException("Not found body...");
            }
        }
        
        for(DummyField dummy : fieldDummies) {
            if(dummy.getType() == null) {
                throw new ASMSupportException("Not specify field type for field '" +  dummy.getName() + "'");
            }
            if(dummy.getName() == null) {
                throw new ASMSupportException("Not specify field name.");
            }
            cmi.createField(dummy.getName(), dummy.getModifiers(), dummy.getType(), dummy.getValue());
        }
        
        for(DummyMethod dummy : methodDummies) {
            cmi.createMethodForDummy(dummy.getModifiers(), dummy.getName(), dummy.getArgTypes(),
                    dummy.getArgNames(), dummy.getReturnType(), dummy.getThrows(), BlockPostern.getTarget(dummy.getMethodBody()));
        }
        
        if(staticBlock != null) {
            cmi.createStaticBlock(BlockPostern.getTarget(staticBlock));
        }
        
        for(DummyModifiedMethod dummy : modifyDummies) {
            cmi.modifyMethod(dummy.getName(), dummy.getArgumentTypes(), BlockPostern.getTarget(dummy.getMethodBody()));
        }
        
        cmi.setClassOutPutPath(classOutPutPath);
        return cmi.startup();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy