Example #1
0
        /// <summary>
        /// Returns value of custom fields for this CmObject.
        /// </summary>
        /// <returns>Either null or a BsonDocument with the following structure
        ///  <br />
        /// { <br />
        ///     "customFields": { fieldName: fieldValue, fieldName2: fieldValue2, etc. } <br />
        ///     "customFieldGuids": { fieldName: "Guid-as-string", fieldName2: "Guid2-as-string", etc. } <br />
        /// } <br />
        /// -OR- <br />
        /// { <br />
        ///     "customFields": { fieldName: fieldValue, fieldName2: fieldValue2, etc. } <br />
        ///     "customFieldGuids": { fieldName: ["guid1", "guid2", "guid3"], fieldName2: "Guid2-as-string", etc. } <br />
        /// } <br />
        /// The format of the fieldName keys will be "customField_FOO_field_name_with_underscores",
        /// where FOO is one of "entry", "senses", or "examples". <br />
        /// Some fields have no need for a GUID (e.g., a custom number field), so not all fieldNames will appear in customFieldGuids.
        /// Only custom fields with actual data will be returned: empty lists and strings will be suppressed, and integer
        /// fields whose value is 0 will be suppressed. (They will get the default int value, 0, when read from Mongo, so this
        /// allows us to save space in the Mongo DB). If a custom field's value is suppressed, it will not appear in the output,
        /// and will not have a corresponding value in customFieldGuids.
        /// If ALL custom fields are suppressed because of having null, default or empty values, then this function will return
        /// null instead of returning a useless-but-not-actually-empty BsonDocument.
        /// </returns>
        /// <param name="cmObj">Cm object.</param>
        /// <param name="objectType">Either "entry", "senses", or "examples"</param>
        /// <param name="listConverters">Dictionary of ConvertLcmToMongoOptionList instances, keyed by list code</param>
        public BsonDocument GetCustomFieldsForThisCmObject(ICmObject cmObj, string objectType,
                                                           IDictionary <string, ConvertLcmToMongoOptionList> listConverters)
        {
            if (cmObj == null)
            {
                return(null);
            }

            List <int> customFieldIds = new List <int>(
                LcmMetaData.GetFields(cmObj.ClassID, false, (int)CellarPropertyTypeFilter.All)
                .Where(flid => cache.GetIsCustomField(flid)));

            var customFieldData  = new BsonDocument();
            var customFieldGuids = new BsonDocument();

            foreach (int flid in customFieldIds)
            {
                string label = LcmMetaData.GetFieldNameOrNull(flid);
                if (label == null)
                {
                    return(null);
                }
                string       lfCustomFieldName = ConvertUtilities.NormalizedFieldName(label, objectType);
                BsonDocument bsonForThisField  = GetCustomFieldData(cmObj.Hvo, flid, objectType, listConverters);

                if (bsonForThisField != null)
                {
                    customFieldData.Add(lfCustomFieldName, bsonForThisField["value"]);
                    BsonValue guid;
                    if (bsonForThisField.TryGetValue("guid", out guid))
                    {
                        if (guid is BsonArray)
                        {
                            customFieldGuids.Add(lfCustomFieldName, guid, ((BsonArray)guid).Count > 0);
                        }
                        else
                        {
                            customFieldGuids.Add(lfCustomFieldName, guid);
                        }
                    }
                }
            }

            BsonDocument result = new BsonDocument();

            result.Add("customFields", customFieldData);
            result.Add("customFieldGuids", customFieldGuids);
            return(result);
        }
        public void SetCustomFieldsForThisCmObject(ICmObject cmObj, string objectType, BsonDocument customFieldValues, BsonDocument customFieldGuids)
        {
            if (customFieldValues == null)
            {
                return;
            }

            IEnumerable <int> customFieldIds =
                lcmMetaData.GetFields(cmObj.ClassID, false, (int)CellarPropertyTypeFilter.All)
                .Where(flid => cache.GetIsCustomField(flid));

            var remainingFieldNames = new HashSet <string>(customFieldValues.Select(elem => elem.Name));

            foreach (int flid in customFieldIds)
            {
                string fieldName = lcmMetaData.GetFieldNameOrNull(flid);
                if (fieldName == null)
                {
                    return;
                }
                fieldName = ConvertUtilities.NormalizedFieldName(fieldName, objectType);
                BsonValue fieldValue       = customFieldValues.GetValue(fieldName, BsonNull.Value);
                BsonValue fieldGuidOrGuids = (customFieldGuids == null) ? BsonNull.Value : customFieldGuids.GetValue(fieldName, BsonNull.Value);
                // Persist Guid.Empty as null to save space
                if (fieldGuidOrGuids.BsonType == BsonType.String && fieldGuidOrGuids.AsString == "00000000-0000-0000-0000-000000000000")
                {
                    fieldGuidOrGuids = BsonNull.Value;
                }
                remainingFieldNames.Remove(fieldName);
                if (fieldValue != BsonNull.Value)
                {
                    SetCustomFieldData(cmObj.Hvo, flid, fieldValue, fieldGuidOrGuids);
                }
            }
            foreach (string fieldName in remainingFieldNames)
            {
                // TODO: These are NEW CUSTOM FIELDS! Will need to create them in LCM, then do:
                // BsonValue fieldValue = customFieldValues.GetValue(fieldName, BsonNull.Value);
                // BsonValue fieldGuidOrGuids = customFieldGuids.GetValue(fieldName, BsonNull.Value);
                // SetCustomFieldData(cmObj.Hvo, flid, fieldValue, fieldGuidOrGuids);
                // Above lines commented out until we can create new custom fields correctly. 2015-11 RM
                logger.Warning("Custom field {0} from LF skipped, because we're not yet creating new custom fields in LCM", fieldName);
            }
        }
Example #3
0
        public void WriteCustomFieldConfigForOneFieldSourceType(
            int classId,
            string fieldSourceType,              // Can be either "entry", "senses", or "examples"
            Dictionary <string, LfConfigFieldBase> lfCustomFieldConfig,
            Dictionary <string, string> lfCustomFieldTypes
            )
        {
            IEnumerable <int> customFieldIds =
                LcmMetaData.GetFields(classId, false, (int)CellarPropertyTypeFilter.All)
                .Where(flid => cache.GetIsCustomField(flid));

            foreach (int flid in customFieldIds)
            {
                string label = LcmMetaData.GetFieldNameOrNull(flid);
                if (label == null)
                {
                    continue;
                }
                string             lfCustomFieldName = ConvertUtilities.NormalizedFieldName(label, fieldSourceType);
                CellarPropertyType LcmFieldType      = (CellarPropertyType)LcmMetaData.GetFieldType(flid);
                lfCustomFieldTypes[lfCustomFieldName] = LcmFieldType.ToString();
                string lfCustomFieldType;
                if (CellarPropertyTypeToLfCustomFieldType.TryGetValue(LcmFieldType, out lfCustomFieldType))
                {
                    // Get custom field configuration info
                    LfConfigFieldBase fieldConfig = null;

                    if (lfCustomFieldType.EndsWith("ListRef"))
                    {
                        // List references, whether single or multi, need a list code
                        string listCode = GetParentListCode(flid);
                        fieldConfig = GetLfCustomFieldOptionListConfig(label, lfCustomFieldType, listCode);
                    }
                    else if (lfCustomFieldType == CellarPropertyTypeToLfCustomFieldType[CellarPropertyType.OwningAtomic])
                    {
                        // Multiparagraphs don't need writing systems
                        fieldConfig = GetLfCustomFieldMultiParagraphConfig(label, lfCustomFieldType);
                    }
                    else
                    {
                        // Single line or MultiText fields need writing systems
                        int fieldWs = LcmMetaData.GetFieldWs(flid);
                        // That's a "magic" ws, which we need to expand into a (list of) real writing system(s).
#if FW8_COMPAT
                        var wsesForThisField = new List <IWritingSystem>();
#else
                        var wsesForThisField = new List <CoreWritingSystemDefinition>();
#endif
                        // GetWritingSystemList() in FW 8.3 is buggy and doesn't properly handle the kwsAnal and kwsVern cases, so we handle them here instead.
                        switch (fieldWs)
                        {
                        case WritingSystemServices.kwsAnal:
                            wsesForThisField.Add(servLoc.LanguageProject.DefaultAnalysisWritingSystem);
                            break;

                        case WritingSystemServices.kwsVern:
                            wsesForThisField.Add(servLoc.LanguageProject.DefaultVernacularWritingSystem);
                            break;

                        default:
                            wsesForThisField = WritingSystemServices.GetWritingSystemList(cache, fieldWs, forceIncludeEnglish: false);
                            break;
                        }
#if FW8_COMPAT
                        IEnumerable <string> inputSystems = wsesForThisField.Select(LcmWs => LcmWs.Id);
#else
                        IEnumerable <string> inputSystems = wsesForThisField.Select(LcmWs => LcmWs.LanguageTag);
#endif
                        // GetWritingSystemList returns all analysis WSes even when asked for just one, so if this
                        // is a single-line custom field, trim the WSes down to just the first one
                        if (lfCustomFieldType.StartsWith("Single"))
                        {
                            inputSystems = inputSystems.Take(1);
                        }
                        fieldConfig = GetLfCustomFieldMultiTextConfig(label, lfCustomFieldType, inputSystems.ToList());
                    }

                    if (fieldConfig != null)
                    {
                        lfCustomFieldConfig[lfCustomFieldName] = fieldConfig;
                    }
                }
            }
        }