KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 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.*;
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  * Generates new interfaces at runtime.
26  * By passing a generated interface to the Enhancer's list of interfaces to
27  * implement, you can make your enhanced classes handle an arbitrary set
28  * of method signatures.
29  * @author Chris Nokleberg
30  * @version $Id: InterfaceMaker.java,v 1.4 2006/03/05 02:43:19 herbyderby Exp $
31  */

32 public class InterfaceMaker extends AbstractClassGenerator
33 {
34     private static final Source SOURCE = new Source(InterfaceMaker.class.getName());
35     private Map signatures = new HashMap();
36
37     /**
38      * Create a new <code>InterfaceMaker</code>. A new <code>InterfaceMaker</code>
39      * object should be used for each generated interface, and should not
40      * be shared across threads.
41      */

42     public InterfaceMaker() {
43         super(SOURCE);
44     }
45
46     /**
47      * Add a method signature to the interface.
48      * @param sig the method signature to add to the interface
49      * @param exceptions an array of exception types to declare for the method
50      */

51     public void add(Signature sig, Type[] exceptions) {
52         signatures.put(sig, exceptions);
53     }
54
55     /**
56      * Add a method signature to the interface. The method modifiers are ignored,
57      * since interface methods are by definition abstract and public.
58      * @param method the method to add to the interface
59      */

60     public void add(Method method) {
61         add(ReflectUtils.getSignature(method),
62             ReflectUtils.getExceptionTypes(method));
63     }
64
65     /**
66      * Add all the public methods in the specified class.
67      * Methods from superclasses are included, except for methods declared in the base
68      * Object class (e.g. <code>getClass</code>, <code>equals</code>, <code>hashCode</code>).
69      * @param class the class containing the methods to add to the interface
70      */

71     public void add(Class JavaDoc clazz) {
72         Method[] methods = clazz.getMethods();
73         for (int i = 0; i < methods.length; i++) {
74             Method m = methods[i];
75             if (!m.getDeclaringClass().getName().equals("java.lang.Object")) {
76                 add(m);
77             }
78         }
79     }
80
81     /**
82      * Create an interface using the current set of method signatures.
83      */

84     public Class JavaDoc create() {
85         setUseCache(false);
86         return (Class JavaDoc)super.create(this);
87     }
88
89     protected ClassLoader JavaDoc getDefaultClassLoader() {
90         return null;
91     }
92     
93     protected Object JavaDoc firstInstance(Class JavaDoc type) {
94         return type;
95     }
96
97     protected Object JavaDoc nextInstance(Object JavaDoc instance) {
98         throw new IllegalStateException JavaDoc("InterfaceMaker does not cache");
99     }
100
101     public void generateClass(ClassVisitor v) throws Exception JavaDoc {
102         ClassEmitter ce = new ClassEmitter(v);
103         ce.begin_class(Constants.V1_2,
104                        Constants.ACC_PUBLIC | Constants.ACC_INTERFACE,
105                        getClassName(),
106                        null,
107                        null,
108                        Constants.SOURCE_FILE);
109         for (Iterator it = signatures.keySet().iterator(); it.hasNext();) {
110             Signature sig = (Signature)it.next();
111             Type[] exceptions = (Type[])signatures.get(sig);
112             ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_ABSTRACT,
113                             sig,
114                             exceptions).end_method();
115         }
116         ce.end_class();
117     }
118 }
119
Popular Tags