예제 #1
0
 private void BuildFilterDefinitions(DocumentMapping classMapping)
 {
     foreach (var defAttribute in AttributeUtil.GetAttributes <FullTextFilterDefAttribute>(classMapping.MappedClass, false))
     {
         classMapping.FullTextFilterDefinitions.Add(BuildFilterDef(defAttribute));
     }
 }
예제 #2
0
 public IList <FilterDef> FullTextFilters(Type type)
 {
     return(AttributeUtil
            .GetAttributes <FullTextFilterDefAttribute>(type, false)
            .Select(CreateFilterDefinition)
            .ToList());
 }
예제 #3
0
        private void BuildClass(
            DocumentMapping documentMapping, bool isRoot,
            string path, BuildContext context
            )
        {
            IList <System.Type> hierarchy = new List <System.Type>();

            System.Type currClass = documentMapping.MappedClass;

            do
            {
                hierarchy.Add(currClass);
                currClass = currClass.BaseType;
                // NB Java stops at null we stop at object otherwise we process the class twice
                // We also need a null test for things like ISet which have no base class/interface
            } while (currClass != null && currClass != typeof(object));

            for (int index = hierarchy.Count - 1; index >= 0; index--)
            {
                currClass = hierarchy[index];

                /**
                 * Override the default analyzer for the properties if the class hold one
                 * That's the reason we go down the hierarchy
                 */

                // NB Must cast here as we want to look at the type's metadata
                var localAnalyzer = GetAnalyzer(currClass);
                var analyzer      = documentMapping.Analyzer ?? localAnalyzer;

                // Check for any ClassBridges
                var classBridgeAttributes = AttributeUtil.GetAttributes <ClassBridgeAttribute>(currClass);
                AttributeUtil.GetClassBridgeParameters(currClass, classBridgeAttributes);

                // Now we can process the class bridges
                foreach (var classBridgeAttribute in classBridgeAttributes)
                {
                    var bridge = BuildClassBridge(classBridgeAttribute, analyzer);
                    documentMapping.ClassBridges.Add(bridge);
                }

                // NB As we are walking the hierarchy only retrieve items at this level
                var propertyInfos = currClass.GetProperties(
                    BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance
                    );
                foreach (var propertyInfo in propertyInfos)
                {
                    BuildProperty(documentMapping, propertyInfo, analyzer, isRoot, path, context);
                }

                var fields = currClass.GetFields(
                    BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance
                    );
                foreach (var fieldInfo in fields)
                {
                    BuildProperty(documentMapping, fieldInfo, analyzer, isRoot, path, context);
                }
            }
        }
예제 #4
0
        private IFieldBridge GetFieldBridge(MemberInfo member)
        {
            var memberType = GetMemberType(member);

            return(BridgeFactory.GuessType(
                       member.Name, memberType,
                       AttributeUtil.GetFieldBridge(member),
                       AttributeUtil.GetAttribute <DateBridgeAttribute>(member)
                       ));
        }
예제 #5
0
        private FilterDef CreateFilterDefinition(FullTextFilterDefAttribute att)
        {
            try
            {
                Activator.CreateInstance(att.Impl);
            }
            catch (Exception ex)
            {
                throw new SearchException("Unable to create Filter class: " + att.Impl.FullName, ex);
            }

            var filterDefinition = new FilterDef
            {
                Name  = att.Name,
                Cache = att.Cache,
                Impl  = att.Impl
            };

            foreach (var method in filterDefinition.Impl.GetMethods())
            {
                if (AttributeUtil.HasAttribute <FactoryAttribute>(method))
                {
                    if (filterDefinition.FactoryMethod != null)
                    {
                        throw new SearchException("Multiple Factory methods found " + filterDefinition.Name + ":" +
                                                  filterDefinition.Impl.FullName + "." + method.Name);
                    }
                    filterDefinition.FactoryMethod = method;
                }

                if (AttributeUtil.HasAttribute <KeyAttribute>(method))
                {
                    if (filterDefinition.KeyMethod != null)
                    {
                        throw new SearchException("Multiple Key methods found " + filterDefinition.Name + ":" +
                                                  filterDefinition.Impl.FullName + "." + method.Name);
                    }
                    filterDefinition.KeyMethod = method;
                }
            }

            foreach (var prop in filterDefinition.Impl.GetProperties())
            {
                if (AttributeUtil.HasAttribute <FilterParameterAttribute>(prop))
                {
                    filterDefinition.Setters[prop.Name] = prop;
                }
            }

            return(filterDefinition);
        }
예제 #6
0
        private FilterDef BuildFilterDef(FullTextFilterDefAttribute attribute)
        {
            var filterDef = new FilterDef
            {
                Name  = attribute.Name,
                Impl  = attribute.Impl,
                Cache = attribute.Cache
            };

            try {
                Activator.CreateInstance(filterDef.Impl);
            }
            catch (Exception e) {
                throw new SearchException("Unable to create Filter class: " + filterDef.Impl.FullName, e);
            }

            foreach (var method in filterDef.Impl.GetMethods())
            {
                if (AttributeUtil.HasAttribute <FactoryAttribute>(method))
                {
                    if (filterDef.FactoryMethod != null)
                    {
                        throw new SearchException("Multiple Factory methods found " + filterDef.Name + ":" +
                                                  filterDef.Impl.FullName + "." + method.Name);
                    }
                    filterDef.FactoryMethod = method;
                }

                if (AttributeUtil.HasAttribute <KeyAttribute>(method))
                {
                    if (filterDef.KeyMethod != null)
                    {
                        throw new SearchException("Multiple Key methods found " + filterDef.Name + ":" +
                                                  filterDef.Impl.FullName + "." + method.Name);
                    }
                    filterDef.KeyMethod = method;
                }
            }

            // Use properties rather than the Java setter logic idea
            foreach (PropertyInfo prop in filterDef.Impl.GetProperties())
            {
                if (AttributeUtil.HasAttribute <FilterParameterAttribute>(prop))
                {
                    filterDef.AddSetter(prop);
                }
            }

            return(filterDef);
        }
예제 #7
0
        private Analyzer GetAnalyzer(MemberInfo member)
        {
            var attribute = AttributeUtil.GetAttribute <AnalyzerAttribute>(member);

            if (attribute == null)
            {
                return(null);
            }

            if (!typeof(Analyzer).IsAssignableFrom(attribute.Type))
            {
                throw new SearchException("Lucene analyzer not implemented by " + attribute.Type.FullName);
            }

            return(GetAnalyzerByType(attribute.Type));
        }
예제 #8
0
        private float?GetBoost(ICustomAttributeProvider member)
        {
            if (member == null)
            {
                return(null);
            }

            var boost = AttributeUtil.GetAttribute <BoostAttribute>(member);

            if (boost == null)
            {
                return(null);
            }

            return(boost.Value);
        }
예제 #9
0
        public DocumentMapping Build(Type type)
        {
            var documentMapping = new DocumentMapping(type)
            {
                Boost     = GetBoost(type),
                IndexName = AttributeUtil.GetAttribute <IndexedAttribute>(type).Index
            };

            var context = new BuildContext
            {
                Root      = documentMapping,
                Processed = { type }
            };

            BuildClass(documentMapping, true, string.Empty, context);
            BuildFilterDefinitions(documentMapping);

            return(documentMapping);
        }
예제 #10
0
 public IAnalyzerDefinition Analyzer(ICustomAttributeProvider member)
 {
     return(AttributeUtil.GetAttribute <AnalyzerAttribute>(member));
 }
예제 #11
0
 public IDateBridgeDefinition DateBridge(MemberInfo member)
 {
     return(AttributeUtil.GetAttribute <DateBridgeAttribute>(member));
 }
예제 #12
0
 public bool HasContainedInDefinition(MemberInfo member)
 {
     return(AttributeUtil.HasAttribute <ContainedInAttribute>(member));
 }
예제 #13
0
 public IIndexedEmbeddedDefinition IndexedEmbedded(MemberInfo member)
 {
     return(AttributeUtil.GetAttribute <IndexedEmbeddedAttribute>(member));
 }
예제 #14
0
 public IList <IFieldDefinition> FieldDefinitions(MemberInfo member)
 {
     return(AttributeUtil.GetAttributes <FieldAttribute>(member));
 }
예제 #15
0
 public IDocumentIdDefinition DocumentId(MemberInfo member)
 {
     return(AttributeUtil.GetAttribute <DocumentIdAttribute>(member));
 }
예제 #16
0
 public IEnumerable <IParameterDefinition> BridgeParameters(ICustomAttributeProvider member)
 {
     return(AttributeUtil.GetAttributes <ParameterAttribute>(member) ?? Enumerable.Empty <IParameterDefinition>());
 }
예제 #17
0
 public IFieldBridgeDefinition FieldBridge(MemberInfo member)
 {
     return(AttributeUtil.GetAttribute <FieldBridgeAttribute>(member));
 }
예제 #18
0
        private void BuildProperty(
            DocumentMapping documentMapping, MemberInfo member, Analyzer parentAnalyzer,
            bool isRoot, string path, BuildContext context
            )
        {
            IFieldBridge bridge = null;

            var analyzer = GetAnalyzer(member) ?? parentAnalyzer;
            var boost    = GetBoost(member);

            var getter = GetGetterFast(documentMapping.MappedClass, member);

            var documentIdAttribute = AttributeUtil.GetAttribute <DocumentIdAttribute>(member);

            if (documentIdAttribute != null)
            {
                string documentIdName = documentIdAttribute.Name ?? member.Name;
                bridge = GetFieldBridge(member);

                if (isRoot)
                {
                    if (!(bridge is ITwoWayFieldBridge))
                    {
                        throw new SearchException("Bridge for document id does not implement TwoWayFieldBridge: " + member.Name);
                    }

                    documentMapping.DocumentId = new DocumentIdMapping(
                        documentIdName, member.Name, (ITwoWayFieldBridge)bridge, getter
                        )
                    {
                        Boost = boost
                    };
                }
                else
                {
                    // Components should index their document id
                    documentMapping.Fields.Add(new FieldMapping(
                                                   GetAttributeName(member, documentIdName),
                                                   bridge, getter
                                                   )
                    {
                        Store = Attributes.Store.Yes,
                        Index = Attributes.Index.UnTokenized,
                        Boost = boost
                    });
                }
            }

            var fieldAttributes = AttributeUtil.GetFields(member);

            if (fieldAttributes.Length > 0)
            {
                if (bridge == null)
                {
                    bridge = GetFieldBridge(member);
                }

                foreach (var fieldAttribute in fieldAttributes)
                {
                    var fieldAnalyzer = GetAnalyzerByType(fieldAttribute.Analyzer) ?? analyzer;
                    var field         = new FieldMapping(
                        GetAttributeName(member, fieldAttribute.Name),
                        bridge, getter
                        )
                    {
                        Store    = fieldAttribute.Store,
                        Index    = fieldAttribute.Index,
                        Analyzer = fieldAnalyzer
                    };

                    documentMapping.Fields.Add(field);
                }
            }

            var embeddedAttribute = AttributeUtil.GetAttribute <IndexedEmbeddedAttribute>(member);

            if (embeddedAttribute != null)
            {
                int oldMaxLevel    = maxLevel;
                int potentialLevel = embeddedAttribute.Depth + level;
                if (potentialLevel < 0)
                {
                    potentialLevel = int.MaxValue;
                }

                maxLevel = potentialLevel > maxLevel ? maxLevel : potentialLevel;
                level++;

                System.Type elementType = embeddedAttribute.TargetElement ?? GetMemberTypeOrGenericArguments(member);

                var localPrefix = embeddedAttribute.Prefix == "." ? member.Name + "." : embeddedAttribute.Prefix;

                if (maxLevel == int.MaxValue && context.Processed.Contains(elementType))
                {
                    throw new SearchException(
                              string.Format(
                                  "Circular reference, Duplicate use of {0} in root entity {1}#{2}",
                                  elementType.FullName,
                                  context.Root.MappedClass.FullName,
                                  path + localPrefix));
                }


                if (level <= maxLevel)
                {
                    context.Processed.Add(elementType); // push
                    var embedded = new EmbeddedMapping(new DocumentMapping(elementType)
                    {
                        Boost    = GetBoost(member),
                        Analyzer = GetAnalyzer(member) ?? parentAnalyzer
                    }, getter)
                    {
                        Prefix = localPrefix
                    };

                    BuildClass(embedded.Class, false, path + localPrefix, context);

                    /**
                     * We will only index the "expected" type but that's OK, HQL cannot do downcasting either
                     */
                    // ayende: because we have to deal with generic collections here, we aren't
                    // actually using the element type to determine what the value is, since that
                    // was resolved to the element type of the possible collection
                    Type actualFieldType = GetMemberTypeOrGenericCollectionType(member);
                    embedded.IsCollection = typeof(IEnumerable).IsAssignableFrom(actualFieldType);

                    documentMapping.Embedded.Add(embedded);
                    context.Processed.Remove(actualFieldType); // pop
                }
                else if (logger.IsDebugEnabled)
                {
                    logger.Debug("Depth reached, ignoring " + path + localPrefix);
                }

                level--;
                maxLevel = oldMaxLevel; // set back the old max level
            }

            if (AttributeUtil.HasAttribute <ContainedInAttribute>(member))
            {
                documentMapping.ContainedIn.Add(new ContainedInMapping(getter));
            }
        }
예제 #19
0
 public IBoostDefinition Boost(ICustomAttributeProvider member)
 {
     return(AttributeUtil.GetAttribute <BoostAttribute>(member));
 }
예제 #20
0
 public IIndexedDefinition Indexed(Type type)
 {
     return(AttributeUtil.GetAttribute <IndexedAttribute>(type));
 }
예제 #21
0
 public IList <IClassBridgeDefinition> ClassBridges(Type type)
 {
     return(AttributeUtil.GetAttributes <ClassBridgeAttribute>(type));
 }
 private bool IsIndexed(Type type)
 {
     return(AttributeUtil.HasAttribute <IndexedAttribute>(type));
 }