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.lang.reflect.Constructor; 19674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.lang.reflect.Modifier; 20674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.util.*; 21674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 22674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.ClassVisitor; 23674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.cglib.core.*; 24674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 25674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 26674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 27674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/** 28674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * <code>Mixin</code> allows 29674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * multiple objects to be combined into a single larger object. The 30674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * methods in the generated object simply call the original methods in the 31674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * underlying "delegate" objects. 32674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @author Chris Nokleberg 33674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @version $Id: Mixin.java,v 1.7 2005/09/27 11:42:27 baliuka Exp $ 34674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 35674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenabstract public class Mixin { 36674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private static final MixinKey KEY_FACTORY = 37674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen (MixinKey)KeyFactory.create(MixinKey.class, KeyFactory.CLASS_BY_NAME); 38674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private static final Map ROUTE_CACHE = Collections.synchronizedMap(new HashMap()); 39674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 40674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public static final int STYLE_INTERFACES = 0; 41674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public static final int STYLE_BEANS = 1; 42674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public static final int STYLE_EVERYTHING = 2; 43674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 44674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interface MixinKey { 45674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Object newInstance(int style, String[] classes, int[] route); 46674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 47674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 48674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen abstract public Mixin newInstance(Object[] delegates); 49674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 50674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 51674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Helper method to create an interface mixin. For finer control over the 52674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * generated instance, use a new instance of <code>Mixin</code> 53674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * instead of this static method. 54674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * TODO 55674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 56674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public static Mixin create(Object[] delegates) { 57674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Generator gen = new Generator(); 58674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen gen.setDelegates(delegates); 59674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return gen.create(); 60674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 61674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 62674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 63674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Helper method to create an interface mixin. For finer control over the 64674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * generated instance, use a new instance of <code>Mixin</code> 65674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * instead of this static method. 66674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * TODO 67674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 68674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public static Mixin create(Class[] interfaces, Object[] delegates) { 69674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Generator gen = new Generator(); 70674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen gen.setClasses(interfaces); 71674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen gen.setDelegates(delegates); 72674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return gen.create(); 73674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 74674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 75674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 76674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public static Mixin createBean(Object[] beans) { 77674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 78674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return createBean(null, beans); 79674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 80674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 81674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 82674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Helper method to create a bean mixin. For finer control over the 83674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * generated instance, use a new instance of <code>Mixin</code> 84674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * instead of this static method. 85674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * TODO 86674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 87674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public static Mixin createBean(ClassLoader loader,Object[] beans) { 88674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Generator gen = new Generator(); 89674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen gen.setStyle(STYLE_BEANS); 90674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen gen.setDelegates(beans); 91674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen gen.setClassLoader(loader); 92674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return gen.create(); 93674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 94674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 95674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public static class Generator extends AbstractClassGenerator { 96674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private static final Source SOURCE = new Source(Mixin.class.getName()); 97674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 98674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private Class[] classes; 99674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private Object[] delegates; 100674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private int style = STYLE_INTERFACES; 101674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 102674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private int[] route; 103674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 104674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Generator() { 105674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen super(SOURCE); 106674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 107674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 108674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen protected ClassLoader getDefaultClassLoader() { 109674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return classes[0].getClassLoader(); // is this right? 110674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 111674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 112674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void setStyle(int style) { 113674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen switch (style) { 114674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case STYLE_INTERFACES: 115674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case STYLE_BEANS: 116674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case STYLE_EVERYTHING: 117674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this.style = style; 118674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 119674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen default: 120674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IllegalArgumentException("Unknown mixin style: " + style); 121674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 122674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 123674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 124674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void setClasses(Class[] classes) { 125674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this.classes = classes; 126674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 127674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 128674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void setDelegates(Object[] delegates) { 129674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this.delegates = delegates; 130674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 131674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 132674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Mixin create() { 133674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (classes == null && delegates == null) { 134674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IllegalStateException("Either classes or delegates must be set"); 135674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 136674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen switch (style) { 137674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case STYLE_INTERFACES: 138674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (classes == null) { 139674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Route r = route(delegates); 140674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen classes = r.classes; 141674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen route = r.route; 142674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 143674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 144674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case STYLE_BEANS: 145674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen // fall-through 146674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case STYLE_EVERYTHING: 147674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (classes == null) { 148674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen classes = ReflectUtils.getClasses(delegates); 149674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 150674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (delegates != null) { 151674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Class[] temp = ReflectUtils.getClasses(delegates); 152674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (classes.length != temp.length) { 153674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IllegalStateException("Specified classes are incompatible with delegates"); 154674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 155674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (int i = 0; i < classes.length; i++) { 156674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (!classes[i].isAssignableFrom(temp[i])) { 157674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IllegalStateException("Specified class " + classes[i] + " is incompatible with delegate class " + temp[i] + " (index " + i + ")"); 158674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 159674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 160674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 161674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 162674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 163674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen setNamePrefix(classes[ReflectUtils.findPackageProtected(classes)].getName()); 164674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 165674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return (Mixin)super.create(KEY_FACTORY.newInstance(style, ReflectUtils.getNames( classes ), route)); 166674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 167674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 168674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void generateClass(ClassVisitor v) { 169674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen switch (style) { 170674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case STYLE_INTERFACES: 171674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen new MixinEmitter(v, getClassName(), classes, route); 172674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 173674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case STYLE_BEANS: 174674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen new MixinBeanEmitter(v, getClassName(), classes); 175674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 176674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case STYLE_EVERYTHING: 177674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen new MixinEverythingEmitter(v, getClassName(), classes); 178674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 179674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 180674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 181674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 182674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen protected Object firstInstance(Class type) { 183674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return ((Mixin)ReflectUtils.newInstance(type)).newInstance(delegates); 184674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 185674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 186674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen protected Object nextInstance(Object instance) { 187674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return ((Mixin)instance).newInstance(delegates); 188674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 189674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 190674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 191674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public static Class[] getClasses(Object[] delegates) { 192674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return (Class[])route(delegates).classes.clone(); 193674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 194674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 195674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen// public static int[] getRoute(Object[] delegates) { 196674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen// return (int[])route(delegates).route.clone(); 197674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen// } 198674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 199674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private static Route route(Object[] delegates) { 200674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Object key = ClassesKey.create(delegates); 201674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Route route = (Route)ROUTE_CACHE.get(key); 202674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (route == null) { 203674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen ROUTE_CACHE.put(key, route = new Route(delegates)); 204674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 205674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return route; 206674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 207674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 208674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private static class Route 209674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen { 210674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private Class[] classes; 211674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private int[] route; 212674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 213674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Route(Object[] delegates) { 214674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Map map = new HashMap(); 215674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen ArrayList collect = new ArrayList(); 216674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (int i = 0; i < delegates.length; i++) { 217674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Class delegate = delegates[i].getClass(); 218674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen collect.clear(); 219674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen ReflectUtils.addAllInterfaces(delegate, collect); 220674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (Iterator it = collect.iterator(); it.hasNext();) { 221674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Class iface = (Class)it.next(); 222674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (!map.containsKey(iface)) { 223674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen map.put(iface, new Integer(i)); 224674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 225674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 226674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 227674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen classes = new Class[map.size()]; 228674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen route = new int[map.size()]; 229674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen int index = 0; 230674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (Iterator it = map.keySet().iterator(); it.hasNext();) { 231674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Class key = (Class)it.next(); 232674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen classes[index] = key; 233674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen route[index] = ((Integer)map.get(key)).intValue(); 234674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen index++; 235674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 236674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 237674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 238674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen} 239