View Javadoc
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