📄 panelclassenhancer.java
字号:
package org.uispec4j.extension;
import org.objectweb.asm.*;
class PanelClassEnhancer extends ClassAdapter implements Constants {
private Extension[] extensions;
public static byte[] transformClass(ClassReader reader, Extension[] extensions) {
ClassWriter writer = new ClassWriter(true, true);
PanelClassEnhancer transformer = new PanelClassEnhancer(writer, extensions);
reader.accept(transformer, false);
return writer.toByteArray();
}
private PanelClassEnhancer(ClassVisitor cv, Extension[] extensions) {
super(cv);
this.extensions = extensions;
}
public CodeVisitor visitMethod(int access,
String name, String desc,
String[] exceptions, Attribute attrs) {
CodeVisitor cd = cv.visitMethod(access, name, desc, exceptions, attrs);
if (cd == null) {
return null;
}
if ("<clinit>".equals(name) && ((access & Constants.ACC_STATIC) != 0)) {
return new StaticInitEnhancer(cd);
}
return cd;
}
private class StaticInitEnhancer extends CodeAdapter {
public StaticInitEnhancer(CodeVisitor cd) {
super(cd);
}
public void visitInsn(int opcode) {
if (opcode == RETURN) {
for (int i = 0; i < extensions.length; i++) {
Extension extension = extensions[i];
String componentClassName = extension.getComponentClassName();
String transformedComponentClassName = transformClassName(componentClassName);
addStaticInitializerForExtension(transformedComponentClassName, componentClassName);
}
}
cv.visitInsn(opcode);
}
private void addStaticInitializerForExtension(String transformedComponentClassName, String componentClassName) {
cv.visitFieldInsn(GETSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
Label l12 = new Label();
cv.visitJumpInsn(IFNONNULL, l12);
cv.visitLdcInsn(componentClassName);
cv.visitMethodInsn(INVOKESTATIC, "org/uispec4j/Panel", "class$", "(Ljava/lang/String;)Ljava/lang/Class;");
cv.visitInsn(DUP);
cv.visitFieldInsn(PUTSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
Label l13 = new Label();
cv.visitJumpInsn(GOTO, l13);
cv.visitLabel(l12);
cv.visitFieldInsn(GETSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
cv.visitLabel(l13);
cv.visitMethodInsn(INVOKESTATIC, "org/uispec4j/utils/UIComponentFactory", "addUIComponentClass", "(Ljava/lang/Class;)V");
}
}
public void visitEnd() {
for (int i = 0; i < extensions.length; i++) {
Extension extension = extensions[i];
addExtension(extension.getComponentName(),
extension.getComponentClassName());
}
cv.visitEnd();
}
private void addExtension(String componentName, String componentClassName) {
String methodName = "get" + componentName;
String transformedComponentClassName = transformClassName(componentClassName);
String slashedComponentClassName = componentClassName.replace('.', '/');
cv.visitField(ACC_STATIC + ACC_SYNTHETIC, transformedComponentClassName, "Ljava/lang/Class;", null, null);
{
CodeVisitor v = cv.visitMethod(ACC_PUBLIC, methodName,
"(Ljava/lang/String;)L" + slashedComponentClassName + ";",
new String[]{"org/uispec4j/ItemNotFoundException", "org/uispec4j/ComponentAmbiguityException"}, null);
Label l0 = new Label();
v.visitLabel(l0);
v.visitVarInsn(ALOAD, 0);
v.visitFieldInsn(GETFIELD, "org/uispec4j/Panel", "finder", "Lorg/uispec4j/finder/ComponentFinder;");
v.visitFieldInsn(GETSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
Label l1 = new Label();
v.visitJumpInsn(IFNONNULL, l1);
v.visitLdcInsn(componentClassName);
v.visitMethodInsn(INVOKESTATIC, "org/uispec4j/Panel", "class$", "(Ljava/lang/String;)Ljava/lang/Class;");
v.visitInsn(DUP);
v.visitFieldInsn(PUTSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
Label l2 = new Label();
v.visitJumpInsn(GOTO, l2);
v.visitLabel(l1);
v.visitFieldInsn(GETSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
v.visitLabel(l2);
v.visitVarInsn(ALOAD, 1);
v.visitMethodInsn(INVOKESTATIC, "org/uispec4j/Panel", "getComponent",
"(Lorg/uispec4j/finder/ComponentFinder;Ljava/lang/Class;Ljava/lang/String;)Lorg/uispec4j/UIComponent;");
v.visitTypeInsn(CHECKCAST, slashedComponentClassName);
v.visitInsn(ARETURN);
v.visitMaxs(3, 2);
}
{
CodeVisitor v = cv.visitMethod(ACC_PUBLIC, methodName,
"()L" + slashedComponentClassName + ";",
new String[]{"org/uispec4j/ItemNotFoundException", "org/uispec4j/ComponentAmbiguityException"}, null);
Label l0 = new Label();
v.visitLabel(l0);
v.visitVarInsn(ALOAD, 0);
v.visitFieldInsn(GETFIELD, "org/uispec4j/Panel", "finder", "Lorg/uispec4j/finder/ComponentFinder;");
v.visitFieldInsn(GETSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
Label l1 = new Label();
v.visitJumpInsn(IFNONNULL, l1);
v.visitLdcInsn(componentClassName);
v.visitMethodInsn(INVOKESTATIC, "org/uispec4j/Panel", "class$", "(Ljava/lang/String;)Ljava/lang/Class;");
v.visitInsn(DUP);
v.visitFieldInsn(PUTSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
Label l2 = new Label();
v.visitJumpInsn(GOTO, l2);
v.visitLabel(l1);
v.visitFieldInsn(GETSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
v.visitLabel(l2);
v.visitInsn(ACONST_NULL);
v.visitMethodInsn(INVOKESTATIC, "org/uispec4j/Panel", "getComponent",
"(Lorg/uispec4j/finder/ComponentFinder;Ljava/lang/Class;Ljava/lang/String;)Lorg/uispec4j/UIComponent;");
v.visitTypeInsn(CHECKCAST, slashedComponentClassName);
v.visitInsn(ARETURN);
v.visitMaxs(3, 1);
}
{
CodeVisitor v = cv.visitMethod(ACC_PUBLIC, methodName,
"(Lorg/uispec4j/finder/ComponentMatcher;)L" + slashedComponentClassName + ";",
new String[]{"org/uispec4j/ItemNotFoundException", "org/uispec4j/ComponentAmbiguityException"}, null);
Label l0 = new Label();
v.visitLabel(l0);
v.visitVarInsn(ALOAD, 0);
v.visitFieldInsn(GETFIELD, "org/uispec4j/Panel", "finder", "Lorg/uispec4j/finder/ComponentFinder;");
v.visitVarInsn(ALOAD, 0);
v.visitFieldInsn(GETSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
Label l1 = new Label();
v.visitJumpInsn(IFNONNULL, l1);
v.visitLdcInsn(componentClassName);
v.visitMethodInsn(INVOKESTATIC, "org/uispec4j/Panel", "class$", "(Ljava/lang/String;)Ljava/lang/Class;");
v.visitInsn(DUP);
v.visitFieldInsn(PUTSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
Label l2 = new Label();
v.visitJumpInsn(GOTO, l2);
v.visitLabel(l1);
v.visitFieldInsn(GETSTATIC, "org/uispec4j/Panel", transformedComponentClassName, "Ljava/lang/Class;");
v.visitLabel(l2);
v.visitVarInsn(ALOAD, 1);
v.visitMethodInsn(INVOKESPECIAL, "org/uispec4j/Panel", "getMatcherByClass", "(Ljava/lang/Class;Lorg/uispec4j/finder/ComponentMatcher;)Lorg/uispec4j/finder/ComponentMatcher;");
v.visitMethodInsn(INVOKESTATIC, "org/uispec4j/Panel", "getComponent", "(Lorg/uispec4j/finder/ComponentFinder;Lorg/uispec4j/finder/ComponentMatcher;)Lorg/uispec4j/UIComponent;");
v.visitTypeInsn(CHECKCAST, slashedComponentClassName);
v.visitInsn(ARETURN);
Label l3 = new Label();
v.visitLabel(l3);
v.visitLineNumber(205, l0);
v.visitLocalVariable("this", "Lorg/uispec4j/Panel;", l0, l3, 0);
v.visitLocalVariable("matcher", "Lorg/uispec4j/finder/ComponentMatcher;", l0, l3, 1);
v.visitMaxs(4, 2);
}
}
private String transformClassName(String componentClassName) {
return "class$" + componentClassName.replace('.', '$');
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -