private void BuildFilterDefinitions(DocumentMapping classMapping) { foreach (var filterDef in mappingDefinition.FullTextFilters(classMapping.MappedClass)) { classMapping.FullTextFilterDefinitions.Add(filterDef); } }
public EmbeddedMapping(DocumentMapping @class, IGetter getter) : base(getter) { this.Class = @class; this.Prefix = string.Empty; this.IsCollection = true; }
private void BuildClass(DocumentMapping documentMapping, bool isRoot, string path, BuildContext context) { IList<System.Type> hierarchy = new List<System.Type>(); var 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 classBridges = mappingDefinition.ClassBridges(currClass); GetClassBridgeParameters(currClass, classBridges); // Now we can process the class bridges foreach (var classBridge in classBridges) { var bridge = BuildClassBridge(classBridge, 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); } } }
public DocumentBuilder(DocumentMapping classMapping, Analyzer defaultAnalyzer, IDirectoryProvider[] directoryProviders, IIndexShardingStrategy shardingStrategy) { analyzer = new ScopedAnalyzer(); this.directoryProviders = directoryProviders; this.shardingStrategy = shardingStrategy; if (classMapping == null) throw new AssertionFailure("Unable to build a DocumemntBuilder with a null class"); rootClassMapping = classMapping; Set<System.Type> processedClasses = new HashedSet<System.Type>(); processedClasses.Add(classMapping.MappedClass); CollectAnalyzers(rootClassMapping, defaultAnalyzer, true, string.Empty, processedClasses); //processedClasses.remove( clazz ); for the sake of completness analyzer.GlobalAnalyzer = defaultAnalyzer; if (idMapping == null) throw new SearchException("No document id for: " + classMapping.MappedClass.Name); }
public DocumentMapping Build(System.Type type) { var documentMapping = new DocumentMapping(type) { Boost = GetBoost(type), IndexName = mappingDefinition.Indexed(type).Index }; var context = new BuildContext { Root = documentMapping, Processed = { type } }; BuildClass(documentMapping, true, string.Empty, context); BuildFilterDefinitions(documentMapping); return documentMapping; }
public DirectoryProviders CreateDirectoryProviders(DocumentMapping classMapping, Configuration cfg, ISearchFactoryImplementor searchFactoryImplementor) { // Get properties string directoryProviderName = GetDirectoryProviderName(classMapping, cfg); IDictionary<string, string>[] indexProps = GetDirectoryProperties(cfg, directoryProviderName); // Set up the directories int nbrOfProviders = indexProps.Length; IDirectoryProvider[] providers = new IDirectoryProvider[nbrOfProviders]; for (int index = 0; index < nbrOfProviders; index++) { string providerName = nbrOfProviders > 1 ? directoryProviderName + "." + index : directoryProviderName; // NB Are the properties nested?? providers[index] = CreateDirectoryProvider(providerName, indexProps[index], searchFactoryImplementor); } // Define sharding strategy IIndexShardingStrategy shardingStrategy; IDictionary<string, string> shardingProperties = new Dictionary<string, string>(); // Any indexProperty will do, the indexProps[0] surely exists. foreach (KeyValuePair<string, string> entry in indexProps[0]) { if (entry.Key.StartsWith(SHARDING_STRATEGY)) { shardingProperties.Add(entry); } } string shardingStrategyName; shardingProperties.TryGetValue(SHARDING_STRATEGY, out shardingStrategyName); if (string.IsNullOrEmpty(shardingStrategyName)) { if (indexProps.Length == 1) { shardingStrategy = new NotShardedStrategy(); } else { shardingStrategy = new IdHashShardingStrategy(); } } else { try { System.Type shardingStrategyClass = ReflectHelper.ClassForName(shardingStrategyName); shardingStrategy = (IIndexShardingStrategy) Activator.CreateInstance(shardingStrategyClass); } catch { // TODO: See if we can get a tigher exception trap here throw new SearchException("Failed to instantiate lucene analyzer with type " + shardingStrategyName); } } shardingStrategy.Initialize(shardingProperties, providers); return new DirectoryProviders(shardingStrategy, providers); }
private string GetDirectoryProviderName(DocumentMapping documentMapping, Configuration cfg) { return string.IsNullOrEmpty(documentMapping.IndexName) ? documentMapping.MappedClass.Name : documentMapping.IndexName; }
private void BindFilterDefs(DocumentMapping mappedClass) { // We only need one test here as we just support multiple FullTextFilter attributes rather than a collection foreach (var filterDef in mappedClass.FullTextFilterDefinitions) { if (filterDefinitions.ContainsKey(filterDef.Name)) throw new SearchException("Multiple definitions of FullTextFilterDef.Name = " + filterDef.Name + ":" + mappedClass.MappedClass.FullName); filterDefinitions[filterDef.Name] = filterDef; } }
private void CollectAnalyzers( DocumentMapping @class, Analyzer parentAnalyzer, bool isRoot, string prefix, ISet<System.Type> processedClasses ) { foreach (var bridge in @class.ClassBridges) { var bridgeAnalyzer = bridge.Analyzer ?? parentAnalyzer; if (bridgeAnalyzer == null) { throw new NotSupportedException("Analyzer should not be undefined"); } analyzer.AddScopedAnalyzer(prefix + bridge.Name, bridgeAnalyzer); } if (isRoot && @class.DocumentId != null) { idMapping = @class.DocumentId; } foreach (var field in @class.Fields) { CollectAnalyzer(field, parentAnalyzer, prefix); } foreach (var embedded in @class.Embedded) { CollectAnalyzers( embedded.Class, parentAnalyzer, false, prefix + embedded.Prefix, processedClasses ); } }
private void BuildDocumentFields(Object instance, Document doc, DocumentMapping classMapping, string prefix) { if (instance == null) { return; } object unproxiedInstance = Unproxy(instance); foreach (var bridge in classMapping.ClassBridges) { var bridgeName = prefix + bridge.Name; try { bridge.Bridge.Set( bridgeName, unproxiedInstance, doc, GetStore(bridge.Store), GetIndex(bridge.Index), bridge.Boost ); } catch (Exception e) { logger.Error( string.Format(CultureInfo.InvariantCulture, "Error processing class bridge for {0}", bridgeName), e); } } foreach (var field in classMapping.Fields) { BuildDocumentField(field, unproxiedInstance, doc, prefix); } foreach (var embedded in classMapping.Embedded) { BuildDocumentFieldsForEmbedded(embedded, unproxiedInstance, doc, prefix); } }
private static void ProcessFieldsForProjection( DocumentMapping mapping, String[] fields, Object[] result, Document document ) { foreach (var field in mapping.Fields) { PopulateResult( field, fields, result, document ); } foreach (var embedded in mapping.Embedded) { if (!embedded.IsCollection) ProcessFieldsForProjection(embedded.Class, fields, result, document); } }
private static void ProcessContainedIn(Object instance, List<LuceneWork> queue, DocumentMapping documentMapping, ISearchFactoryImplementor searchFactoryImplementor) { foreach (var containedIn in documentMapping.ContainedIn) { object value = containedIn.Getter.Get(instance); if (value == null) continue; Array array = value as Array; if (array != null) { foreach (object arrayValue in array) { // Highly inneficient but safe wrt the actual targeted class, e.g. polymorphic items in the array System.Type valueType = NHibernateUtil.GetClass(arrayValue); if (valueType == null || !searchFactoryImplementor.DocumentBuilders.ContainsKey(valueType)) { continue; } ProcessContainedInValue(arrayValue, queue, valueType, searchFactoryImplementor.DocumentBuilders[valueType], searchFactoryImplementor); } } else if (typeof(IEnumerable).IsAssignableFrom(value.GetType())) { // NB We only see ISet and IDictionary`2 as IEnumerable IEnumerable collection = value as IEnumerable; if (typeof(IDictionary).IsAssignableFrom(value.GetType())) { collection = ((IDictionary) value).Values; } if (collection == null) { continue; } foreach (object collectionValue in collection) { // Highly inneficient but safe wrt the actual targeted class, e.g. polymorphic items in the array System.Type valueType = NHibernateUtil.GetClass(collectionValue); if (valueType == null || !searchFactoryImplementor.DocumentBuilders.ContainsKey(valueType)) { continue; } ProcessContainedInValue(collectionValue, queue, valueType, searchFactoryImplementor.DocumentBuilders[valueType], searchFactoryImplementor); } } else { System.Type valueType = NHibernateUtil.GetClass(value); if (valueType == null || !searchFactoryImplementor.DocumentBuilders.ContainsKey(valueType)) { continue; } ProcessContainedInValue(value, queue, valueType, searchFactoryImplementor.DocumentBuilders[valueType], searchFactoryImplementor); } } //an embedded cannot have a useful @ContainedIn (no shared reference) //do not walk through them }
private static void ProcessFieldsForProjection( DocumentMapping mapping, String[] fields, Object[] result, Document document, string prefix ) { foreach (var field in mapping.Fields) { PopulateResult( prefix + field.Name, field.Bridge, field.Store, fields, result, document ); } foreach (var embedded in mapping.Embedded) { if (!embedded.IsCollection) ProcessFieldsForProjection(embedded.Class, fields, result, document, prefix + embedded.Prefix); } }
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 documentId = mappingDefinition.DocumentId(member); if (documentId != null) { string documentIdName = documentId.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( GetFieldName(member, documentIdName), bridge, getter) { Store = Attributes.Store.Yes, Index = Attributes.Index.UnTokenized, Boost = boost }); } } var fieldDefinitions = mappingDefinition.FieldDefinitions(member); if (fieldDefinitions.Count > 0) { if (bridge == null) bridge = GetFieldBridge(member); foreach (var fieldDefinition in fieldDefinitions) { fieldDefinition.Name = fieldDefinition.Name ?? member.Name; var fieldAnalyzer = GetAnalyzerByType(fieldDefinition.Analyzer) ?? analyzer; var field = new FieldMapping( GetFieldName(member, fieldDefinition.Name), bridge, getter ) { Store = fieldDefinition.Store, Index = fieldDefinition.Index, Analyzer = fieldAnalyzer, Boost = boost }; documentMapping.Fields.Add(field); } } var embeddedDefinition = mappingDefinition.IndexedEmbedded(member); if (embeddedDefinition != null) { int oldMaxLevel = maxLevel; int potentialLevel = embeddedDefinition.Depth + level; if (potentialLevel < 0) { potentialLevel = int.MaxValue; } maxLevel = potentialLevel > maxLevel ? maxLevel : potentialLevel; level++; System.Type elementType = embeddedDefinition.TargetElement ?? GetMemberTypeOrGenericArguments(member); var localPrefix = embeddedDefinition.Prefix == "." ? member.Name + "." : embeddedDefinition.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 System.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 (mappingDefinition.HasContainedInDefinition(member)) { documentMapping.ContainedIn.Add(new ContainedInMapping(getter)); } }