java: refactor JavassistTemplateBuilder.java

This commit is contained in:
Muga Nishizawa
2010-12-23 15:51:04 +09:00
parent 910e642a8b
commit 4b36340474

View File

@@ -18,16 +18,17 @@
package org.msgpack.template; package org.msgpack.template;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.*; import java.lang.reflect.Array;
import java.util.Map; import java.lang.reflect.Constructor;
import java.util.HashMap; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import org.msgpack.*; import org.msgpack.*;
import javassist.CannotCompileException; import javassist.CannotCompileException;
import javassist.ClassPool; import javassist.ClassPool;
import javassist.CtClass; import javassist.CtClass;
import javassist.CtConstructor; import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod; import javassist.CtMethod;
import javassist.CtNewConstructor; import javassist.CtNewConstructor;
import javassist.CtNewMethod; import javassist.CtNewMethod;
@@ -38,7 +39,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class JavassistTemplateBuilder extends TemplateBuilder { public class JavassistTemplateBuilder extends TemplateBuilder {
private static Logger LOG = LoggerFactory.getLogger(JavassistTemplateBuilder.class);
private static JavassistTemplateBuilder instance; private static JavassistTemplateBuilder instance;
public synchronized static JavassistTemplateBuilder getInstance() { public synchronized static JavassistTemplateBuilder getInstance() {
if(instance == null) { if(instance == null) {
instance = new JavassistTemplateBuilder(); instance = new JavassistTemplateBuilder();
@@ -47,17 +51,15 @@ public class JavassistTemplateBuilder extends TemplateBuilder {
} }
public static void addClassLoader(ClassLoader cl) { public static void addClassLoader(ClassLoader cl) {
instance.pool.appendClassPath(new LoaderClassPath(cl)); getInstance().pool.appendClassPath(new LoaderClassPath(cl));
} }
private JavassistTemplateBuilder() { private JavassistTemplateBuilder() {
this.pool = ClassPool.getDefault(); this.pool = ClassPool.getDefault();
} }
private static Logger LOG = LoggerFactory
.getLogger(JavassistTemplateBuilder.class);
protected ClassPool pool; protected ClassPool pool;
private int seqId = 0; private int seqId = 0;
CtClass makeCtClass(String className) { CtClass makeCtClass(String className) {
@@ -74,24 +76,30 @@ public class JavassistTemplateBuilder extends TemplateBuilder {
private static abstract class BuildContextBase { private static abstract class BuildContextBase {
protected JavassistTemplateBuilder director; protected JavassistTemplateBuilder director;
protected Class<?> origClass;
protected String origName;
protected String tmplName; protected String tmplName;
protected CtClass tmplCtClass; protected CtClass tmplCtClass;
protected abstract void setSuperClass() throws CannotCompileException, NotFoundException; protected abstract void setSuperClass() throws CannotCompileException, NotFoundException;
protected abstract void buildConstructor() throws CannotCompileException, NotFoundException; protected abstract void buildConstructor() throws CannotCompileException, NotFoundException;
protected void buildMethodInit() { } protected void buildMethodInit() { }
protected abstract String buildPackMethodBody(); protected abstract String buildPackMethodBody();
protected abstract String buildUnpackMethodBody(); protected abstract String buildUnpackMethodBody();
protected abstract String buildConvertMethodBody(); protected abstract String buildConvertMethodBody();
protected abstract Template buildInstance(Class<?> c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException; protected abstract Template buildInstance(Class<?> c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException;
public BuildContextBase(JavassistTemplateBuilder director) { public BuildContextBase(JavassistTemplateBuilder director) {
this.director = director; this.director = director;
} }
protected Template build(String className) { protected Template build(final String className) {
try { try {
reset(className); reset(className);
buildClass(); buildClass();
@@ -104,9 +112,7 @@ public class JavassistTemplateBuilder extends TemplateBuilder {
} catch (Exception e) { } catch (Exception e) {
String code = getBuiltString(); String code = getBuiltString();
if(code != null) { if(code != null) {
LOG.error("builder: "+this.stringBuilder.toString()); LOG.error("builder: " + code, e);
}
if(code != null) {
throw new TemplateBuildException("cannot compile: " + code, e); throw new TemplateBuildException("cannot compile: " + code, e);
} else { } else {
throw new TemplateBuildException(e); throw new TemplateBuildException(e);
@@ -115,14 +121,13 @@ public class JavassistTemplateBuilder extends TemplateBuilder {
} }
protected void reset(String className) { protected void reset(String className) {
this.tmplName = className + "_$$_Template" + director.nextSeqId(); tmplName = className + "_$$_Template" + director.nextSeqId();
this.tmplCtClass = director.makeCtClass(this.tmplName); tmplCtClass = director.makeCtClass(tmplName);
} }
protected void buildClass() throws CannotCompileException, NotFoundException { protected void buildClass() throws CannotCompileException, NotFoundException {
setSuperClass(); setSuperClass();
this.tmplCtClass.addInterface( tmplCtClass.addInterface(director.getCtClass(Template.class.getName()));
director.getCtClass(Template.class.getName()));
} }
protected void buildPackMethod() throws CannotCompileException, NotFoundException { protected void buildPackMethod() throws CannotCompileException, NotFoundException {
@@ -139,9 +144,8 @@ public class JavassistTemplateBuilder extends TemplateBuilder {
}; };
CtMethod newCtMethod = CtNewMethod.make( CtMethod newCtMethod = CtNewMethod.make(
mod, returnType, mname, mod, returnType, mname,
paramTypes, exceptTypes, mbody, paramTypes, exceptTypes, mbody, tmplCtClass);
this.tmplCtClass); tmplCtClass.addMethod(newCtMethod);
this.tmplCtClass.addMethod(newCtMethod);
} }
protected void buildUnpackMethod() throws CannotCompileException, NotFoundException { protected void buildUnpackMethod() throws CannotCompileException, NotFoundException {
@@ -158,9 +162,8 @@ public class JavassistTemplateBuilder extends TemplateBuilder {
}; };
CtMethod newCtMethod = CtNewMethod.make( CtMethod newCtMethod = CtNewMethod.make(
mod, returnType, mname, mod, returnType, mname,
paramTypes, exceptTypes, mbody, paramTypes, exceptTypes, mbody, tmplCtClass);
this.tmplCtClass); tmplCtClass.addMethod(newCtMethod);
this.tmplCtClass.addMethod(newCtMethod);
} }
protected void buildConvertMethod() throws CannotCompileException, NotFoundException { protected void buildConvertMethod() throws CannotCompileException, NotFoundException {
@@ -177,42 +180,41 @@ public class JavassistTemplateBuilder extends TemplateBuilder {
}; };
CtMethod newCtMethod = CtNewMethod.make( CtMethod newCtMethod = CtNewMethod.make(
mod, returnType, mname, mod, returnType, mname,
paramTypes, exceptTypes, mbody, paramTypes, exceptTypes, mbody, tmplCtClass);
this.tmplCtClass); tmplCtClass.addMethod(newCtMethod);
this.tmplCtClass.addMethod(newCtMethod);
} }
protected Class<?> createClass() throws CannotCompileException { protected Class<?> createClass() throws CannotCompileException {
return (Class<?>)this.tmplCtClass.toClass(null, null); return (Class<?>) tmplCtClass.toClass(null, null);
} }
protected StringBuilder stringBuilder = null; protected StringBuilder stringBuilder = null;
protected void resetStringBuilder() { protected void resetStringBuilder() {
this.stringBuilder = new StringBuilder(); stringBuilder = new StringBuilder();
} }
protected void buildString(String str) { protected void buildString(String str) {
this.stringBuilder.append(str); stringBuilder.append(str);
} }
protected void buildString(String format, Object... args) { protected void buildString(String format, Object... args) {
this.stringBuilder.append(String.format(format, args)); stringBuilder.append(String.format(format, args));
} }
protected String getBuiltString() { protected String getBuiltString() {
if(this.stringBuilder == null) { if(stringBuilder == null) {
return null; return null;
} }
return this.stringBuilder.toString(); return stringBuilder.toString();
} }
} }
public static abstract class JavassistTemplate extends AbstractTemplate { public static abstract class JavassistTemplate extends AbstractTemplate {
public Class targetClass; public Class<?> targetClass;
public Template[] templates; public Template[] templates;
public JavassistTemplate(Class targetClass, Template[] templates) { public JavassistTemplate(Class<?> targetClass, Template[] templates) {
this.targetClass = targetClass; this.targetClass = targetClass;
this.templates = templates; this.templates = templates;
} }
@@ -279,7 +281,6 @@ public class JavassistTemplateBuilder extends TemplateBuilder {
protected String buildPackMethodBody() { protected String buildPackMethodBody() {
resetStringBuilder(); resetStringBuilder();
buildString("{"); buildString("{");
buildString("%s _$$_t = (%s)$2;", this.origName, this.origName); buildString("%s _$$_t = (%s)$2;", this.origName, this.origName);
buildString("$1.packArray(%d);", entries.length); buildString("$1.packArray(%d);", entries.length);
for(int i=0; i < entries.length; i++) { for(int i=0; i < entries.length; i++) {
@@ -303,7 +304,6 @@ public class JavassistTemplateBuilder extends TemplateBuilder {
buildString("}"); buildString("}");
} }
} }
buildString("}"); buildString("}");
return getBuiltString(); return getBuiltString();
} }
@@ -463,7 +463,6 @@ public class JavassistTemplateBuilder extends TemplateBuilder {
return getBuiltString(); return getBuiltString();
} }
protected String primitivePackName(Class<?> type) { protected String primitivePackName(Class<?> type) {
if(type == boolean.class) { if(type == boolean.class) {
return "packBoolean"; return "packBoolean";