Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2014-2015 the original author or authors.
   *
   * 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.
  */
 package org.lastaflute.di.helper.beans.impl;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 

Author(s):
modified by jflute (originated in Seasar)
 
 public class BeanDescImpl implements BeanDesc {
 
     private static final SLogger logger = SLogger.getLogger(BeanDescImpl.class);
     private static final Object[] EMPTY_ARGS = new Object[0];
     private static final Class<?>[] EMPTY_PARAM_TYPES = new Class[0];
     private static final String[] EMPTY_STRING_ARRAY = new String[0];
     private static final String PARAMETER_NAME_ANNOTATION = ParameterName.class.getName();
 
     private Class<?> beanClass;
     private Constructor<?>[] constructors;
     private Map typeVariables;
     private Map methodsCache = new HashMap();
     private ArrayMap<StringFieldfieldCache = new ArrayMap<StringField>();
     private ArrayMap<StringList<Field>> hiddenFieldCache// lazy loaded
     private transient Set<StringinvalidPropertyNames = new HashSet<String>();
     private Map methodParameterNamesCache;
 
     public BeanDescImpl(Class<?> beanClassthrows EmptyRuntimeException {
         if (beanClass == null) {
             throw new EmptyRuntimeException("beanClass");
         }
         this. = beanClass;
          = beanClass.getConstructors();
          = ParameterizedClassDescFactory.getTypeVariables(beanClass);
         setupPropertyDescs();
         setupMethods();
         setupFields();
     }
 
     public Class<?> getBeanClass() {
        return ;
    }
    public boolean hasPropertyDesc(String propertyName) {
        return .get(propertyName) != null;
    }
    public PropertyDesc getPropertyDesc(String propertyNamethrows PropertyNotFoundRuntimeException {
        PropertyDesc pd = (PropertyDesc.get(propertyName);
        if (pd == null) {
            throw new PropertyNotFoundRuntimeException(propertyName);
        }
        return pd;
    }
    private PropertyDesc getPropertyDesc0(String propertyName) {
        return (PropertyDesc.get(propertyName);
    }
    public PropertyDesc getPropertyDesc(int index) {
        return (PropertyDesc.get(index);
    }
    public int getPropertyDescSize() {
        return .size();
    }
    public boolean hasField(String fieldName) {
        return .get(fieldName) != null;
    }
    public Object newInstance(Object[] argsthrows ConstructorNotFoundRuntimeException {
        Constructor<?> constructor = getSuitableConstructor(args);
        return LdiConstructorUtil.newInstance(constructorargs);
    }
    public Object invoke(Object targetString methodNameObject[] args) {
        Method method = getSuitableMethod(methodNameargs);
        return LdiMethodUtil.invoke(methodtargetargs);
    }
        if (args == null) {
            args = ;
        }
        Constructor<?> constructor = findSuitableConstructor(args);
        if (constructor != null) {
            return constructor;
        }
        constructor = findSuitableConstructorAdjustNumber(args);
        if (constructor != null) {
            return constructor;
        }
        throw new ConstructorNotFoundRuntimeException(args);
    }
    public Constructor<?> getConstructor(final Class<?>[] paramTypes) {
        for (int i = 0; i < .; ++i) {
            if (Arrays.equals(paramTypes[i].getParameterTypes())) {
                return [i];
            }
        }
        throw new ConstructorNotFoundRuntimeException(paramTypes);
    }
    public Method getMethod(final String methodName) {
        return getMethod(methodName);
    }
    public Method getMethodNoException(final String methodName) {
        return getMethodNoException(methodName);
    }
    public Method getMethod(final String methodNamefinal Class[] paramTypes) {
        Method method = getMethodNoException(methodNameparamTypes);
        if (method != null) {
            return method;
        }
        throw new MethodNotFoundRuntimeException(methodNameparamTypes);
    }
    public Method getMethodNoException(final String methodNamefinal Class[] paramTypes) {
        final Method[] methods = (Method[]) .get(methodName);
        if (methods == null) {
            return null;
        }
        for (int i = 0; i < methods.length; ++i) {
            if (Arrays.equals(paramTypesmethods[i].getParameterTypes())) {
                return methods[i];
            }
        }
        return null;
    }
    public Method[] getMethods(String methodNamethrows MethodNotFoundRuntimeException {
        Method[] methods = (Method[]) .get(methodName);
        if (methods == null) {
            throw new MethodNotFoundRuntimeException(methodNamenull);
        }
        return methods;
    }
    public boolean hasMethod(String methodName) {
        return .get(methodName) != null;
    }
    public String[] getMethodNames() {
        return (String[]) .keySet().toArray(new String[.size()]);
    }
    public String[] getConstructorParameterNames(final Class[] parameterTypes) {
        return getConstructorParameterNames(getConstructor(parameterTypes));
    }
    public String[] getConstructorParameterNames(final Constructor<?> constructor) {
        if ( == null) {
        }
        if (!.containsKey(constructor)) {
            throw new ConstructorNotFoundRuntimeException(constructor.getParameterTypes());
        }
        return (String[]) .get(constructor);
    }
    public String[] getMethodParameterNamesNoException(final String methodNamefinal Class[] parameterTypes) {
        return getMethodParameterNamesNoException(getMethod(methodNameparameterTypes));
    }
    public String[] getMethodParameterNames(final String methodNamefinal Class[] parameterTypes) {
        return getMethodParameterNames(getMethod(methodNameparameterTypes));
    }
    public String[] getMethodParameterNames(final Method method) {
        String[] names = getMethodParameterNamesNoException(method);
        if (names == null || names.length != method.getParameterTypes().length) {
            throw new IllegalDiiguRuntimeException();
        }
        return names;
    }
    public String[] getMethodParameterNamesNoException(final Method method) {
        if ( == null) {
        }
        if (!.containsKey(method)) {
            throw new MethodNotFoundRuntimeException(method.getName(), method.getParameterTypes());
        }
        return (String[]) .get(method);
    }
        final Map map = new HashMap();
        final ClassPool pool = ClassPoolUtil.getClassPool();
        for (int i = 0; i < .; ++i) {
            final Constructor<?> constructor = [i];
            if (constructor.getParameterTypes().length == 0) {
                map.put(constructor);
                continue;
            }
            final CtClass clazz = ClassPoolUtil.toCtClass(poolconstructor.getDeclaringClass());
            final CtClass[] parameterTypes = ClassPoolUtil.toCtClassArray(poolconstructor.getParameterTypes());
            try {
                final String[] names = getParameterNames(clazz.getDeclaredConstructor(parameterTypes));
                map.put(constructornames);
            } catch (final NotFoundException e) {
                .log("WSSR0084"new Object[] { .getName(), constructor });
            }
        }
        return map;
    }
        final Map map = new HashMap();
        final ClassPool pool = ClassPoolUtil.getClassPool();
        for (final Iterator it = .values().iterator(); it.hasNext();) {
            final Method[] methods = (Method[]) it.next();
            for (int i = 0; i < methods.length; ++i) {
                final Method method = methods[i];
                if (method.getParameterTypes().length == 0) {
                    map.put(methods[i], );
                    continue;
                }
                final CtClass clazz = ClassPoolUtil.toCtClass(poolmethod.getDeclaringClass());
                final CtClass[] parameterTypes = ClassPoolUtil.toCtClassArray(poolmethod.getParameterTypes());
                try {
                    final String[] names = getParameterNames(clazz.getDeclaredMethod(method.getName(), parameterTypes));
                    map.put(methods[i], names);
                } catch (final NotFoundException e) {
                    .log("WSSR0085"new Object[] { .getName(), method });
                }
            }
        }
        return map;
    }
    private String[] getParameterNames(final CtBehavior behaviorthrows NotFoundException {
        final MethodInfo methodInfo = behavior.getMethodInfo();
        final ParameterAnnotationsAttribute attribute =
        if (attribute == null) {
            return null;
        }
        final int numParameters = behavior.getParameterTypes().length;
        final String[] parameterNames = new String[numParameters];
        final Annotation[][] annotationsArray = attribute.getAnnotations();
        if (annotationsArray == null || annotationsArray.length != numParameters) {
            return null;
        }
        for (int i = 0; i < numParameters; ++i) {
            final String parameterName = getParameterName(annotationsArray[i]);
            if (parameterName == null) {
                return null;
            }
            parameterNames[i] = parameterName;
        }
        return parameterNames;
    }
    private String getParameterName(final Annotation[] annotations) {
        Annotation nameAnnotation = null;
        for (int i = 0; i < annotations.length; ++i) {
            final Annotation annotation = annotations[i];
            if (.equals(annotation.getTypeName())) {
                nameAnnotation = annotation;
                break;
            }
        }
        if (nameAnnotation == null) {
            return null;
        }
        return ((StringMemberValuenameAnnotation.getMemberValue("value")).getValue();
    }
    private Constructor<?> findSuitableConstructor(Object[] args) {
        outerLoop: for (int i = 0; i < .; ++i) {
            Class<?>[] paramTypes = [i].getParameterTypes();
            if (paramTypes.length != args.length) {
                continue;
            }
            for (int j = 0; j < args.length; ++j) {
                if (args[j] == null || LdiClassUtil.isAssignableFrom(paramTypes[j], args[j].getClass())) {
                    continue;
                }
                continue outerLoop;
            }
            return [i];
        }
        return null;
    }
        outerLoop: for (int i = 0; i < .; ++i) {
            Class<?>[] paramTypes = [i].getParameterTypes();
            if (paramTypes.length != args.length) {
                continue;
            }
            for (int j = 0; j < args.length; ++j) {
                if (args[j] == null || LdiClassUtil.isAssignableFrom(paramTypes[j], args[j].getClass())
                        || adjustNumber(paramTypesargsj)) {
                    continue;
                }
                continue outerLoop;
            }
            return [i];
        }
        return null;
    }
    private static boolean adjustNumber(Class<?>[] paramTypesObject[] argsint index) {
        if (paramTypes[index].isPrimitive()) {
            if (paramTypes[index] == int.class) {
                args[index] = LdiIntegerConversionUtil.toInteger(args[index]);
                return true;
            } else if (paramTypes[index] == double.class) {
                args[index] = LdiDoubleConversionUtil.toDouble(args[index]);
                return true;
            } else if (paramTypes[index] == long.class) {
                args[index] = LdiLongConversionUtil.toLong(args[index]);
                return true;
            } else if (paramTypes[index] == short.class) {
                args[index] = LdiShortConversionUtil.toShort(args[index]);
                return true;
            } else if (paramTypes[index] == float.class) {
                args[index] = LdiFloatConversionUtil.toFloat(args[index]);
                return true;
            }
        } else {
            if (paramTypes[index] == Integer.class) {
                args[index] = LdiIntegerConversionUtil.toInteger(args[index]);
                return true;
            } else if (paramTypes[index] == Double.class) {
                args[index] = LdiDoubleConversionUtil.toDouble(args[index]);
                return true;
            } else if (paramTypes[index] == Long.class) {
                args[index] = LdiLongConversionUtil.toLong(args[index]);
                return true;
            } else if (paramTypes[index] == Short.class) {
                args[index] = LdiShortConversionUtil.toShort(args[index]);
                return true;
            } else if (paramTypes[index] == Float.class) {
                args[index] = LdiFloatConversionUtil.toFloat(args[index]);
                return true;
            }
        }
        return false;
    }
    private void setupPropertyDescs() {
        final Method[] methods = .getMethods();
        for (int i = 0; i < methods.lengthi++) {
            final Method method = methods[i];
            if (LdiMethodUtil.isBridgeMethod(method) || LdiMethodUtil.isSyntheticMethod(method)) {
                continue;
            }
            final String methodName = method.getName();
            if (methodName.startsWith("get")) {
                if (method.getParameterTypes().length != 0 || methodName.equals("getClass") || method.getReturnType() == void.class) {
                    continue;
                }
                final String propertyName = decapitalizePropertyName(methodName.substring(3));
                setupReadMethod(methodpropertyName);
            } else if (methodName.startsWith("is")) {
                if (method.getParameterTypes().length != 0 || !method.getReturnType().equals(.)
                        && !method.getReturnType().equals(Boolean.class)) {
                    continue;
                }
                final String propertyName = decapitalizePropertyName(methodName.substring(2));
                setupReadMethod(methodpropertyName);
            } else if (methodName.startsWith("set")) {
                if (method.getParameterTypes().length != 1 || methodName.equals("setClass") || method.getReturnType() != void.class) {
                    continue;
                }
                final String propertyName = decapitalizePropertyName(methodName.substring(3));
                setupWriteMethod(methodpropertyName);
            }
        }
        for (Iterator<?> i = .iterator(); i.hasNext();) {
            .remove(i.next());
        }
        .clear();
    }
    private static String decapitalizePropertyName(String name) {
        if (LdiStringUtil.isEmpty(name)) {
            return name;
        }
        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0))) {
            return name;
        }
        final char[] chars = name.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }
    private void addPropertyDesc(PropertyDesc propertyDescthrows EmptyRuntimeException {
        if (propertyDesc == null) {
            throw new EmptyRuntimeException("propertyDesc");
        }
        .put(propertyDesc.getPropertyName(), propertyDesc);
    }
    private void setupReadMethod(Method readMethodString propertyName) {
        final Class<?> propertyType = readMethod.getReturnType();
        final PropertyDesc propDesc = getPropertyDesc0(propertyName);
        if (propDesc != null) {
            if (!propDesc.getPropertyType().equals(propertyType)) {
                .add(propertyName);
            } else {
                propDesc.setReadMethod(readMethod);
            }
        } else {
            addPropertyDesc(new PropertyDescImpl(propertyNamepropertyTypereadMethodnullnullthis));
        }
    }
    private void setupWriteMethod(Method writeMethodString propertyName) {
        final Class<?> propertyType = writeMethod.getParameterTypes()[0];
        final PropertyDesc propDesc = getPropertyDesc0(propertyName);
        if (propDesc != null) {
            if (!propDesc.getPropertyType().equals(propertyType)) {
                .add(propertyName);
            } else {
                propDesc.setWriteMethod(writeMethod);
            }
        } else {
            addPropertyDesc(new PropertyDescImpl(propertyNamepropertyTypenullwriteMethodnullthis));
        }
    }
    private Method getSuitableMethod(String methodNameObject[] argsthrows MethodNotFoundRuntimeException {
        if (args == null) {
            args = ;
        }
        final Method[] methods = getMethods(methodName);
        Method method = findSuitableMethod(methodsargs);
        if (method != null) {
            return method;
        }
        method = findSuitableMethodAdjustNumber(methodsargs);
        if (method != null) {
            return method;
        }
        throw new MethodNotFoundRuntimeException(methodNameargs);
    }
    private Method findSuitableMethod(Method[] methodsObject[] args) {
        outerLoop: for (int i = 0; i < methods.length; ++i) {
            final Class<?>[] paramTypes = methods[i].getParameterTypes();
            if (paramTypes.length != args.length) {
                continue;
            }
            for (int j = 0; j < args.length; ++j) {
                if (args[j] == null || LdiClassUtil.isAssignableFrom(paramTypes[j], args[j].getClass())) {
                    continue;
                }
                continue outerLoop;
            }
            return methods[i];
        }
        return null;
    }
    private Method findSuitableMethodAdjustNumber(Method[] methodsObject[] args) {
        outerLoop: for (int i = 0; i < methods.length; ++i) {
            Class<?>[] paramTypes = methods[i].getParameterTypes();
            if (paramTypes.length != args.length) {
                continue;
            }
            for (int j = 0; j < args.length; ++j) {
                if (args[j] == null || LdiClassUtil.isAssignableFrom(paramTypes[j], args[j].getClass())
                        || adjustNumber(paramTypesargsj)) {
                    continue;
                }
                continue outerLoop;
            }
            return methods[i];
        }
        return null;
    }
    // ===================================================================================
    //                                                                      Set up Methods
    //                                                                      ==============
    private void setupMethods() {
        ArrayMap methodListMap = new ArrayMap();
        Method[] methods = .getMethods();
        for (int i = 0; i < methods.lengthi++) {
            Method method = methods[i];
            if (LdiMethodUtil.isBridgeMethod(method) || LdiMethodUtil.isSyntheticMethod(method)) {
                continue;
            }
            String methodName = method.getName();
            List list = (ListmethodListMap.get(methodName);
            if (list == null) {
                list = new ArrayList();
                methodListMap.put(methodNamelist);
            }
            list.add(method);
        }
        for (int i = 0; i < methodListMap.size(); ++i) {
            List methodList = (ListmethodListMap.get(i);
            .put(methodListMap.getKey(i), methodList.toArray(new Method[methodList.size()]));
        }
    }
    // ===================================================================================
    //                                                                       Set up Fields
    //                                                                       =============
    private void setupFields() {
        setupFields();
    }
    private void setupFields(Class<?> targetClass) {
        if (targetClass.isInterface()) {
            setupFieldsByInterface(targetClass);
        } else {
            setupFieldsByClass(targetClass);
        }
    }
    private void setupFieldsByInterface(Class<?> interfaceClass) {
        addFields(interfaceClass);
        final Class<?>[] interfaces = interfaceClass.getInterfaces();
        for (int i = 0; i < interfaces.length; ++i) {
            setupFieldsByInterface(interfaces[i]);
        }
    }
    private void setupFieldsByClass(Class<?> targetClass) {
        addFields(targetClass);
        final Class<?>[] interfaces = targetClass.getInterfaces();
        for (int i = 0; i < interfaces.length; ++i) {
            setupFieldsByInterface(interfaces[i]);
        }
        final Class<?> superClass = targetClass.getSuperclass();
        if (superClass != Object.class && superClass != null) {
            setupFieldsByClass(superClass);
        }
    }
    private void addFields(Class<?> clazz) {
        final Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; ++i) {
            final Field field = fields[i];
            final String fname = field.getName();
            if (!.containsKey(fname)) {
                field.setAccessible(true);
                .put(fnamefield);
                if (LdiFieldUtil.isInstanceField(field)) {
                    if (hasPropertyDesc(fname)) {
                        final PropertyDesc pd = getPropertyDesc(field.getName());
                        pd.setField(field);
                    } else if (LdiFieldUtil.isPublicField(field)) {
                        final PropertyDesc pd = new PropertyDescImpl(field.getName(), field.getType(), nullnullfieldthis);
                        .put(fnamepd);
                    }
                }
            } else { // hidden field (to inject them)
                field.setAccessible(true);
                if ( == null) {
                     = new ArrayMap<StringList<Field>>();
                }
                List<FieldhiddenFieldList = .get(fname);
                if (hiddenFieldList == null) {
                    hiddenFieldList = new ArrayList<Field>(2);
                    .put(fnamehiddenFieldList);
                }
                hiddenFieldList.add(field);
            }
        }
    }
    // ===================================================================================
    //                                                                        Field Access
    //                                                                        ============
    @Override
    public Object getFieldValue(String fieldNameObject targetthrows FieldNotFoundRuntimeException {
        return LdiFieldUtil.get(getField(fieldName), target);
    }
    @Override
    public Field getField(String fieldName) {
        final Field field = .get(fieldName);
        if (field == null) {
            throw new FieldNotFoundRuntimeException(fieldName);
        }
        return field;
    }
    @Override
    public Field getField(int index) {
        return .get(index);
    }
    @Override
    public int getFieldSize() {
        return .size();
    }
    @Override
    public List<FieldgetHiddenFieldList(String fieldName) {
        if ( != null) {
            final List<FieldfieldList = .get(fieldName);
            if (fieldList != null) {
                return Collections.unmodifiableList(fieldList);
            }
        }
        return Collections.emptyList();
    }
    // ===================================================================================
    //                                                                            Accessor
    //                                                                            ========
    Map getTypeVariables() {
        return ;
    }
New to GrepCode? Check out our FAQ X