Ejemplo n.º 1
0
        protected PropertyInfoEntry GetPropertyEntry(Type type, SmartCopyMap <Type, PropertyInfoEntry> map, bool isOldIocMode, bool isIocMode)
        {
            ParamChecker.AssertParamNotNull(type, "type");
            PropertyInfoEntry propertyEntry = map.Get(type);

            if (propertyEntry != null)
            {
                return(propertyEntry);
            }
            Object writeLock = map.GetWriteLock();

            lock (writeLock)
            {
                propertyEntry = map.Get(type);
                if (propertyEntry != null)
                {
                    // Concurrent thread might have been faster
                    return(propertyEntry);
                }

                HashMap <String, HashMap <Type, HashMap <String, MethodInfo> > > sortedMethods = new HashMap <String, HashMap <Type, HashMap <String, MethodInfo> > >();
                MethodInfo[] methods = ReflectUtil.GetDeclaredMethodsInHierarchy(type);

                foreach (MethodInfo method in methods)
                {
                    if (method.DeclaringType.Equals(typeof(Object)))
                    {
                        continue;
                    }
                    if (method.IsStatic)
                    {
                        continue;
                    }
                    try
                    {
                        String propName = GetPropertyNameFor(method);
                        if (propName.Length == 0)
                        {
                            continue;
                        }
                        HashMap <Type, HashMap <String, MethodInfo> > sortedMethod = sortedMethods.Get(propName);
                        if (sortedMethod == null)
                        {
                            sortedMethod = HashMap <Type, HashMap <String, MethodInfo> > .Create(1);

                            sortedMethods.Put(propName, sortedMethod);
                        }

                        ParameterInfo[] parameterInfos = method.GetParameters();
                        Type            propertyType;
                        String          prefix;
                        if (parameterInfos.Length == 1)
                        {
                            propertyType = parameterInfos[0].ParameterType;
                            prefix       = "set";
                        }
                        else if (parameterInfos.Length == 0)
                        {
                            propertyType = method.ReturnType;
                            prefix       = "get";
                        }
                        else
                        {
                            throw new Exception("Method is not an accessor: " + method);
                        }

                        HashMap <String, MethodInfo> methodPerType = sortedMethod.Get(propertyType);
                        if (methodPerType == null)
                        {
                            methodPerType = HashMap <String, MethodInfo> .Create(2);

                            sortedMethod.Put(propertyType, methodPerType);
                        }

                        methodPerType.Put(prefix, method);
                    }
                    catch (Exception e)
                    {
                        throw RuntimeExceptionUtil.Mask(e, "Error occured while processing " + method);
                    }
                }

                HashMap <String, HashMap <String, MethodInfo> > filteredMethods = FilterOverriddenMethods(sortedMethods, type);

                HashMap <String, IPropertyInfo> propertyMap = new HashMap <String, IPropertyInfo>(0.5f);
                foreach (MapEntry <String, HashMap <String, MethodInfo> > propertyData in filteredMethods)
                {
                    String propertyName = propertyData.Key;

                    HashMap <String, MethodInfo> propertyMethods = propertyData.Value;
                    MethodInfo getter = propertyMethods.Get("get");
                    MethodInfo setter = propertyMethods.Get("set");

                    if (isIocMode)
                    {
                        if (setter == null ||
                            (!setter.IsPublic && !AnnotationUtil.IsAnnotationPresent <AutowiredAttribute>(setter, false) &&
                             !AnnotationUtil.IsAnnotationPresent <PropertyAttribute>(setter, false)))
                        {
                            continue;
                        }
                    }
                    MethodPropertyInfo propertyInfo = new MethodPropertyInfo(type, propertyName, getter, setter);
                    propertyMap.Put(propertyInfo.Name, propertyInfo);
                }

                Type[]      interfaces    = type.GetInterfaces();
                List <Type> typesToSearch = new List <Type>(interfaces);
                typesToSearch.Add(type);
                foreach (Type typeToSearch in typesToSearch)
                {
                    PropertyInfo[] properties = typeToSearch.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);
                    foreach (PropertyInfo property in properties)
                    {
                        if (property.GetGetMethod() != null && property.GetGetMethod().GetParameters().Length != 0)
                        {
                            continue;
                        }
                        if (property.GetSetMethod() != null && property.GetSetMethod().GetParameters().Length != 1)
                        {
                            continue;
                        }
                        MethodInfo getter = null;
                        MethodInfo setter = null;

                        MethodPropertyInfo propertyInfo = (MethodPropertyInfo)propertyMap.Get(property.Name);
                        if (propertyInfo != null)
                        {
                            getter = propertyInfo.Getter;
                            setter = propertyInfo.Setter;
                        }
                        if (getter == null)
                        {
                            getter = property.GetGetMethod();
                        }
                        if (setter == null)
                        {
                            setter = property.GetSetMethod();
                        }
                        if (isIocMode && setter == null)
                        {
                            continue;
                        }
                        propertyInfo = new MethodPropertyInfo(type, property.Name, getter, setter);
                        propertyInfo.PutAnnotations(property);
                        propertyMap.Put(propertyInfo.Name, propertyInfo);
                    }
                }

                FieldInfo[] fields = ReflectUtil.GetDeclaredFieldsInHierarchy(type);
                foreach (FieldInfo field in fields)
                {
                    if (field.IsStatic)
                    {
                        continue;
                    }
                    if (isOldIocMode)
                    {
                        if (!AnnotationUtil.IsAnnotationPresent <AutowiredAttribute>(field, false) && !AnnotationUtil.IsAnnotationPresent <PropertyAttribute>(field, false))
                        {
                            continue;
                        }
                    }
                    String        propertyName     = GetPropertyNameFor(field);
                    IPropertyInfo existingProperty = propertyMap.Get(propertyName);
                    if (existingProperty != null && existingProperty.IsWritable)
                    {
                        // Ignore field injection if the already resolved (method-)property is writable
                        continue;
                    }
                    IPropertyInfo propertyInfo = new FieldPropertyInfo(type, propertyName, field);
                    propertyMap.Put(propertyInfo.Name, propertyInfo);
                }
                propertyEntry = new PropertyInfoEntry(propertyMap);
                map.Put(type, propertyEntry);
                return(propertyEntry);
            }
        }