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.beans;
55
56 import java.lang.reflect.Constructor;
57 import java.lang.reflect.Method;
58 import java.lang.reflect.Modifier;
59 import java.util.*;
60 import net.sf.cglib.core.*;
61 import org.objectweb.asm.ClassVisitor;
62 import org.objectweb.asm.Type;
63
64 class BulkBeanEmitter extends ClassEmitter {
65 private static final Signature GET_PROPERTY_VALUES =
66 TypeUtils.parseSignature("void getPropertyValues(Object, Object[])");
67 private static final Signature SET_PROPERTY_VALUES =
68 TypeUtils.parseSignature("void setPropertyValues(Object, Object[])");
69 private static final Signature CSTRUCT_EXCEPTION =
70 TypeUtils.parseConstructor("Throwable, int");
71 private static final Type BULK_BEAN =
72 TypeUtils.parseType("net.sf.cglib.beans.BulkBean");
73 private static final Type BULK_BEAN_EXCEPTION =
74 TypeUtils.parseType("net.sf.cglib.beans.BulkBeanException");
75
76 public BulkBeanEmitter(ClassVisitor v,
77 String className,
78 Class target,
79 String[] getterNames,
80 String[] setterNames,
81 Class[] types) {
82 super(v);
83
84 Method[] getters = new Method[getterNames.length];
85 Method[] setters = new Method[setterNames.length];
86 validate(target, getterNames, setterNames, types, getters, setters);
87
88 begin_class(Constants.ACC_PUBLIC, className, BULK_BEAN, null, Constants.SOURCE_FILE);
89 EmitUtils.null_constructor(this);
90 generateGet(target, getters);
91 generateSet(target, setters);
92 end_class();
93 }
94
95 private void generateGet(final Class target, final Method[] getters) {
96 CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_VALUES, null, null);
97 if (getters.length >= 0) {
98 e.load_arg(0);
99 e.checkcast(Type.getType(target));
100 Local bean = e.make_local();
101 e.store_local(bean);
102 for (int i = 0; i < getters.length; i++) {
103 if (getters[i] != null) {
104 e.load_arg(1);
105 e.push(i);
106 e.load_local(bean);
107 e.invoke(getters[i]);
108 e.box(Type.getType(getters[i].getReturnType()));
109 e.aastore();
110 }
111 }
112 }
113 e.return_value();
114 e.end_method();
115 }
116
117 private void generateSet(final Class target, final Method[] setters) {
118 // setPropertyValues
119 CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SET_PROPERTY_VALUES, null, null);
120 if (setters.length > 0) {
121 Local index = e.make_local(Type.INT_TYPE);
122 e.push(0);
123 e.store_local(index);
124 e.load_arg(0);
125 e.checkcast(Type.getType(target));
126 e.load_arg(1);
127 Block handler = e.begin_block();
128 int lastIndex = 0;
129 for (int i = 0; i < setters.length; i++) {
130 if (setters[i] != null) {
131 int diff = i - lastIndex;
132 if (diff > 0) {
133 e.iinc(index, diff);
134 lastIndex = i;
135 }
136 e.dup2();
137 e.aaload(i);
138 e.unbox(Type.getType(setters[i].getParameterTypes()[0]));
139 e.invoke(setters[i]);
140 }
141 }
142 handler.end();
143 e.return_value();
144 e.catch_exception(handler, Constants.TYPE_THROWABLE);
145 e.new_instance(BULK_BEAN_EXCEPTION);
146 e.dup_x1();
147 e.swap();
148 e.load_local(index);
149 e.invoke_constructor(BULK_BEAN_EXCEPTION, CSTRUCT_EXCEPTION);
150 e.athrow();
151 } else {
152 e.return_value();
153 }
154 e.end_method();
155 }
156
157 private static void validate(Class target,
158 String[] getters,
159 String[] setters,
160 Class[] types,
161 Method[] getters_out,
162 Method[] setters_out) {
163 int i = -1;
164 if (setters.length != types.length || getters.length != types.length) {
165 throw new BulkBeanException("accessor array length must be equal type array length", i);
166 }
167 try {
168 for (i = 0; i < types.length; i++) {
169 if (getters[i] != null) {
170 Method method = ReflectUtils.findDeclaredMethod(target, getters[i], null);
171 if (method.getReturnType() != types[i]) {
172 throw new BulkBeanException("Specified type " + types[i] +
173 " does not match declared type " + method.getReturnType(), i);
174 }
175 if (Modifier.isPrivate(method.getModifiers())) {
176 throw new BulkBeanException("Property is private", i);
177 }
178 getters_out[i] = method;
179 }
180 if (setters[i] != null) {
181 Method method = ReflectUtils.findDeclaredMethod(target, setters[i], new Class[]{ types[i] });
182 if (Modifier.isPrivate(method.getModifiers()) ){
183 throw new BulkBeanException("Property is private", i);
184 }
185 setters_out[i] = method;
186 }
187 }
188 } catch (NoSuchMethodException e) {
189 throw new BulkBeanException("Cannot find specified property", i);
190 }
191 }
192 }
This page was automatically generated by Maven