KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > cglib > transform > impl > AddDelegateTransformer


1 /*
2  * Copyright 2003 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package net.sf.cglib.transform.impl;
17
18 import net.sf.cglib.transform.*;
19 import java.lang.reflect.*;
20 import java.util.*;
21 import net.sf.cglib.core.*;
22 import org.objectweb.asm.Attribute;
23 import org.objectweb.asm.Type;
24
25 /**
26  * @author Juozas Baliuka
27  */

28 public class AddDelegateTransformer extends ClassEmitterTransformer {
29     private static final String JavaDoc DELEGATE = "$CGLIB_DELEGATE";
30     private static final Signature CSTRUCT_OBJECT =
31       TypeUtils.parseSignature("void <init>(Object)");
32     
33     private Class JavaDoc[] delegateIf;
34     private Class JavaDoc delegateImpl;
35     private Type delegateType;
36     
37     /** Creates a new instance of AddDelegateTransformer */
38     public AddDelegateTransformer(Class JavaDoc delegateIf[], Class JavaDoc delegateImpl) {
39         try {
40             delegateImpl.getConstructor(new Class JavaDoc[]{ Object JavaDoc.class });
41             this.delegateIf = delegateIf;
42             this.delegateImpl = delegateImpl;
43             delegateType = Type.getType(delegateImpl);
44         } catch (NoSuchMethodException JavaDoc e) {
45             throw new CodeGenerationException(e);
46         }
47     }
48     
49     public void begin_class(int version, int access, String JavaDoc className, Type superType, Type[] interfaces, String JavaDoc sourceFile) {
50         
51         if(!TypeUtils.isInterface(access)){
52             
53         Type[] all = TypeUtils.add(interfaces, TypeUtils.getTypes(delegateIf));
54         super.begin_class(version, access, className, superType, all, sourceFile);
55         
56         declare_field(Constants.ACC_PRIVATE | Constants.ACC_TRANSIENT,
57                       DELEGATE,
58                       delegateType,
59                       null);
60         for (int i = 0; i < delegateIf.length; i++) {
61             Method[] methods = delegateIf[i].getMethods();
62             for (int j = 0; j < methods.length; j++) {
63                 if (Modifier.isAbstract(methods[j].getModifiers())) {
64                     addDelegate(methods[j]);
65                 }
66             }
67         }
68         }else{
69            super.begin_class(version, access, className, superType, interfaces, sourceFile);
70         }
71     }
72
73     public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) {
74         final CodeEmitter e = super.begin_method(access, sig, exceptions);
75         if (sig.getName().equals(Constants.CONSTRUCTOR_NAME)) {
76             return new CodeEmitter(e) {
77                 private boolean transformInit = true;
78                 public void visitMethodInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
79                     super.visitMethodInsn(opcode, owner, name, desc);
80                     if (transformInit && opcode == Constants.INVOKESPECIAL) {
81                         load_this();
82                         new_instance(delegateType);
83                         dup();
84                         load_this();
85                         invoke_constructor(delegateType, CSTRUCT_OBJECT);
86                         putfield(DELEGATE);
87                         transformInit = false;
88                     }
89                 }
90             };
91         }
92         return e;
93     }
94
95     private void addDelegate(Method m) {
96         Method delegate;
97         try {
98             delegate = delegateImpl.getMethod(m.getName(), m.getParameterTypes());
99             if (!delegate.getReturnType().getName().equals(m.getReturnType().getName())){
100                 throw new IllegalArgumentException JavaDoc("Invalid delegate signature " + delegate);
101             }
102         } catch (NoSuchMethodException JavaDoc e) {
103             throw new CodeGenerationException(e);
104         }
105
106         final Signature sig = ReflectUtils.getSignature(m);
107         Type[] exceptions = TypeUtils.getTypes(m.getExceptionTypes());
108         CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, sig, exceptions);
109         e.load_this();
110         e.getfield(DELEGATE);
111         e.load_args();
112         e.invoke_virtual(delegateType, sig);
113         e.return_value();
114         e.end_method();
115     }
116 }
117
118
119
120
Popular Tags