Exemplo n.º 1
0
        public static object ParseFieldValue(Type modelType, string field, string fieldValue)
        {
            if (String.IsNullOrWhiteSpace(fieldValue) || fieldValue == "*" || fieldValue == "NULL")
            {
                return(null);
            }

            var prop = modelType.GetProperty(field, BindingFlags.Public | BindingFlags.Instance);

            if (prop == null)
            {
                // if not corresponding property was found, it might be custom fields, they are all treated as string
                return(fieldValue);
            }

            if (TypeHelper.IsSimpleType(prop.PropertyType))
            {
                return(LuceneUtility.FromFieldStringValue(fieldValue, prop.PropertyType));
            }

            var propTypeInfo = ModelTypeInfo.GetTypeInfo(prop.PropertyType);

            if (propTypeInfo.IsDictionary)
            {
                return(LuceneUtility.FromFieldStringValue(fieldValue, propTypeInfo.DictionaryValueType));
            }
            else if (propTypeInfo.IsCollection)
            {
                return(LuceneUtility.FromFieldStringValue(fieldValue, propTypeInfo.ElementType));
            }

            return(null);
        }
Exemplo n.º 2
0
        static IEnumerable <IFieldable> ToFields(object container, PropertyInfo property)
        {
            var fieldAttr = property.GetCustomAttribute <FieldAttribute>(false) ?? new FieldAttribute(Field.Index.NOT_ANALYZED, Field.Store.YES);
            var propType  = ModelTypeInfo.GetTypeInfo(property.PropertyType);

            if (propType.IsSimpleType)
            {
                var propValue = property.GetValue(container, null);
                yield return(fieldAttr.CreateLuceneField(property.Name, propValue));
            }
            else
            {
                if (propType.IsCollection)
                {
                    if (propType.IsDictionary)
                    {
                        if (!TypeHelper.IsSimpleType(propType.DictionaryKeyType))
                        {
                            throw new NotSupportedException("Not support complex dictionary key.");
                        }

                        if (TypeHelper.IsSimpleType(propType.DictionaryValueType))
                        {
                            var dic = property.GetValue(container, null) as IDictionary;
                            foreach (DictionaryEntry entry in dic)
                            {
                                var fieldName = GetDictionaryFieldName(property.Name, entry.Key.ToString());
                                yield return(fieldAttr.CreateLuceneField(fieldName, entry.Value));
                            }
                        }
                        else
                        {
                            var valueTypeInfo = ModelTypeInfo.GetTypeInfo(propType.DictionaryValueType);
                            if (valueTypeInfo.IsCollection && !valueTypeInfo.IsDictionary && TypeHelper.IsSimpleType(valueTypeInfo.ElementType))
                            {
                                var dic = property.GetValue(container, null) as IDictionary;
                                foreach (DictionaryEntry entry in dic)
                                {
                                    var fieldName = GetDictionaryFieldName(property.Name, entry.Key.ToString());
                                    var values    = entry.Value as IEnumerable;
                                    foreach (var value in values)
                                    {
                                        yield return(fieldAttr.CreateLuceneField(fieldName, value));
                                    }
                                }
                            }
                            else
                            {
                                throw new NotSupportedException("Not support dictionary property with value type other than simple type and simple type collection.");
                            }
                        }
                    }
                    else
                    {
                        if (!TypeHelper.IsSimpleType(propType.ElementType))
                        {
                            throw new NotSupportedException("Not support complex collection element.");
                        }

                        var items = property.GetValue(container, null) as IEnumerable;
                        if (items != null)
                        {
                            foreach (var item in items)
                            {
                                yield return(fieldAttr.CreateLuceneField(property.Name, item));
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        public static object ToModel(Document document, Type modelType)
        {
            var model = Activator.CreateInstance(modelType);

            foreach (var prop in modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (TypeHelper.IsSimpleType(prop.PropertyType))
                {
                    var field = document.GetField(prop.Name);
                    if (field != null)
                    {
                        var propValue = LuceneUtility.FromFieldStringValue(field.StringValue, prop.PropertyType);
                        prop.SetValue(model, propValue, null);
                    }
                }
                else
                {
                    var propTypeInfo = ModelTypeInfo.GetTypeInfo(prop.PropertyType);
                    if (propTypeInfo.IsCollection)
                    {
                        if (propTypeInfo.IsDictionary)
                        {
                            var propValue = prop.GetValue(model, null);
                            if (propValue == null)
                            {
                                propValue = Activator.CreateInstance(typeof(Dictionary <,>).MakeGenericType(propTypeInfo.DictionaryKeyType, propTypeInfo.DictionaryValueType));
                                prop.SetValue(model, propValue, null);
                            }

                            var dic    = propValue as IDictionary;
                            var fields = document.GetFields().Where(f => f.Name.StartsWith(prop.Name));

                            // Property type is IDictionary<TKey, TValue>
                            if (TypeHelper.IsSimpleType(propTypeInfo.DictionaryValueType))
                            {
                                foreach (var field in fields)
                                {
                                    string propName;
                                    string dicKey;

                                    if (TryParseDictionaryFieldName(field.Name, out propName, out dicKey))
                                    {
                                        var fieldValue = LuceneUtility.FromFieldStringValue(field.StringValue, propTypeInfo.DictionaryValueType);
                                        dic.Add(dicKey, fieldValue);
                                    }
                                }
                            }
                            else // Property type is IDictionary<TKey, IList<TValue>> or IDictionary<TKey, ISet<TValue>>
                            {
                                var dicValueTypeInfo = ModelTypeInfo.GetTypeInfo(propTypeInfo.DictionaryValueType);
                                if (dicValueTypeInfo.IsCollection && TypeHelper.IsSimpleType(dicValueTypeInfo.ElementType))
                                {
                                    Type       newDicValueType  = null;
                                    MethodInfo hashsetAddMethod = null;
                                    if (dicValueTypeInfo.IsSet)
                                    {
                                        newDicValueType  = typeof(HashSet <>).MakeGenericType(dicValueTypeInfo.ElementType);
                                        hashsetAddMethod = GetAddMethod(newDicValueType, dicValueTypeInfo.ElementType);
                                    }
                                    else
                                    {
                                        newDicValueType = typeof(List <>).MakeGenericType(dicValueTypeInfo.ElementType);
                                    }

                                    foreach (var field in fields)
                                    {
                                        string propName;
                                        string dicKey;

                                        if (TryParseDictionaryFieldName(field.Name, out propName, out dicKey))
                                        {
                                            var fieldValue = LuceneUtility.FromFieldStringValue(field.StringValue, dicValueTypeInfo.ElementType);
                                            if (!dic.Contains(dicKey))
                                            {
                                                dic.Add(dicKey, Activator.CreateInstance(newDicValueType));
                                            }

                                            var list = dic[dicKey];

                                            if (dicValueTypeInfo.IsSet) // is HashSet<>
                                            {
                                                hashsetAddMethod.Invoke(list, new[] { fieldValue });
                                            }
                                            else // is IList<>
                                            {
                                                (list as IList).Add(fieldValue);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else // Property is collection but not dictionary
                        {
                            var fields = document.GetFields(prop.Name);
                            if (fields.Length == 0)
                            {
                                continue;
                            }

                            var list = Activator.CreateInstance(typeof(List <>).MakeGenericType(propTypeInfo.ElementType)) as IList;

                            foreach (var field in fields)
                            {
                                var fieldValue = LuceneUtility.FromFieldStringValue(field.StringValue, propTypeInfo.ElementType);
                                list.Add(fieldValue);
                            }

                            if (prop.PropertyType.IsArray)
                            {
                                prop.SetValue(model, list.OfType <object>().ToArray(), null);
                            }
                            else
                            {
                                prop.SetValue(model, list, null);
                            }
                        }
                    }
                }
            }

            return(model);
        }
Exemplo n.º 4
0
        protected virtual void MapComplexProperty(PropertyInfo targetProperty, PropertyInfo sourceProperty, object sourcePropValue, object source, object target, Type sourceType, Type targetType, string propertyPath, MappingContext context)
        {
            object targetPropValue = targetProperty.GetValue(target, null);

            if (context.VisitedObjects.Contains(targetPropValue))
            {
                return;
            }

            var targetPropTypeInfo = ModelTypeInfo.GetTypeInfo(targetProperty.PropertyType);

            if (targetPropTypeInfo.IsCollection)
            {
                var sourcePropTypeInfo = ModelTypeInfo.GetTypeInfo(sourceProperty.PropertyType);

                if (targetPropTypeInfo.IsDictionary)
                {
                    if (sourcePropTypeInfo.IsDictionary)
                    {
                        // Map between dictionaries
                        var targetDic = Activator.CreateInstance(typeof(Dictionary <,>).MakeGenericType(targetPropTypeInfo.DictionaryKeyType, targetPropTypeInfo.DictionaryValueType)) as IDictionary;
                        targetProperty.SetValue(target, targetDic, null);

                        var sourceDic = sourcePropValue as IDictionary;
                        foreach (var key in sourceDic.Keys)
                        {
                            targetDic.Add(key, sourceDic[key]);
                        }
                    }
                    else if (sourcePropTypeInfo.IsCollection)
                    {
                        // source collection element: Name or Key field -> dictionary key, Value field -> dictionary value
                        var keyProp = sourcePropTypeInfo.ElementType.GetProperty("Key", BindingFlags.Public | BindingFlags.Instance);
                        if (keyProp == null)
                        {
                            keyProp = sourcePropTypeInfo.ElementType.GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);
                        }

                        if (keyProp != null)
                        {
                            var valueProp = sourcePropTypeInfo.ElementType.GetProperty("Value", BindingFlags.Public | BindingFlags.Instance);
                            if (valueProp != null)
                            {
                                var targetDic = Activator.CreateInstance(typeof(Dictionary <,>).MakeGenericType(targetPropTypeInfo.DictionaryKeyType, targetPropTypeInfo.DictionaryValueType)) as IDictionary;
                                foreach (var item in sourcePropValue as IEnumerable)
                                {
                                    var key   = keyProp.GetValue(item, null);
                                    var value = valueProp.GetValue(item, null);
                                    targetDic.Add(key, value);
                                }

                                targetProperty.SetValue(target, targetDic, null);
                            }
                        }
                    }
                }
                else // List or Array
                {
                    var sourceElementType = sourcePropTypeInfo.ElementType;

                    var elementMapper = GetMapperOrDefault(sourceElementType, targetPropTypeInfo.ElementType);
                    if (elementMapper == null)
                    {
                        return;
                    }

                    var targetList = Activator.CreateInstance(typeof(List <>).MakeGenericType(targetPropTypeInfo.ElementType));
                    var addMethod  = targetList.GetType().GetMethod("Add", BindingFlags.Public | BindingFlags.Instance, null, new[] { targetPropTypeInfo.ElementType }, null);

                    var sourceList    = sourcePropValue as IEnumerable;
                    var elementPrefix = propertyPath + ".";
                    var totalElements = 0;

                    foreach (var sourceElement in sourceList)
                    {
                        var targetElement = elementMapper.Map(sourceElement, Activator.CreateInstance(targetPropTypeInfo.ElementType), sourceElementType, targetPropTypeInfo.ElementType, elementPrefix, context);
                        addMethod.Invoke(targetList, new[] { targetElement });
                        totalElements++;
                    }

                    if (!Object.ReferenceEquals(targetList, targetPropValue))
                    {
                        if (targetProperty.PropertyType.IsArray)
                        {
                            var array = Array.CreateInstance(targetPropTypeInfo.ElementType, totalElements);
                            var i     = 0;
                            foreach (var item in targetList as IEnumerable)
                            {
                                array.SetValue(item, i);
                                i++;
                            }

                            targetProperty.SetValue(target, array, null);
                        }
                        else
                        {
                            targetProperty.SetValue(target, targetList, null);
                        }
                    }
                }
            }
            else
            {
                var mapper = GetMapperOrDefault(sourceProperty.PropertyType, targetProperty.PropertyType);
                if (mapper != null)
                {
                    if (targetPropValue == null)
                    {
                        targetPropValue = Activator.CreateInstance(targetProperty.PropertyType);
                    }

                    targetPropValue = mapper.Map(sourcePropValue, targetPropValue, sourceProperty.PropertyType, targetProperty.PropertyType, propertyPath + ".", context);

                    targetProperty.SetValue(target, targetPropValue, null);
                }
            }
        }