-
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathConvertLcmToMongoCustomField.cs
More file actions
527 lines (487 loc) · 23.1 KB
/
Copy pathConvertLcmToMongoCustomField.cs
File metadata and controls
527 lines (487 loc) · 23.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
// Copyright (c) 2016-2018 SIL International
// This software is licensed under the MIT license (http://opensource.org/licenses/MIT)
using System;
using System.Collections.Generic;
using System.Linq;
using Autofac;
using LfMerge.Core.FieldWorks;
using LfMerge.Core.LanguageForge.Config;
using LfMerge.Core.LanguageForge.Infrastructure;
using LfMerge.Core.LanguageForge.Model;
using LfMerge.Core.Logging;
using MongoDB.Bson;
using SIL.LCModel;
using SIL.LCModel.Application;
using SIL.LCModel.Core.Cellar;
using SIL.LCModel.Core.KernelInterfaces;
using SIL.LCModel.Core.WritingSystems;
using SIL.LCModel.DomainServices;
using SIL.LCModel.Infrastructure;
namespace LfMerge.Core.DataConverters
{
public class ConvertLcmToMongoCustomField
{
private LcmCache cache;
private FwServiceLocatorCache servLoc;
private IFwMetaDataCacheManaged LcmMetaData;
private ILogger logger;
private int _wsEn;
/// <summary>
/// Mapping of Lcm CellarProperty type enumeration to LF custom field type.
/// Refer to Lcm SIL.CoreImpl.CellarPropertyType.
/// </summary>
private static readonly Dictionary<CellarPropertyType, string> CellarPropertyTypeToLfCustomFieldType = new Dictionary<CellarPropertyType, string>
{
{CellarPropertyType.ReferenceCollection, "Multi_ListRef"},
{CellarPropertyType.String, "Single_Line"},
{CellarPropertyType.MultiString, "MultiText"},
{CellarPropertyType.MultiUnicode, "MultiText"},
{CellarPropertyType.OwningAtomic, "MultiParagraph"}, // Equivalent to MinObj
{CellarPropertyType.ReferenceAtomic, "Single_ListRef"},
// The following custom fields currently aren't displayed in LF
//{CellarPropertyType.Integer, "Number"},
//{CellarPropertyType.GenDate, "Date"},
};
private Dictionary<Guid, string> GuidToListCode;
private Dictionary<string, string> _fieldNameToFieldType;
public ConvertLcmToMongoCustomField(LcmCache cache, FwServiceLocatorCache serviceLocator, ILogger logger)
{
this.cache = cache;
this.servLoc = serviceLocator;
this.LcmMetaData = (IFwMetaDataCacheManaged)cache.MetaDataCacheAccessor;
this.logger = logger;
_wsEn = servLoc.WritingSystemFactory.GetWsFromStr("en");
GuidToListCode = new Dictionary<Guid, string>
{
{servLoc.LanguageProject.LexDbOA.DomainTypesOA.Guid, MagicStrings.LfOptionListCodeForAcademicDomainTypes},
{servLoc.LanguageProject.AnthroListOA.Guid, MagicStrings.LfOptionListCodeForAnthropologyCodes},
{servLoc.LanguageProject.PartsOfSpeechOA.Guid, MagicStrings.LfOptionListCodeForGrammaticalInfo},
{servLoc.LanguageProject.LocationsOA.Guid, MagicStrings.LfOptionListCodeForLocations},
{servLoc.LanguageProject.SemanticDomainListOA.Guid, MagicStrings.LfOptionListCodeForSemanticDomains},
{servLoc.LanguageProject.LexDbOA.SenseTypesOA.Guid, MagicStrings.LfOptionListCodeForSenseTypes},
{servLoc.LanguageProject.StatusOA.Guid, MagicStrings.LfOptionListCodeForStatus},
{servLoc.LanguageProject.LexDbOA.UsageTypesOA.Guid, MagicStrings.LfOptionListCodeForUsageTypes}
};
_fieldNameToFieldType = new Dictionary<string, string>();
}
public bool CreateCustomFieldsConfigViews(ILfProject project, Dictionary<string, LfConfigFieldBase> lfCustomFieldList, Dictionary<string, string> lfCustomFieldTypes)
{
return CreateCustomFieldsConfigViews(project, lfCustomFieldList, lfCustomFieldTypes, false);
}
public bool CreateCustomFieldsConfigViews(ILfProject project, Dictionary<string, LfConfigFieldBase> lfCustomFieldList, Dictionary<string, string> lfCustomFieldTypes, bool isTest)
{
var customFieldSpecs = new List<CustomFieldSpec>();
foreach (string lfCustomFieldName in lfCustomFieldList.Keys)
{
customFieldSpecs.Add(new CustomFieldSpec(lfCustomFieldName, _fieldNameToFieldType[lfCustomFieldName]));
}
var lfproxy = MainClass.Container.Resolve<ILanguageForgeProxy>();
string output = lfproxy.UpdateCustomFieldViews(project.ProjectCode, customFieldSpecs, isTest);
if (string.IsNullOrEmpty(output) || output == "false")
return false;
return true;
}
/// <summary>
/// Returns a dictionary of custom fields at the LexEntry, LexSense, and LexExampleSentence levels
/// From Lcm to LF. If the dictionary doesn't exist, create one.
/// </summary>
/// <returns>Dictionary of custom fields where the keys are the parent listCode</returns>
public Dictionary<string, ICmPossibilityList> GetCustomFieldParentLists()
{
// Generate the dictionary of custom fields
var lfCustomFieldLists = new Dictionary<string, ICmPossibilityList>();
// The three classes that are allowed to have custom fields in them are LexEntry, LexSense, and LexExampleSentence
List<int> customFieldIds = new List<int>(
LcmMetaData.GetFields(LexEntryTags.kClassId, false, (int)CellarPropertyTypeFilter.AllReference)
.Where(flid => cache.GetIsCustomField(flid) && LcmMetaData.GetFieldListRoot(flid) != Guid.Empty));
customFieldIds.AddRange(
LcmMetaData.GetFields(LexSenseTags.kClassId, false, (int)CellarPropertyTypeFilter.AllReference)
.Where(flid => cache.GetIsCustomField(flid) && LcmMetaData.GetFieldListRoot(flid) != Guid.Empty));
customFieldIds.AddRange(
LcmMetaData.GetFields(LexExampleSentenceTags.kClassId, false, (int)CellarPropertyTypeFilter.AllReference)
.Where(flid => cache.GetIsCustomField(flid) && LcmMetaData.GetFieldListRoot(flid) != Guid.Empty));
var listRepo = servLoc.GetInstance<ICmPossibilityListRepository>();
foreach (int flid in customFieldIds)
{
Guid parentListGuid = LcmMetaData.GetFieldListRoot(flid);
string listCode = GetParentListCode(flid);
lfCustomFieldLists[listCode] = listRepo.GetObject(parentListGuid);
}
return lfCustomFieldLists;
}
/// <summary>
/// Write the custom field config into the provided dictionary
/// </summary>
/// <param name="lfCustomFieldConfig">Dictionary to receive LF custom field configuration settings (keys are field names
/// as found in LF, e.g. customField_entry_MyCustomField)</param>
public void WriteCustomFieldConfig(
Dictionary<string, LfConfigFieldBase> lfCustomFieldConfig,
Dictionary<string, string> lfCustomFieldTypes)
{
WriteCustomFieldConfigForOneFieldSourceType(LexEntryTags.kClassId, "entry", lfCustomFieldConfig, lfCustomFieldTypes);
WriteCustomFieldConfigForOneFieldSourceType(LexSenseTags.kClassId, "senses", lfCustomFieldConfig, lfCustomFieldTypes);
WriteCustomFieldConfigForOneFieldSourceType(LexExampleSentenceTags.kClassId, "examples", lfCustomFieldConfig, lfCustomFieldTypes);
}
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);
_fieldNameToFieldType[lfCustomFieldName] = LcmFieldType.ToString(); // TODO: Comment this one OUT. Bad design.
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;
}
}
}
/// <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,
params string[] fieldNamesToSkip)
{
if (cmObj == null) return null;
List<int> customFieldIds = new List<int>(
LcmMetaData.GetFields(cmObj.ClassID, false, (int)CellarPropertyTypeFilter.All)
.Where(flid => cache.GetIsCustomField(flid))
.Where(flid => !fieldNamesToSkip.Contains(LcmMetaData.GetFieldName(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;
}
/// <summary>
/// Get the list code of the parent
/// </summary>
/// <returns>The list code as used in LF (e.g., "sense-type" or "grammatical-info").
/// For custom lists from Lcm, returns the user-given list name or abbreviation.</returns>
/// <param name="flid">Flid.</param>
private string GetParentListCode(int flid)
{
string result = string.Empty;
Guid parentListGuid = LcmMetaData.GetFieldListRoot(flid);
if (parentListGuid != Guid.Empty)
{
if (GuidToListCode.TryGetValue(parentListGuid, out result))
return result;
// If it wasn't in GuidToListCode, it's a custom field we haven't actually seen yet
ICmPossibilityList parentList;
if (servLoc.GetInstance<ICmPossibilityListRepository>().TryGetObject(parentListGuid, out parentList))
{
if (parentList.Name != null)
result = ConvertLcmToMongoTsStrings.TextFromTsString(parentList.Name.BestAnalysisVernacularAlternative, servLoc.WritingSystemFactory);
if (!String.IsNullOrEmpty(result) && result != MagicStrings.UnknownString)
{
GuidToListCode[parentListGuid] = result;
return result;
}
if (parentList.Abbreviation != null)
result = ConvertLcmToMongoTsStrings.TextFromTsString(parentList.Abbreviation.BestAnalysisVernacularAlternative, servLoc.WritingSystemFactory);
if (!String.IsNullOrEmpty(result) && result != MagicStrings.UnknownString)
{
GuidToListCode[parentListGuid] = result;
return result;
}
result = String.Format("Custom List {0}", parentListGuid);
GuidToListCode[parentListGuid] = result;
return result;
}
}
return result; // If we reach here, result is still an empty string
}
/// <summary>
/// Gets the data for one custom field, and any relevant GUIDs.
/// </summary>
/// <param name="hvo">Hvo of object we're getting the field for.</param>
/// <param name="flid">Flid for this field.</param>
/// <param name="fieldSourceType">Either "entry", "senses" or "examples". Could also be "allomorphs", eventually.</param>
/// <param name="bsonForThisField">Output of a BsonDocument with the following structure: <br />
/// { fieldName: { "value": BsonValue, "guid": "some-guid-as-a-string" } } <br />
/// -OR- <br />
/// { fieldName: { "value": BsonValue, "guid": ["guid1", "guid2", "guid3"] } } <br />
/// The format of the fieldName key will be "customField_FOO_field_name_with_underscores",
/// where FOO is one of "entry", "senses", or "examples". <br />
/// The type of the "guid" value (array or string) will determine whether there is a single GUID,
/// or a list of GUIDs that happens to contain only one entry.
/// If there is no "guid" key, that field has no need for a GUID. (E.g., a number).
/// </param>
/// <param name="listConverters">Dictionary of ConvertLcmToMongoOptionList instances, keyed by list code</param>
private BsonDocument GetCustomFieldData(int hvo, int flid, string fieldSourceType,
IDictionary<string, ConvertLcmToMongoOptionList> listConverters)
{
BsonValue fieldValue = null;
BsonValue fieldGuid = null; // Might be a single value, might be a list (as a BsonArray)
ISilDataAccessManaged data = (ISilDataAccessManaged)cache.DomainDataByFlid;
CellarPropertyType LcmFieldType = (CellarPropertyType)LcmMetaData.GetFieldType(flid);
var dataGuids = new List<Guid>();
// Valid field types in Lcm are GenDate, Integer, String, OwningAtomic, ReferenceAtomic, and ReferenceCollection, so that's all we implement.
switch (LcmFieldType)
{
case CellarPropertyType.GenDate:
GenDate genDate = data.get_GenDateProp(hvo, flid);
string genDateStr = genDate.ToLongString();
// LF wants single-string fields in the format { "ws": { "value": "contents" } }
fieldValue = String.IsNullOrEmpty(genDateStr) ? null :
LfMultiText.FromSingleStringMapping(
MagicStrings.LanguageCodeForGenDateFields, genDateStr).AsBsonDocument();
break;
// When parsing, will use GenDate.TryParse(str, out genDate)
case CellarPropertyType.Integer:
fieldValue = new BsonInt32(data.get_IntProp(hvo, flid));
if (fieldValue.AsInt32 == default(Int32))
fieldValue = null; // Suppress int fields with 0 in them, to save Mongo DB space
else
// LF wants single-string fields in the format { "ws": { "value": "contents" } }
fieldValue = LfMultiText.FromSingleStringMapping(
MagicStrings.LanguageCodeForIntFields, fieldValue.AsInt32.ToString()).AsBsonDocument();
break;
case CellarPropertyType.OwningAtomic:
case CellarPropertyType.ReferenceAtomic:
int ownedHvo = data.get_ObjectProp(hvo, flid);
fieldValue = GetCustomReferencedObject(ownedHvo, flid, listConverters, ref dataGuids);
if (fieldValue != null && LcmFieldType == CellarPropertyType.ReferenceAtomic)
{
// Single CmPossiblity reference - LF expects format like { "value": "key of possibility" }
fieldValue = new BsonDocument("value", fieldValue);
}
fieldGuid = new BsonString(dataGuids.FirstOrDefault().ToString());
break;
case CellarPropertyType.MultiUnicode:
ITsMultiString tss = data.get_MultiStringProp(hvo, flid);
if (tss != null && tss.StringCount > 0)
fieldValue = LfMultiText.FromMultiITsString(tss, servLoc.WritingSystemManager).AsBsonDocument();
break;
case CellarPropertyType.OwningCollection:
case CellarPropertyType.OwningSequence:
case CellarPropertyType.ReferenceCollection:
case CellarPropertyType.ReferenceSequence:
int[] listHvos = data.VecProp(hvo, flid);
var innerValues = new BsonArray(listHvos.Select(listHvo => GetCustomReferencedObject(listHvo, flid, listConverters, ref dataGuids)).Where(x => x != null));
if (innerValues.Count == 0)
fieldValue = null;
else
{
fieldValue = new BsonDocument("values", innerValues);
fieldGuid = new BsonArray(dataGuids.Select(guid => guid.ToString()));
}
break;
case CellarPropertyType.String:
ITsString iTsValue = data.get_StringProp(hvo, flid);
if (iTsValue == null || String.IsNullOrEmpty(iTsValue.Text))
fieldValue = null;
else
fieldValue = LfMultiText.FromSingleITsString(iTsValue, servLoc.WritingSystemManager).AsBsonDocument();
break;
default:
fieldValue = null;
if (logger != null)
logger.Warning("Lcm CellarPropertyType.{0} not recognized for LF custom field", LcmFieldType.ToString());
break;
}
if (fieldValue == null)
return null;
else
{
var result = new BsonDocument();
result.Add("value", fieldValue ?? BsonNull.Value); // BsonValues aren't allowed to have C# nulls; they have their own null representation
if (fieldGuid is BsonArray)
result.Add("guid", fieldGuid, ((BsonArray)fieldGuid).Count > 0);
else
result.Add("guid", fieldGuid, fieldGuid != null);
return result;
}
}
/// <summary>
/// Gets the lf custom field option list config settings.
/// </summary>
/// <returns>The lf custom field settings as LfConfigMultiOptionList or LfConfigOptionList.</returns>
/// <param name="label">Custom field label.</param>
/// <param name="lfCustomFieldType">lf custom field type</param>
/// <param name="listCode">Parent list code.</param>
private LfConfigFieldBase GetLfCustomFieldOptionListConfig(string label, string lfCustomFieldType, string listCode)
{
if (lfCustomFieldType == CellarPropertyTypeToLfCustomFieldType[CellarPropertyType.ReferenceCollection])
{
return new LfConfigMultiOptionList {
Label = label,
ListCode = listCode,
};
}
else
{
return new LfConfigOptionList {
Label = label,
ListCode = listCode,
};
}
}
private LfConfigMultiText GetLfCustomFieldMultiTextConfig(string label, string lfCustomFieldType, List<string> inputSystems)
{
if (lfCustomFieldType == null)
return null;
return new LfConfigMultiText {
Label = label,
DisplayMultiline = !lfCustomFieldType.StartsWith("Single"),
Width = 20,
InputSystems = inputSystems,
};
}
private LfConfigMultiParagraph GetLfCustomFieldMultiParagraphConfig(string label, string lfCustomFieldType)
{
if (lfCustomFieldType == null)
return null;
return new LfConfigMultiParagraph {
Label = label,
};
}
/// <summary>
/// Get a BsonValue and GUID for the object referenced by a Reference or Owning field.
/// The GUID will be returned by adding it to a list passed in by reference, so that
/// ReferenceCollection, OwningSequence, and similar fields will be easy to process.
/// Note that we guarantee that a GUID will always be added to the list, even if this function
/// returns null for the object's data. That way Select(hvo => GetCustomReferencedObject(hvo, flid, ref myGuidList))
/// will always return the same number of items as the number of GUIDs in myGuidList.
/// </summary>
/// <returns>The custom referenced object's data converted to a BsonValue.</returns>
/// <param name="hvo">Hvo of referenced object.</param>
/// <param name="flid">Flid of referring field (required to get correct writing system for an StText).</param>
/// <param name="listConverters">Dictionary of ConvertLcmToMongoOptionList instances, keyed by list code</param>
/// <param name="referencedObjectGuids">List to which referenced object's GUID will be added.</param>
private BsonValue GetCustomReferencedObject(int hvo, int flid,
IDictionary<string, ConvertLcmToMongoOptionList> listConverters,
ref List<Guid> referencedObjectGuids)
{
ISilDataAccessManaged data = (ISilDataAccessManaged)cache.DomainDataByFlid;
if (hvo == 0 || !data.get_IsValidObject(hvo))
{
referencedObjectGuids.Add(Guid.Empty);
return null;
}
ICmObject referencedObject = cache.GetAtomicPropObject(hvo);
if (referencedObject == null)
{
referencedObjectGuids.Add(Guid.Empty);
return null;
}
referencedObjectGuids.Add(referencedObject.Guid);
if (referencedObject is IStText)
return ConvertUtilities.GetCustomStTextValues((IStText)referencedObject, flid,
servLoc.WritingSystemManager, LcmMetaData, cache.DefaultUserWs);
else if (referencedObject is ICmPossibility)
{
//return GetCustomListValues((ICmPossibility)referencedObject, flid);
string listCode = GetParentListCode(flid);
return new BsonString(listConverters[listCode].LfItemKeyString((ICmPossibility)referencedObject, _wsEn));
}
else
return null;
}
}
}