Esempio n. 1
0
        /// <summary>
        /// Gets the document.
        /// </summary>
        /// <param name="fetchXmlResult">The fetch XML result.</param>
        /// <returns></returns>
        /// <exception cref="System.InvalidOperationException">
        /// </exception>
        public CrmEntityIndexDocument GetDocument(FetchXmlResult fetchXmlResult)
        {
            var entityMetadata = _dataContext.GetEntityMetadata(_fetchXml.LogicalName, _metadataCache);

            var attributes = entityMetadata.Attributes.ToDictionary(a => a.LogicalName, a => a);

            var document = new Document();

            var primaryKey = Guid.Empty;

            var languageValueAdded = false;

            var lcid = 0;

            // Store the entity logical name and the logical name of the primary key attribute in the index document, for
            // easier later retrieval of the entity corresponding to this document.
            document.Add(
                new Field(_index.LogicalNameFieldName, entityMetadata.LogicalName, Field.Store.YES, Field.Index.NOT_ANALYZED));
            document.Add(
                new Field(
                    _index.PrimaryKeyLogicalNameFieldName,
                    entityMetadata.PrimaryIdAttribute,
                    Field.Store.YES,
                    Field.Index.NOT_ANALYZED));
            try
            {
                var content = new ContentFieldBuilder();

                foreach (var fetchXmlField in fetchXmlResult)
                {
                    // Treat the primary key field in a special way.
                    if (fetchXmlField.Name == entityMetadata.PrimaryIdAttribute)
                    {
                        primaryKey = new Guid(fetchXmlField.Value);

                        document.Add(new Field(_index.PrimaryKeyFieldName, primaryKey.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                        document.Add(new Field(fetchXmlField.Name, primaryKey.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));

                        // Adding webroles for the webpage to the index.
                        if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching))
                        {
                            if (entityMetadata.LogicalName == "adx_webpage")
                            {
                                ADXTrace.Instance.TraceInfo(TraceCategory.Monitoring, "CMS is enabled. Adding roles for adx_webpage index");

                                var ruleNames = CmsIndexHelper.GetWebPageWebRoles(this._contentMapProvider, primaryKey);
                                this.AddWebRolesToDocument(document, ruleNames);
                            }

                            if (entityMetadata.LogicalName == "adx_ideaforum")
                            {
                                ADXTrace.Instance.TraceInfo(TraceCategory.Monitoring, "CMS is enabled. Adding roles for adx_ideaforum index");

                                var ruleNames = CmsIndexHelper.GetIdeaForumWebRoles(this._contentMapProvider, primaryKey);
                                this.AddWebRolesToDocument(document, ruleNames);
                            }

                            if (entityMetadata.LogicalName == "adx_communityforum")
                            {
                                ADXTrace.Instance.TraceInfo(TraceCategory.Monitoring, "CMS is enabled. Adding roles for adx_communityforum index");

                                var ruleNames = CmsIndexHelper.GetForumsWebRoles(this._contentMapProvider, primaryKey);
                                this.AddWebRolesToDocument(document, ruleNames);
                            }
                        }
                        continue;
                    }

                    if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching))
                    {
                        if (fetchXmlField.Name == "adx_ideaforumid" && entityMetadata.LogicalName == "adx_idea")
                        {
                            ADXTrace.Instance.TraceInfo(TraceCategory.Monitoring, "CMS is enabled. Adding roles for adx_idea index");

                            var ruleNames = CmsIndexHelper.GetIdeaForumWebRoles(
                                this._contentMapProvider,
                                new Guid(fetchXmlField.Value));
                            this.AddWebRolesToDocument(document, ruleNames);
                        }

                        // Based off the Parent Web Page get the webroles for each given entity
                        if ((fetchXmlField.Name == "adx_parentpageid" && entityMetadata.LogicalName == "adx_blog") ||
                            (fetchXmlField.Name == "adx_blog_blogpost.adx_parentpageid" && entityMetadata.LogicalName == "adx_blogpost") ||
                            (fetchXmlField.Name == "adx_parentpageid" && entityMetadata.LogicalName == "adx_webfile"))
                        {
                            ADXTrace.Instance.TraceInfo(TraceCategory.Monitoring, string.Format("CMS is enabled. Adding roles for {0} index", fetchXmlField.Name));

                            var ruleNames = CmsIndexHelper.GetWebPageWebRoles(this._contentMapProvider, new Guid(fetchXmlField.Value));
                            this.AddWebRolesToDocument(document, ruleNames);
                        }

                        if ((fetchXmlField.Name == "adx_forumid" && entityMetadata.LogicalName == "adx_communityforumthread") ||
                            (fetchXmlField.Name == "adx_communityforumpost_communityforumthread.adx_forumid" && entityMetadata.LogicalName == "adx_communityforumpost"))
                        {
                            ADXTrace.Instance.TraceInfo(TraceCategory.Monitoring, string.Format("CMS is enabled. Adding roles for {0} index", fetchXmlField.Name));

                            var ruleNames = CmsIndexHelper.GetForumsWebRoles(
                                this._contentMapProvider,
                                new Guid(fetchXmlField.Value));
                            this.AddWebRolesToDocument(document, ruleNames);
                        }
                        if (entityMetadata.LogicalName == "annotation" && fetchXmlField.Name == "knowledgearticle.knowledgearticleid")
                        {
                            var id = new Guid(fetchXmlField.Value);
                            document.Add(new Field("annotation_knowledgearticleid", id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                        }
                    }


                    // Store the title of the result in a special field.
                    if (fetchXmlField.Name == _titleAttributeLogicalName && entityMetadata.LogicalName != "annotation")
                    {
                        document.Add(new Field(_index.TitleFieldName, fetchXmlField.Value, Field.Store.YES, Field.Index.ANALYZED));
                    }

                    // Store the language locale code in a separate field.
                    if (_localeConfig.IsLanguageCodeLogicalName(fetchXmlField.Name))
                    {
                        document.Add(
                            new Field(
                                _index.LanguageLocaleCodeFieldName,
                                fetchXmlField.Value.ToLowerInvariant(),
                                Field.Store.YES,
                                Field.Index.NOT_ANALYZED));
                        languageValueAdded = true;
                    }

                    // Store the language locale LCID in a separate field.
                    if (_localeConfig.IsLCIDLogicalName(fetchXmlField.Name) && int.TryParse(fetchXmlField.Value, out lcid))
                    {
                        document.Add(
                            new Field(_index.LanguageLocaleLCIDFieldName, fetchXmlField.Value, Field.Store.YES, Field.Index.NOT_ANALYZED));
                    }

                    // Skip metadata parsing for language fields
                    if (_localeConfig.CanSkipMetadata(fetchXmlField.Name))
                    {
                        continue;
                    }

                    FetchXmlLinkAttribute link;

                    if (_fetchXml.TryGetLinkAttribute(fetchXmlField, out link))
                    {
                        var linkEntityMetadata = _dataContext.GetEntityMetadata(link.EntityLogicalName, _metadataCache);

                        var linkAttributeMetadata = linkEntityMetadata.Attributes.FirstOrDefault(a => a.LogicalName == link.LogicalName);

                        if (linkAttributeMetadata == null)
                        {
                            throw new InvalidOperationException("Unable to retrieve attribute metadata for FetchXML result field {0} for entity {1}.".FormatWith(link.LogicalName, linkEntityMetadata.LogicalName));
                        }

                        var fieldName = fetchXmlResult.Any(f => f.Name == link.LogicalName)
                                                                                        ? "{0}.{1}".FormatWith(linkEntityMetadata.LogicalName, linkAttributeMetadata.LogicalName)
                                                                                        : link.LogicalName;

                        //Renaming product identifier field to  "associated.product"
                        if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching) &&
                            (this._fetchXml.LogicalName == "knowledgearticle" && fieldName == "record2id" ||
                             this._fetchXml.LogicalName == "annotation" && fieldName == "productid"))
                        {
                            fieldName = FixedFacetsConfiguration.ProductFieldFacetName;
                        }
                        if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching) &&
                            (this._fetchXml.LogicalName == "knowledgearticle" && (fieldName == "notetext" || fieldName == "filename")))
                        {
                            fieldName = "related_" + fieldName;
                        }

                        if (fieldName == "related_filename")
                        {
                            fetchXmlField.Value = Regex.Replace(fetchXmlField.Value, "[._,-]", " ");
                        }
                        if (fieldName == "related_notetext")
                        {
                            fetchXmlField.Value = fetchXmlField.Value.Substring(GetNotesFilterPrefix().Length);
                        }

                        AddDocumentFields(document, fieldName, fetchXmlField, linkAttributeMetadata, content);
                    }
                    else
                    {
                        AttributeMetadata attributeMetadata;

                        if (!attributes.TryGetValue(fetchXmlField.Name, out attributeMetadata))
                        {
                            throw new InvalidOperationException(
                                      ResourceManager.GetString("Attribute_Metadata_Fetchxml_Retrieve_Exception")
                                      .FormatWith(fetchXmlField.Name, entityMetadata.LogicalName));
                        }

                        if (fetchXmlField.Name == "filename")
                        {
                            fetchXmlField.Value = Regex.Replace(fetchXmlField.Value, "[._,-]", " ");
                        }
                        if (fetchXmlField.Name == "notetext")
                        {
                            fetchXmlField.Value = fetchXmlField.Value.Substring(GetNotesFilterPrefix().Length);
                        }

                        AddDocumentFields(document, fetchXmlField.Name, fetchXmlField, attributeMetadata, content);
                    }
                }

                if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching))
                {
                    // Add the default value for entities that are not Knowledge articles for the Product filtering field.
                    if (entityMetadata.LogicalName != "knowledgearticle")
                    {
                        document.Add(
                            new Field(
                                FixedFacetsConfiguration.ProductFieldFacetName,
                                this._index.ProductAccessNonKnowledgeArticleDefaultValue,
                                Field.Store.NO,
                                Field.Index.NOT_ANALYZED));
                        document.Add(
                            new Field(FixedFacetsConfiguration.ContentAccessLevel,
                                      "public",
                                      Field.Store.NO,
                                      Field.Index.NOT_ANALYZED));
                    }
                    else
                    {
                        // If there aren't any products associated to the article add the default value so then at query time
                        //    based on the site setting it will add these to the result or not.
                        var productsDocument = document.GetField(FixedFacetsConfiguration.ProductFieldFacetName);
                        if (productsDocument == null)
                        {
                            document.Add(
                                new Field(
                                    FixedFacetsConfiguration.ProductFieldFacetName,
                                    this._index.ProductAccessDefaultValue,
                                    Field.Store.NO,
                                    Field.Index.NOT_ANALYZED));
                        }
                    }
                }

                if (!languageValueAdded)
                {
                    document.Add(new Field(_index.LanguageLocaleCodeFieldName, _index.LanguageLocaleCodeDefaultValue, Field.Store.YES, Field.Index.NOT_ANALYZED));
                }

                // Add the field for the main, analyzed, search content.
                document.Add(new Field(_index.ContentFieldName, content.ToString(), _index.StoreContentField ? Field.Store.YES : Field.Store.NO, Field.Index.ANALYZED));

                if (_index.AddScopeField)
                {
                    var scopeField = document.GetField(_index.ScopeValueSourceFieldName);

                    var scopeValue = scopeField == null ? _index.ScopeDefaultValue : scopeField.StringValue;

                    document.Add(new Field(_index.ScopeFieldName, scopeValue, Field.Store.NO, Field.Index.NOT_ANALYZED));
                }

                if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching))
                {
                    this.AddDefaultWebRoleToAllDocumentsNotUnderCMS(document, entityMetadata.LogicalName);
                    this.AddUrlDefinedToDocument(document, entityMetadata.LogicalName, fetchXmlResult);
                }

                var documentAnalyzer = lcid > 0
                                                                                   ? _index.GetLanguageSpecificAnalyzer(lcid)
                                                                                   : _index.Analyzer;
                return(new CrmEntityIndexDocument(document, documentAnalyzer, primaryKey));
            }
            catch (Exception e)
            {
                ADXTrace.Instance.TraceError(TraceCategory.Application, string.Format("Error: Exception when trying to create the index document. {0}", e));
            }
            return(new CrmEntityIndexDocument(document, _index.Analyzer, primaryKey));
        }