1674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/* 2674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Copyright 2003,2004 The Apache Software Foundation 3674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 4674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Licensed under the Apache License, Version 2.0 (the "License"); 5674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * you may not use this file except in compliance with the License. 6674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * You may obtain a copy of the License at 7674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 8674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * http://www.apache.org/licenses/LICENSE-2.0 9674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 10674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Unless required by applicable law or agreed to in writing, software 11674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * distributed under the License is distributed on an "AS IS" BASIS, 12674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * See the License for the specific language governing permissions and 14674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * limitations under the License. 15674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 16674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpackage org.mockito.cglib.proxy; 17674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 18674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.util.*; 19674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 20674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.Label; 21674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.Type; 22674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.cglib.core.*; 23674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 24674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass LazyLoaderGenerator implements CallbackGenerator { 25674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public static final LazyLoaderGenerator INSTANCE = new LazyLoaderGenerator(); 26674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 27674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private static final Signature LOAD_OBJECT = 28674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen TypeUtils.parseSignature("Object loadObject()"); 29674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private static final Type LAZY_LOADER = 30674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen TypeUtils.parseType("org.mockito.cglib.proxy.LazyLoader"); 31674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 32674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void generate(ClassEmitter ce, Context context, List methods) { 33674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Set indexes = new HashSet(); 34674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (Iterator it = methods.iterator(); it.hasNext();) { 35674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen MethodInfo method = (MethodInfo)it.next(); 36674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (TypeUtils.isProtected(method.getModifiers())) { 37674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen // ignore protected methods 38674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 39674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen int index = context.getIndex(method); 40674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen indexes.add(new Integer(index)); 41674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen CodeEmitter e = context.beginMethod(ce, method); 42674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.load_this(); 43674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.dup(); 44674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.invoke_virtual_this(loadMethod(index)); 45674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.checkcast(method.getClassInfo().getType()); 46674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.load_args(); 47674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.invoke(method); 48674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.return_value(); 49674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.end_method(); 50674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 51674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 52674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 53674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (Iterator it = indexes.iterator(); it.hasNext();) { 54674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen int index = ((Integer)it.next()).intValue(); 55674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 56674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String delegate = "CGLIB$LAZY_LOADER_" + index; 57674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen ce.declare_field(Constants.ACC_PRIVATE, delegate, Constants.TYPE_OBJECT, null); 58674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 59674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen CodeEmitter e = ce.begin_method(Constants.ACC_PRIVATE | 60674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Constants.ACC_SYNCHRONIZED | 61674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Constants.ACC_FINAL, 62674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen loadMethod(index), 63674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen null); 64674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.load_this(); 65674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.getfield(delegate); 66674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.dup(); 67674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Label end = e.make_label(); 68674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.ifnonnull(end); 69674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.pop(); 70674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.load_this(); 71674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen context.emitCallback(e, index); 72674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.invoke_interface(LAZY_LOADER, LOAD_OBJECT); 73674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.dup_x1(); 74674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.putfield(delegate); 75674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.mark(end); 76674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.return_value(); 77674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen e.end_method(); 78674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 79674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 80674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 81674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 82674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private Signature loadMethod(int index) { 83674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return new Signature("CGLIB$LOAD_PRIVATE_" + index, 84674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Constants.TYPE_OBJECT, 85674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Constants.TYPES_EMPTY); 86674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 87674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 88674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void generateStatic(CodeEmitter e, Context context, List methods) { } 89674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen} 90