/*
* Copyright 2008-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.hasor.core.classcode;
import net.hasor.core.classcode.asm.ClassReader;
import net.hasor.core.classcode.asm.ClassVisitor;
import net.hasor.core.classcode.asm.ClassWriter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Modifier;
import java.util.concurrent.atomic.AtomicLong;
/**
*
* @version : 2014年9月7日
* @author 赵永春(zyc@hasor.net)
*/
public abstract class AbstractClassConfig {
/**默认超类java.lang.Object。*/
public static final Class<?> DefaultSuperClass = ClassCodeObject.class;
private Class<?> superClass = DefaultSuperClass;
private String className = null; //新类名称
private byte[] classBytes = null; //新类字节码
private MoreClassLoader parentLoader = new MoreClassLoader();
//
/**创建{@link AbstractClassConfig}类型对象。 */
public AbstractClassConfig(Class<?> superClass) {
this(superClass, superClass.getClassLoader());
}
/**创建{@link AbstractClassConfig}类型对象。 */
public AbstractClassConfig(Class<?> superClass, ClassLoader parentLoader) {
this.superClass = superClass;
this.className = this.initClassName();
if (parentLoader instanceof MoreClassLoader) {
this.parentLoader = (MoreClassLoader) parentLoader;
} else {
this.parentLoader = new MoreClassLoader(parentLoader);
}
}
//
private static AtomicLong index = new AtomicLong(0);
protected static long index() {
return index.getAndIncrement();
}
protected String initClassName() {
return this.superClass.getName() + "$Auto$" + index();
}
//
protected ClassVisitor acceptClass(ClassVisitor writer) {
return null;
}
/**调用ClassLoader,生成字节码并装载它*/
public synchronized Class<?> toClass() throws IOException, ClassNotFoundException {
this.classBytes = this.buildBytes();
return this.parentLoader.findClass(getClassName());
}
/**取得字节码信息*/
public byte[] getBytes() {
return this.classBytes;
}
/**父类类型*/
public Class<?> getSuperClass() {
return superClass;
}
/**新类类名*/
public String getClassName() {
return this.className;
}
/**新类类名*/
public String getSimpleName() {
if (this.className == null)
return null;
return this.className.substring(this.className.lastIndexOf(".") + 1);
}
public byte[] buildBytes() throws IOException {
if (this.classBytes == null) {
this.classBytes = this.buildClass();
this.parentLoader.addClassConfig(this);
}
return this.classBytes;
}
;
/**父类是否支持*/
public static boolean isSupport(Class<?> superClass) {
String resName = superClass.getName().replace(".", "/") + ".class";
if (resName.startsWith("java/") || resName.startsWith("javax/")) {
return false;
} else {
return ASMEngineTools.checkIn(superClass.getModifiers(), Modifier.PUBLIC);
}
}
/**父类是否支持*/
public boolean isSupport() {
return isSupport(this.getSuperClass());
}
//
protected final byte[] buildClass() throws IOException {
//1.基本信息
Class<?> superClass = this.getSuperClass();
String resName = superClass.getName().replace(".", "/") + ".class";
if (!isSupport()) {
throw new IOException("class in package java or javax , does not support.");
}
//2.构建visitor环
//------第一环,写入
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
//------第二环,用户扩展
ClassVisitor visitor = this.acceptClass(writer);
visitor = (visitor == null) ? writer : visitor;
//------第三环,Aop
visitor = this.buildClassVisitor(visitor);
//3.Read
ClassLoader typeLoader = superClass.getClassLoader();
if (typeLoader == null) {
typeLoader = ClassLoader.getSystemClassLoader();
}
InputStream inStream = typeLoader.getResourceAsStream(resName);
ClassReader reader = new ClassReader(inStream);//创建ClassReader
reader.accept(visitor, ClassReader.SKIP_DEBUG);
return writer.toByteArray();
}
protected abstract ClassVisitor buildClassVisitor(ClassVisitor parentVisitor);
/**是否包含改变*/
public abstract boolean hasChange();
}