KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > cglib > beans > BulkBeanEmitter


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.beans;
17
18 import java.lang.reflect.Constructor JavaDoc;
19 import java.lang.reflect.Method JavaDoc;
20 import java.lang.reflect.Modifier JavaDoc;
21 import java.util.*;
22 import net.sf.cglib.core.*;
23 import org.objectweb.asm.ClassVisitor;
24 import org.objectweb.asm.Type;
25     
26 class BulkBeanEmitter extends ClassEmitter {
27     private static final Signature GET_PROPERTY_VALUES =
28       TypeUtils.parseSignature("void getPropertyValues(Object, Object[])");
29     private static final Signature SET_PROPERTY_VALUES =
30       TypeUtils.parseSignature("void setPropertyValues(Object, Object[])");
31     private static final Signature CSTRUCT_EXCEPTION =
32       TypeUtils.parseConstructor("Throwable, int");
33     private static final Type BULK_BEAN =
34       TypeUtils.parseType("net.sf.cglib.beans.BulkBean");
35     private static final Type BULK_BEAN_EXCEPTION =
36       TypeUtils.parseType("net.sf.cglib.beans.BulkBeanException");
37         
38     public BulkBeanEmitter(ClassVisitor v,
39                            String JavaDoc className,
40                            Class JavaDoc target,
41                            String JavaDoc[] getterNames,
42                            String JavaDoc[] setterNames,
43                            Class JavaDoc[] types) {
44         super(v);
45
46         Method JavaDoc[] getters = new Method JavaDoc[getterNames.length];
47         Method JavaDoc[] setters = new Method JavaDoc[setterNames.length];
48         validate(target, getterNames, setterNames, types, getters, setters);
49
50         begin_class(Constants.V1_2, Constants.ACC_PUBLIC, className, BULK_BEAN, null, Constants.SOURCE_FILE);
51         EmitUtils.null_constructor(this);
52         generateGet(target, getters);
53         generateSet(target, setters);
54         end_class();
55     }
56
57     private void generateGet(final Class JavaDoc target, final Method JavaDoc[] getters) {
58         CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_VALUES, null);
59         if (getters.length >= 0) {
60             e.load_arg(0);
61             e.checkcast(Type.getType(target));
62             Local bean = e.make_local();
63             e.store_local(bean);
64             for (int i = 0; i < getters.length; i++) {
65                 if (getters[i] != null) {
66                     MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]);
67                     e.load_arg(1);
68                     e.push(i);
69                     e.load_local(bean);
70                     e.invoke(getter);
71                     e.box(getter.getSignature().getReturnType());
72                     e.aastore();
73                 }
74             }
75         }
76         e.return_value();
77         e.end_method();
78     }
79
80     private void generateSet(final Class JavaDoc target, final Method JavaDoc[] setters) {
81         // setPropertyValues
82
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SET_PROPERTY_VALUES, null);
83         if (setters.length > 0) {
84             Local index = e.make_local(Type.INT_TYPE);
85             e.push(0);
86             e.store_local(index);
87             e.load_arg(0);
88             e.checkcast(Type.getType(target));
89             e.load_arg(1);
90             Block handler = e.begin_block();
91             int lastIndex = 0;
92             for (int i = 0; i < setters.length; i++) {
93                 if (setters[i] != null) {
94                     MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]);
95                     int diff = i - lastIndex;
96                     if (diff > 0) {
97                         e.iinc(index, diff);
98                         lastIndex = i;
99                     }
100                     e.dup2();
101                     e.aaload(i);
102                     e.unbox(setter.getSignature().getArgumentTypes()[0]);
103                     e.invoke(setter);
104                 }
105             }
106             handler.end();
107             e.return_value();
108             e.catch_exception(handler, Constants.TYPE_THROWABLE);
109             e.new_instance(BULK_BEAN_EXCEPTION);
110             e.dup_x1();
111             e.swap();
112             e.load_local(index);
113             e.invoke_constructor(BULK_BEAN_EXCEPTION, CSTRUCT_EXCEPTION);
114             e.athrow();
115         } else {
116             e.return_value();
117         }
118         e.end_method();
119     }
120     
121     private static void validate(Class JavaDoc target,
122                                  String JavaDoc[] getters,
123                                  String JavaDoc[] setters,
124                                  Class JavaDoc[] types,
125                                  Method JavaDoc[] getters_out,
126                                  Method JavaDoc[] setters_out) {
127         int i = -1;
128         if (setters.length != types.length || getters.length != types.length) {
129             throw new BulkBeanException("accessor array length must be equal type array length", i);
130         }
131         try {
132             for (i = 0; i < types.length; i++) {
133                 if (getters[i] != null) {
134                     Method JavaDoc method = ReflectUtils.findDeclaredMethod(target, getters[i], null);
135                     if (method.getReturnType() != types[i]) {
136                         throw new BulkBeanException("Specified type " + types[i] +
137                                                     " does not match declared type " + method.getReturnType(), i);
138                     }
139                     if (Modifier.isPrivate(method.getModifiers())) {
140                         throw new BulkBeanException("Property is private", i);
141                     }
142                     getters_out[i] = method;
143                 }
144                 if (setters[i] != null) {
145                     Method JavaDoc method = ReflectUtils.findDeclaredMethod(target, setters[i], new Class JavaDoc[]{ types[i] });
146                     if (Modifier.isPrivate(method.getModifiers()) ){
147                         throw new BulkBeanException("Property is private", i);
148                     }
149                     setters_out[i] = method;
150                 }
151             }
152         } catch (NoSuchMethodException JavaDoc e) {
153             throw new BulkBeanException("Cannot find specified property", i);
154         }
155     }
156 }
157
Popular Tags