/** * Copyright 2008 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loonframework * @author chenpeng * @email:ceponline@yahoo.com.cn * @version 0.2 */ package org.ripple.power.ioc; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Set; import org.ripple.power.collection.MapArray; import org.ripple.power.utils.CollectionUtils; import org.ripple.power.utils.ReflectorUtils; public class ClassMethod { private final MapArray fieldList = CollectionUtils.createArrayMap(); private final MapArray methods = CollectionUtils.createArrayMap(); private final MapArray fieldTypes = CollectionUtils.createArrayMap(); private final MapArray getterMethods = CollectionUtils.createArrayMap(); private final MapArray setterMethods = CollectionUtils.createArrayMap(); private final Set<Object> nonGetters = CollectionUtils.createSet(); /** * 缓冲对应类数据,并设置是否保存Final方法 * * @param clazz * @param includeFinalMethods */ public ClassMethod(final Class<?> clazz, final boolean includeFinalMethods) { processClass(clazz, includeFinalMethods); } /** * 缓冲对应类数据,并设置是否保存Final方法 * * @param clazz * @param includeFinalMethods */ private void processClass(final Class<?> clazz, final boolean includeFinalMethods) { final Method[] methods = clazz.getMethods(); for (int i = 0; i < methods.length; i++) { final int mask = includeFinalMethods ? Modifier.PUBLIC : Modifier.PUBLIC | Modifier.FINAL; if (((methods[i].getModifiers() & mask) == Modifier.PUBLIC) && (methods[i].getParameterTypes().length == 0) && (!methods[i].getName().equals("<init>")) && (!methods[i].getName().equals("<clinit>")) && (methods[i].getReturnType() != void.class)) { final int fieldIndex = this.methods.size(); addToMapping(methods[i], fieldIndex); } else if (((methods[i].getModifiers() & mask) == Modifier.PUBLIC)) { final int fieldIndex = this.methods.size(); addToMapping(methods[i], fieldIndex); } } addFieldToMapping(clazz); } private void addToMapping(final Method method, final int index) { String methodName = ReflectorUtils.getMethodName(method); int offset = ReflectorUtils.getMethodOffsetAll(methodName); if (this.methods.containsKey(methodName)) { if (offset != 0 && this.nonGetters.contains(methodName)) { removeOldMethod(methodName); storeMethod(methodName, method); storeGetterSetter(method, methodName); this.nonGetters.remove(methodName); } else if (offset != 0) { storeGetterSetter(method, methodName); } } else { storeMethod(methodName, method); storeGetterSetter(method, methodName); if (offset == 0) { this.nonGetters.add(methodName); } } } /** * 记录类中的Field * * @param clazz */ private void addFieldToMapping(final Class<?> clazz) { Field[] fields = clazz.getFields(); for (int i = 0; i < fields.length; i++) { addFieldToMapping(fields[i]); } } /** * 记录Field * * @param field */ private void addFieldToMapping(final Field field) { try { fieldList.put(field.getName(), field); } catch (final Exception ex) { throw new RuntimeException(ex); } } public MapArray getFields() { return this.fieldList; } public MapArray getMethods() { return this.methods; } public MapArray getMethodFieldTypes() { return this.fieldTypes; } public MapArray getGetterMethods() { return this.getterMethods; } public MapArray getSetterMethods() { return this.setterMethods; } private void removeOldMethod(final String methodName) { this.methods.remove(methodName); this.fieldTypes.remove(methodName); this.getterMethods.remove(methodName); } private void storeMethod(final String methodName, final Method method) { this.methods.put(methodName, method); } private void storeGetterSetter(final Method method, final String methodName) { if (method.getName().startsWith("set")) { this.setterMethods.put(methodName, method); if (!fieldTypes.containsKey(methodName)) { if (method.getParameterTypes().length > 0) { this.fieldTypes.put(methodName, method.getParameterTypes()[0]); } } } else { this.getterMethods.put(methodName, method); this.fieldTypes.put(methodName, method.getReturnType()); } } }