KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > cglib > proxy > MixinEmitter


1 /*
2  * Copyright 2003,2004 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.proxy;
17
18 import java.lang.reflect.Method JavaDoc;
19 import java.util.*;
20 import net.sf.cglib.core.*;
21 import org.objectweb.asm.ClassVisitor;
22 import org.objectweb.asm.Type;
23
24 /**
25  * @author Chris Nokleberg
26  * @version $Id: MixinEmitter.java,v 1.9 2006/08/27 21:04:37 herbyderby Exp $
27  */

28 class MixinEmitter extends ClassEmitter {
29     private static final String JavaDoc FIELD_NAME = "CGLIB$DELEGATES";
30     private static final Signature CSTRUCT_OBJECT_ARRAY =
31       TypeUtils.parseConstructor("Object[]");
32     private static final Type MIXIN =
33       TypeUtils.parseType("net.sf.cglib.proxy.Mixin");
34     private static final Signature NEW_INSTANCE =
35       new Signature("newInstance", MIXIN, new Type[]{ Constants.TYPE_OBJECT_ARRAY });
36
37     public MixinEmitter(ClassVisitor v, String JavaDoc className, Class JavaDoc[] classes, int[] route) {
38         super(v);
39
40         begin_class(Constants.V1_2,
41                     Constants.ACC_PUBLIC,
42                     className,
43                     MIXIN,
44                     TypeUtils.getTypes(getInterfaces(classes)),
45                     Constants.SOURCE_FILE);
46         EmitUtils.null_constructor(this);
47         EmitUtils.factory_method(this, NEW_INSTANCE);
48
49         declare_field(Constants.ACC_PRIVATE, FIELD_NAME, Constants.TYPE_OBJECT_ARRAY, null);
50
51         CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT_ARRAY, null);
52         e.load_this();
53         e.super_invoke_constructor();
54         e.load_this();
55         e.load_arg(0);
56         e.putfield(FIELD_NAME);
57         e.return_value();
58         e.end_method();
59
60         Set unique = new HashSet();
61         for (int i = 0; i < classes.length; i++) {
62             Method JavaDoc[] methods = getMethods(classes[i]);
63             for (int j = 0; j < methods.length; j++) {
64                 if (unique.add(MethodWrapper.create(methods[j]))) {
65                     MethodInfo method = ReflectUtils.getMethodInfo(methods[j]);
66                     e = EmitUtils.begin_method(this, method, Constants.ACC_PUBLIC);
67                     e.load_this();
68                     e.getfield(FIELD_NAME);
69                     e.aaload((route != null) ? route[i] : i);
70                     e.checkcast(method.getClassInfo().getType());
71                     e.load_args();
72                     e.invoke(method);
73                     e.return_value();
74                     e.end_method();
75                 }
76             }
77         }
78
79         end_class();
80     }
81
82     protected Class JavaDoc[] getInterfaces(Class JavaDoc[] classes) {
83         return classes;
84     }
85
86     protected Method JavaDoc[] getMethods(Class JavaDoc type) {
87         return type.getMethods();
88     }
89 }
90
Popular Tags