1 /*
2 * The Apache Software License, Version 1.1
3 *
4 * Copyright (c) 2002 The Apache Software Foundation. All rights
5 * reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. The end-user documentation included with the redistribution,
20 * if any, must include the following acknowledgment:
21 * "This product includes software developed by the
22 * Apache Software Foundation (http://www.apache.org/)."
23 * Alternately, this acknowledgment may appear in the software itself,
24 * if and wherever such third-party acknowledgments normally appear.
25 *
26 * 4. The names "Apache" and "Apache Software Foundation" must
27 * not be used to endorse or promote products derived from this
28 * software without prior written permission. For written
29 * permission, please contact apache@apache.org.
30 *
31 * 5. Products derived from this software may not be called "Apache",
32 * nor may "Apache" appear in their name, without prior written
33 * permission of the Apache Software Foundation.
34 *
35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This software consists of voluntary contributions made by many
50 * individuals on behalf of the Apache Software Foundation. For more
51 * information on the Apache Software Foundation, please see
52 * <http://www.apache.org/>.
53 */
54 package net.sf.cglib.reflect;
55
56 import java.lang.reflect.*;
57 import net.sf.cglib.core.*;
58 import org.objectweb.asm.ClassVisitor;
59 import org.objectweb.asm.Type;
60
61 /***
62 * @author Chris Nokleberg
63 * @version $Id: ConstructorDelegate.java,v 1.16 2003/11/06 05:10:52 herbyderby Exp $
64 */
65 abstract public class ConstructorDelegate {
66 private static final ConstructorKey KEY_FACTORY =
67 (ConstructorKey)KeyFactory.create(ConstructorKey.class, KeyFactory.CLASS_BY_NAME);
68
69 interface ConstructorKey {
70 public Object newInstance(Class declaring, Class iface);
71 }
72
73 protected ConstructorDelegate() {
74 }
75
76 public static ConstructorDelegate create(Class targetClass, Class iface) {
77 Generator gen = new Generator();
78 gen.setTargetClass(targetClass);
79 gen.setInterface(iface);
80 return gen.create();
81 }
82
83 public static class Generator extends AbstractClassGenerator {
84 private static final Source SOURCE = new Source(ConstructorDelegate.class.getName());
85 private static final Type CONSTRUCTOR_DELEGATE =
86 TypeUtils.parseType("net.sf.cglib.reflect.ConstructorDelegate");
87
88 private Class iface;
89 private Class targetClass;
90
91 public Generator() {
92 super(SOURCE);
93 }
94
95 public void setInterface(Class iface) {
96 this.iface = iface;
97 }
98
99 public void setTargetClass(Class targetClass) {
100 this.targetClass = targetClass;
101 }
102
103 public ConstructorDelegate create() {
104 setNamePrefix(targetClass.getName());
105 Object key = KEY_FACTORY.newInstance(iface, targetClass);
106 return (ConstructorDelegate)super.create(key);
107 }
108
109 protected ClassLoader getDefaultClassLoader() {
110 return targetClass.getClassLoader();
111 }
112
113 public void generateClass(ClassVisitor v) {
114 setNamePrefix(targetClass.getName());
115
116 final Method newInstance = ReflectUtils.findNewInstance(iface);
117 if (!newInstance.getReturnType().isAssignableFrom(targetClass)) {
118 throw new IllegalArgumentException("incompatible return type");
119 }
120 final Constructor constructor;
121 try {
122 constructor = targetClass.getDeclaredConstructor(newInstance.getParameterTypes());
123 } catch (NoSuchMethodException e) {
124 throw new IllegalArgumentException("interface does not match any known constructor");
125 }
126
127 ClassEmitter ce = new ClassEmitter(v);
128 ce.begin_class(Constants.ACC_PUBLIC,
129 getClassName(),
130 CONSTRUCTOR_DELEGATE,
131 new Type[]{ Type.getType(iface) },
132 Constants.SOURCE_FILE);
133 Type declaring = Type.getType(constructor.getDeclaringClass());
134 EmitUtils.null_constructor(ce);
135 CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,
136 ReflectUtils.getSignature(newInstance),
137 ReflectUtils.getExceptionTypes(newInstance),
138 null);
139 e.new_instance(declaring);
140 e.dup();
141 e.load_args();
142 e.invoke_constructor(declaring, ReflectUtils.getSignature(constructor));
143 e.return_value();
144 e.end_method();
145 ce.end_class();
146 }
147
148 protected Object firstInstance(Class type) {
149 return ReflectUtils.newInstance(type);
150 }
151
152 protected Object nextInstance(Object instance) {
153 return instance;
154 }
155 }
156 }
This page was automatically generated by Maven