1 /***
2 *
3 */
4 package org.vafer.dependency.resources.runtime;
5
6 import java.util.HashSet;
7 import java.util.Set;
8
9 import org.objectweb.asm.ClassAdapter;
10 import org.objectweb.asm.ClassVisitor;
11 import org.objectweb.asm.MethodAdapter;
12 import org.objectweb.asm.MethodVisitor;
13 import org.objectweb.asm.Opcodes;
14 import org.vafer.dependency.asm.Remapper;
15 import org.vafer.dependency.resources.ResolverUtils;
16
17 final class RuntimeResourceResolvingClassAdapter extends ClassAdapter implements Opcodes {
18
19 private final String runimeClass = "org/vafer/dependency/resources/runtime/Mapper";
20 private final Remapper mapper;
21 private String current;
22
23 public RuntimeResourceResolvingClassAdapter( final ClassVisitor cv, final Remapper pMapper ) {
24 super(cv);
25 mapper = pMapper;
26 }
27
28 public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
29 super.visit(version, access, name, signature, superName, interfaces);
30
31 current = name;
32 }
33
34 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
35
36 final MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
37
38 return new MethodWrapper(mv);
39 }
40
41 private class MethodWrapper extends MethodAdapter {
42
43 private final MethodVisitor mv;
44
45 public MethodWrapper(final MethodVisitor pMv) {
46 super(pMv);
47 mv = pMv;
48 }
49
50
51 private void inject( MethodVisitor mv, String method ) {
52
53
54 mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
55
56 mv.visitInsn(DUP);
57
58 mv.visitLdcInsn(mapper.map(""));
59
60 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V");
61
62 mv.visitInsn(DUP2);
63
64 mv.visitInsn(POP);
65
66 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
67
68 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
69
70 mv.visitMethodInsn(INVOKESTATIC, runimeClass, method, "(Ljava/lang/String;)Ljava/lang/String;");
71
72 mv.visitInsn(SWAP);
73
74 mv.visitInsn(POP);
75
76 }
77
78 public void visitMethodInsn(int opcode, String owner, String name, String desc) {
79
80 if (ResolverUtils.needsResourceResolving(owner, name)) {
81
82 System.out.println("Wrapping resource access " + name + " in " + current);
83
84 inject(mv, "resolveResource");
85
86 } else if (ResolverUtils.needsClassResolving(owner, name)) {
87
88 System.out.println("Wrapping class access " + name + " in " + current);
89
90 inject(mv, "resolveClass");
91
92 }
93
94 mv.visitMethodInsn(opcode, owner, name, desc);
95 }
96 }
97 }