internal static ElementStrategy AddKeyedElementType(MergeStrategies mergeStrategies, string name, string attribute, bool orderOfTheseIsRelevant) { var strategy = new ElementStrategy(orderOfTheseIsRelevant) { MergePartnerFinder = new FindByKeyAttribute(attribute) }; mergeStrategies.SetStrategy(name, strategy); return strategy; }
internal static void AddElementStrategies(MergeStrategies mergeStrategies) { // Document root. mergeStrategies.SetStrategy("LayoutInventory", ElementStrategy.CreateSingletonElement()); #region 'layoutType' and children. mergeStrategies.SetStrategy("layoutType", ElementStrategy.CreateSingletonElement()); var elStrat = new ElementStrategy(false) { MergePartnerFinder = new FindByMultipleKeyAttributes(new List<string> { "class", "layout" }), NumberOfChildren = NumberOfChildrenAllowed.Zero, IsAtomic = true, ContextDescriptorGenerator = new FieldWorkCustomLayoutContextGenerator() }; mergeStrategies.SetStrategy("configure", elStrat); #endregion 'layoutType' and children. #region 'layout' and children. elStrat = new ElementStrategy(false) { MergePartnerFinder = new FindByMultipleKeyAttributes(new List<string> { "class", "type", "name" }), ContextDescriptorGenerator = new FieldWorkCustomLayoutContextGenerator() }; mergeStrategies.SetStrategy("layout", elStrat); elStrat = new ElementStrategy(true) { MergePartnerFinder = new FindByKeyAttributeInList("ref"), IsAtomic = true }; mergeStrategies.SetStrategy("part", elStrat); elStrat = new ElementStrategy(true) { //MergePartnerFinder = new FindByMultipleKeyAttributes(new List<string> { "class", "fieldType", "restrictions" }), MergePartnerFinder = new FindByKeyAttributeInList("combinedkey"), IsAtomic = true }; mergeStrategies.SetStrategy("generate", elStrat); elStrat = new ElementStrategy(true) { MergePartnerFinder = new FindByKeyAttributeInList("name"), IsAtomic = true, NumberOfChildren = NumberOfChildrenAllowed.Zero }; mergeStrategies.SetStrategy("sublayout", elStrat); #endregion 'layout' and children. }
/// <summary> /// Add all of the Lift range related ElementStrategy instacnes suitable for use in the lift file, and the lift-ranges file. /// /// This will likely over-populate mergeStrategies with strategies for the lift file, but no matter. /// </summary> /// <remarks> /// NB: There are more element strategies needed to support ranges, but they are expected to be defined elsewhere, as they are common to other non-range elements. /// Examples: "description" and "form" elements. /// </remarks> internal static void AddLiftBasicElementStrategies(MergeStrategies mergeStrategies) { // ******************************* <form> ************************************************** // <form // lang='lang' (required) AddKeyedElementType(mergeStrategies, "form", "lang", false); // <text> (Required, sig of <text>) // <annotation> [Optional, Multiple, sig=annotation] // </form> // ******************************* </form> ************************************************** // ******************************* <text> ************************************************** // Mixes text data and <span> elements // 'lang' attr from parent <form> element is the defacto same thing for the <text> element, but has no attrs itself. // <text> var textStrategy = AddSingletonElementType(mergeStrategies, "text"); textStrategy.IsAtomic = true; // don't attempt merge within text elements if they have non-text-node children, e.g., <span> // but we can do text-level merging if there are no spans; this allows text editing conflicts to be reported // and multiple text nodes which amount to the same inner text to be ignored. textStrategy.AllowAtomicTextMerge = true; // </text> // ******************************* </text> ************************************************** // ******************************* <span> ************************************************** // <span // lang='lang' (optional, so how can it really be used as a key to find a match?) NB: UML chart has it as 'string', not 'lang', but 'lang' is better for us var elementStrategy = ElementStrategy.CreateForKeyedElementInList("lang"); // href='URL' (optional, ignore?) elementStrategy.AttributesToIgnoreForMerging.Add("href"); // class='string'> (optional) // <span> (optional, multiple) // </span> mergeStrategies.SetStrategy("span", elementStrategy); // ******************************* </span> ************************************************** // ******************************* <multitext> ************************************************** // Formally 'inherits' from <text>, so has all it has (parent 'lang' attr governs, and other <text> rules on <span>, etc.). // Gotchas: // 1. There are no occurrences of a span being used to store content except as part of a multitext. // 2. text [Optional] If there is only one form the form element itself is optional and a multitext // may consist of a single text node containing the contents of the text. // This means that if there is no form there is no span capability. // <multitext No attrs // <form> [Optional, Multiple, sig=form] // </multitext> // Note: If it is 'abstract', then no element strategy is needed. // ******************************* </multitext> ************************************************** // ******************************* <URLRef> ************************************************** // <URLRef> element never occurs in the wild, as it always gets a name change. // <URLRef // href="URL" [Required, sig=URL] // <label> [Optional, sig=multitext] AddSingletonElementType(mergeStrategies, "label"); // </URLRef> // ******************************* </URLRef> ************************************************** // ******************************* <annotation> ************************************************** // <annotation // name [Required, key] // value [Required, key] elementStrategy = new ElementStrategy(false) { // Need both keys to find the match. MergePartnerFinder = new FindByMultipleKeyAttributes(new List<string> { "name", "value" }) }; mergeStrategies.SetStrategy("annotation", elementStrategy); // who [Optional, key] // when [Optional, key] // <form> [Optional, Multiple, sig=form, inherited from <multitext>] // </annotation> // ******************************* </annotation> ************************************************** // Shared with <header> in lift file, <range-element> and <range> in lift and lift-ranges files. elementStrategy = AddSingletonElementType(mergeStrategies, "description"); elementStrategy.OrderIsRelevant = false; }
internal static ElementStrategy AddSingletonElementType(MergeStrategies mergeStrategies, string name) { var strategy = new ElementStrategy(false) { MergePartnerFinder = new FindFirstElementWithSameName() }; mergeStrategies.SetStrategy(name, strategy); return strategy; }
private static void AddVariantStrategy(MergeStrategies mergeStrategies) { var strategy = new ElementStrategy(false) { MergePartnerFinder = new OptionalKeyAttrFinder("ref", new FormMatchingFinder()) }; strategy.AttributesToIgnoreForMerging.Add("dateModified"); mergeStrategies.SetStrategy("variant", strategy); }
private static void AddTranslationStrategy(MergeStrategies mergeStrategies) { var strategy = new ElementStrategy(false) { MergePartnerFinder = new OptionalKeyAttrFinder("type", new FormMatchingFinder()) }; mergeStrategies.SetStrategy("translation", strategy); }
/* Called <pronunciation> in lift file. private static void AddPhoneticStrategy(MergeStrategies mergeStrategies) { var strategy = new ElementStrategy(false) { MergePartnerFinder = new FormMatchingFinder() }; strategy.AttributesToIgnoreForMerging.Add("dateModified"); mergeStrategies.SetStrategy("phonetic", strategy); }*/ private static void AddPronunciationStrategy(MergeStrategies mergeStrategies) { var strategy = new ElementStrategy(false) { MergePartnerFinder = new FormMatchingFinder() }; strategy.AttributesToIgnoreForMerging.Add("dateModified"); mergeStrategies.SetStrategy("pronunciation", strategy); }
internal static void AddLiftElementStrategies(MergeStrategies mergeStrategies) { LiftBasicElementStrategiesMethod.AddLiftBasicElementStrategies(mergeStrategies); LiftRangesElementStrategiesMethod.AddLiftRangeElementStrategies(mergeStrategies); #region Header Elements //enhance: don't currently have a way of limiting etymology/form to a single instance but not multitext/form // ******************************* <lift> ************************************************** // Added to complete the whole file, but it gets no ElementStrategy. // <lift // version [Required, (string?)] // producer [Optional, string] // <header> [Optional, header] // <entry> [Optional, Multiple, Entry] // </lift> // ******************************* <lift> ************************************************** // ******************************* <header> ************************************************** // <header var elementStrategy = AddSingletonElementType(mergeStrategies, "header"); elementStrategy.ContextDescriptorGenerator = new LiftHeaderContextGenerator(); // <description> [Optional, multitext] NAME OVERRIDE (Declared in [LiftBasicElementStrategiesMethod], as it is shared here and in the lift-ranges file.) // <ranges> [Optional, ranges] elementStrategy = AddSingletonElementType(mergeStrategies, "ranges"); elementStrategy.OrderIsRelevant = false; // <fields> [Optional, field-defns] NAME OVERRIDE elementStrategy = AddSingletonElementType(mergeStrategies, "fields"); elementStrategy.OrderIsRelevant = false; // </header> // ******************************* </header> ************************************************** // ******************************* <ranges> ************************************************** // <ranges // <range> [Optional, Multiple, range-ref] NAME OVERRIDE // NB: Done in LiftRangesElementStrategiesMethod // </ranges> // ******************************* </ranges> ************************************************** // ******************************* <field-defns> ************************************************** // <field-defns // <field> [Optional, Multiple, field-defn] NAME OVERRIDE // </field-defns> // ******************************* </field-defns> ************************************************** // ******************************* <field-defn> ************************************************** // <field-defn> element never occurs in the wild (0.13), as it always gets a name change to <field>. // <field-defn (aka <field> in 0.13) // tag [Required, key] // !!!!!!!!! HACK ALERT !!!!!!!!! LiftBasicElementStrategiesMethod.AddKeyedElementType(mergeStrategies, "headerfield", "tag", false); // !!!!!!!!! END HACK ALERT !!!!!!!!! // <form> [optional, multiple] // </field-defn> // ******************************* </field-defn> ************************************************** #endregion #region Header Elements #region Entry Elements // ******************************* <extensible> ************************************************** // Notes: This is only be a bundle of attrs and content others can use, rather than an actual element in the file. // <extensible // dateCreated [Optional, datetime] // attr in UML // dateModified [Optional, datetime] // attr in UML // <field> [Optional, Multiple, field] // <trait> [Optional, Multiple, trait] // NB: sig changed in text to 'flag', but 'trait' in UML. // <annotation> [Optional, Multiple, annotation] // </extensible> // It is 'abstract', so no element strategy is needed. // ******************************* </extensible> ************************************************** // ******************************* <field> ************************************************** // Technically part of Base, but I don't know why, as the <field> elements appear in entries (or maybe senses). // Formal inheritance from <multitext>, and partial from <extensible> (all but <field>). // Observation: <field> inherits everything, except its 'type' attribute. // <field // type [Required, sig=key] // !!!!!!!!! HACK ALERT !!!!!!!!! elementStrategy = LiftBasicElementStrategiesMethod.AddKeyedElementType(mergeStrategies, "mainfield", "type", false); // !!!!!!!!! END HACK ALERT !!!!!!!!! // dateCreated [Optional, sig=datetime, inherited from <extensible>] // dateModified [Optional, sig=datetime, inherited from <extensible>] elementStrategy.AttributesToIgnoreForMerging.Add("dateModified"); // <trait> [Optional, Multiple, trait, inherited from <extensible>] // <annotation> [Optional, Multiple, sig=annotation, inherited from <extensible>] // <form> [Optional, Multiple, sig=form, inherited from <multitext>] // </field> // ******************************* </field> ************************************************** // ******************************* <trait> ************************************************** // Notes: A trait is simply a reference to a single range-element // in a range. It can be used to give the dialect for a variant or the status of an entry. // The semantics of a trait in a particular context is given by the parent object and also by the range // and range-element being referred to. Where no range is linked the name is informal or resolved by name. // <trait // name [Required, sig=key] // value [Required, sig=key] elementStrategy = new ElementStrategy(false) { // Need both keys to find the match. MergePartnerFinder = new FindByMultipleKeyAttributes(new List<string> { "name", "value" }) }; mergeStrategies.SetStrategy("trait", elementStrategy); // id [Optional, sig=key] // Note: Gives the particular trait an identifier such that it can be referenced by a sibling element. // The id key only needs to be unique within the parent element, although globale keys may be used. // There is no requirement that the key keeps its value across different versions of the file. // <annotation /> [Optional, Multiple, sig=annotation] // </trait> // ******************************* </trait> ************************************************** // ******************************* <note> ************************************************** // <note // type [Optional, sig=key] There is only one note with a given type in any parent element. // Thus translations of the note are held as different forms of the one note. elementStrategy = new ElementStrategy(false) { MergePartnerFinder = new OptionalKeyAttrFinder("type", new FormMatchingFinder()) }; // dateCreated [Optional, sig=datetime, inherited from <extensible>] // dateModified [Optional, sig=datetime, inherited from <extensible>] elementStrategy.AttributesToIgnoreForMerging.Add("dateModified"); // <field> [Optional, Multiple, sig=field, inherited from <extensible>] // <trait> [Optional, Multiple, sig=trait, inherited from <extensible>] // <annotation> [Optional, Multiple, sig=annotation, inherited from <extensible>] // <form> [Optional, Multiple, sig=form, inherited from <multitext>] mergeStrategies.SetStrategy("note", elementStrategy); // </note> // ******************************* </note> ************************************************** // ******************************* <relation> ************************************************** // <relation // type [Required, sig=key] // ref [Required, sig=refid] elementStrategy = new ElementStrategy(false) { // Need both keys to find this puppy's match. MergePartnerFinder = new FindByMultipleKeyAttributes(new List<string> { "type", "ref" }) }; mergeStrategies.SetStrategy("relation", elementStrategy); // order [Optional, sig=int] // dateCreated [Optional, sig=datetime, inherited from <extensible>] // dateModified [Optional, sig=datetime, inherited from <extensible>] elementStrategy.AttributesToIgnoreForMerging.Add("dateModified"); // <field> [Optional, Multiple, sig=field, inherited from <extensible>] // <trait> [Optional, Multiple, sig=trait, inherited from <extensible>] // <annotation> [Optional, Multiple, sig=annotation, inherited from <extensible>] // <usage> [Optional, sig=multitext] AddSingletonElementType(mergeStrategies, "usage"); // </relation> // ******************************* </relation> ************************************************** #region Entry // ******************************* <entry> ************************************************** // <entry // id [Optional, refid] This gives a unique identifier to this Entry. Notice that this is unique across all Entrys and **all Senses**. elementStrategy = LiftBasicElementStrategiesMethod.AddKeyedElementType(mergeStrategies, "entry", "id", false); elementStrategy.ContextDescriptorGenerator = new LexEntryContextGenerator(); // order [Optional, int] // guid [Optional, string] // dateDeleted [Optional, datetime] elementStrategy.AttributesToIgnoreForMerging.Add("dateDeleted"); // One might think it is immutable, but it might not be true. // dateCreated [Optional, sig=datetime, inherited from <extensible>] // dateModified [Optional, sig=datetime, inherited from <extensible>] elementStrategy.AttributesToIgnoreForMerging.Add("dateModified"); // <field> [Optional, Multiple, sig=field, inherited from <extensible>] // <trait> [Optional, Multiple, sig=trait, inherited from <extensible>] // <annotation> [Optional, Multiple, sig=annotation, inherited from <extensible>] // <lexical-unit> [Optional, multitext] AddSingletonElementType(mergeStrategies, "lexical-unit"); // <citation> [Optional, multitext] AddSingletonElementType(mergeStrategies, "citation"); // <pronunciation> [Optional, Multiple, phonetic] NAME OVERRIDE AddPronunciationStrategy(mergeStrategies); // <variant> [Optional, Multiple, variant] dealt with below // <sense> [Optional, Multiple, Sense] // <note> [Optional, Multiple, note] // <relation> [Optional, Multiple, relation] // <etymology> [Optional, Multiple, etymology] // </entry> // ******************************* </entry> ************************************************** // ******************************* <variant> ************************************************** // <variant // ref [Optional, refid] NOTE: Doc: refentry, UML: refid, so go with refid, since there is nothing called refentry. Gives the variation as a reference to another entry or sense rather than specifying the form // dateCreated [Optional, sig=datetime, inherited from <extensible>] // dateModified [Optional, sig=datetime, inherited from <extensible>] // <field> [Optional, Multiple, sig=field, inherited from <extensible>] // <trait> [Optional, Multiple, sig=trait, inherited from <extensible>] // <annotation> [Optional, Multiple, sig=annotation, inherited from <extensible>] // <form> [Optional, Multiple, sig=form, inherited from <multitext>] // <pronunciation> [Optional, Multiple, sig=phonetic] // <relation> [Optional, Multiple, sig=relation] // </variant> AddVariantStrategy(mergeStrategies); // ******************************* </variant> ************************************************** // ******************************* <phonetic> ************************************************** // NB: Element name changed to <pronunciation> // <phonetic // dateCreated [Optional, sig=datetime, inherited from <extensible>] // dateModified [Optional, sig=datetime, inherited from <extensible>] ignored in phonetic strategy // <field> [Optional, Multiple, sig=field, inherited from <extensible>] // <trait> [Optional, Multiple, sig=trait, inherited from <extensible>] // <annotation> [Optional, Multiple, sig=annotation, inherited from <extensible>] // <form> [Optional, Multiple, sig=form, inherited from <multitext>] // <media> [Optional, Multiple, sig=URLRef] NAME OVERRIDE // Not ever in lift file, as <pronunciation> wraps it. AddPhoneticStrategy(mergeStrategies); LiftBasicElementStrategiesMethod.AddKeyedElementType(mergeStrategies, "media", "href", false); // </phonetic> // ******************************* </phonetic> ************************************************** // ******************************* <etymology> ************************************************** // <etymology // type [Required, sig=key] // source [Required, sig=key] // UML has 'key', doc has 'string'. Go with key elementStrategy = new ElementStrategy(false) { // SteveMc says to use them both. // Need both keys to find the match. MergePartnerFinder = new FindByMultipleKeyAttributes(new List<string> { "type", "source" }) }; mergeStrategies.SetStrategy("etymology", elementStrategy); // dateCreated [Optional, sig=datetime, inherited from <extensible>] // dateModified [Optional, sig=datetime, inherited from <extensible>] elementStrategy.AttributesToIgnoreForMerging.Add("dateModified"); // <field> [Optional, Multiple, sig=field, inherited from <extensible>] // <trait> [Optional, Multiple, sig=trait, inherited from <extensible>] // <annotation> [Optional, Multiple, sig=annotation, inherited from <extensible>] // <gloss> [Optional, Multiple, sig=form] // <form> [Required, sig=form] // UML has Optional // </etymology> // ******************************* </etymology> ************************************************** #endregion Entry #region Sense // ******************************* <sense> ************************************************** // <sense // id [Optional, refid] The id is unique across all Senses in the lexicon and all Entries as well. elementStrategy = LiftBasicElementStrategiesMethod.AddKeyedElementType(mergeStrategies, "sense", "id", true);// main sense and nested senses, according to doc // order [Optional int] // dateCreated [Optional, sig=datetime, inherited from <extensible>] // dateModified [Optional, sig=datetime, inherited from <extensible>] elementStrategy.AttributesToIgnoreForMerging.Add("dateModified"); // <field> [Optional, Multiple, sig=field, inherited from <extensible>] // <trait> [Optional, Multiple, sig=trait, inherited from <extensible>] // <annotation> [Optional, Multiple, sig=annotation, inherited from <extensible>] // <grammatical-info> [Optional, grammi] grammi? Better go with grammatical-info. (Added below) // <gloss> [Optional, Multiple, form] LiftBasicElementStrategiesMethod.AddKeyedElementType(mergeStrategies, "gloss", "lang", false); // <definition> [Optional, multitext] AddSingletonElementType(mergeStrategies, "definition"); // <relation> [Optional, Multiple, relation] (Added below) // <note> [Optional, Multiple, note] (Added below) // <example> [Optional, Multiple, example] (Must use default element strategy, or some other hand-made one.) // <reversal> [Optional, Multiple, reversal] (Added below) // <illustration> [Optional, Multiple, URLref] NAME OVERRIDE LiftBasicElementStrategiesMethod.AddKeyedElementType(mergeStrategies, "illustration", "href", false); // <subsense> [Optional, Multiple, sense] NAME OVERRIDE LiftBasicElementStrategiesMethod.AddKeyedElementType(mergeStrategies, "subsense", "id", true); // nested sense in a <sense>, according to rng // </sense> // ******************************* </sense> ************************************************** // ******************************* <reversal> ************************************************** // <reversal // type [Optional, sig=key] AddReversalStrategy(mergeStrategies); // <form> [Optional, Multiple, sig=form, inherited from <multitext>] // <main> [Optional, sig=reversal] NAME OVERRIDE AddSingletonElementType(mergeStrategies, "main"); // <grammatical-info> [Optional, sig=grammatical-info] (Added elsewhere) // </reversal> // ******************************* </reversal> ************************************************** // ******************************* <grammatical-info> ************************************************** // <grammatical-info // value [Required, sig=key] The part of speech tag into the grammatical-info range. // <trait> {Optional, Multiple, sig=trait] Allows grammatical information to have attributes. // </grammatical-info> // Sense and reversal have this as Optional, so singleton will do, while keyed is more future-safe. // It may bad to use a key, since if a user changes the 'value', then we'd get two of them. AddSingletonElementType(mergeStrategies, "grammatical-info"); // ******************************* </grammatical-info> ************************************************** // ******************************* <example> ************************************************** // <example AddExampleSentenceStrategy(mergeStrategies); // 'dateModified' is ignored in AddExampleSentenceStrategy // source [Optional, key] // Not suitable for keyed el strat. // dateCreated [Optional, sig=datetime, inherited from <extensible>] // dateModified [Optional, sig=datetime, inherited from <extensible>] // <field> [Optional, Multiple, sig=field, inherited from <extensible>] // <trait> [Optional, Multiple, sig=trait, inherited from <extensible>] // <annotation> [Optional, Multiple, sig=annotation, inherited from <extensible>] // <form> [Optional, Multiple, sig=form, inherited from <multitext>] // <translation> [Optional, Multiple, sig=translation] // </example> // ******************************* </example> ************************************************** // ******************************* <translation> ************************************************** // A translation is simply a multitext with an optional translation type attribute. // <translation // type [Optional, key] AddTranslationStrategy(mergeStrategies); // <form> [Optional, Multiple, sig=form, inherited from <multitext>] // </translation> // ******************************* </translation> ************************************************** #endregion Sense #endregion End Entry Elements }
private static void MakeClassStrategy(MergeStrategies strategiesForMerger, FdoClassInfo classInfo, FieldWorkObjectContextGenerator defaultDescriptor) { Guard.AgainstNull(defaultDescriptor, "defaultDescriptor"); // These values can be overridden or added to in the big switch, below. var classStrat = new ElementStrategy(false) { ContextDescriptorGenerator = defaultDescriptor, MergePartnerFinder = GuidKeyFinder, IsAtomic = false }; strategiesForMerger.SetStrategy(classInfo.ClassName, classStrat); // Try to keep these in alphbetical order, and where there are 'blocks', then try to keep the blocks in order. // That will make them easier to find. switch (classInfo.ClassName) { case "CmPossibilityList": classStrat.ContextDescriptorGenerator = new PossibilityListContextGenerator(); break; case "FsClosedFeature": classStrat.ContextDescriptorGenerator = new MultiLingualStringsContextGenerator("Phonological Features", "Name", "Abbreviation"); break; case "FsFeatStruc": classStrat.IsAtomic = true; break; case "LangProject": classStrat.ContextDescriptorGenerator = new LanguageProjectContextGenerator(); break; case "LexEntry": classStrat.ContextDescriptorGenerator = new LexEntryContextGenerator(); break; case "PhEnvironment": classStrat.ContextDescriptorGenerator = new EnvironmentContextGenerator(); break; case "PhNCSegments": classStrat.ContextDescriptorGenerator = new MultiLingualStringsContextGenerator("Natural Class", "Name", "Abbreviation"); break; case "ReversalIndexEntry": classStrat.ContextDescriptorGenerator = new ReversalEntryContextGenerator(); break; case "RnGenericRec": classStrat.ContextDescriptorGenerator = new RnGenericRecContextGenerator(); break; case "ScrBook": classStrat.ContextDescriptorGenerator = new ScrBookContextGenerator(); break; case "ScrDraft": // ScrDraft instances can only be added or removed, but not changed, according to John Wickberg (18 Jan 2012). classStrat.IsImmutable = true; break; case "ScrSection": classStrat.ContextDescriptorGenerator = new ScrSectionContextGenerator(); break; case "ScrTxtPara": // Fall through. case "StTxtPara": // This will never be used, since StTxtParas & ScrTxtParas are actually in an 'ownseq' element. classStrat.Premerger = new StTxtParaPremerger(); // Didn't work, since StTxtParas & ScrTxtParas are actually in an 'ownseq' element. // classStrat.IsAtomic = true; break; case "Text": classStrat.ContextDescriptorGenerator = new TextContextGenerator(); break; case "WfiWordform": classStrat.ContextDescriptorGenerator = new WfiWordformContextGenerator(); break; // These should be all the subclasses of CmPossiblity. It's unfortuate to have to list them here; // OTOH, if we ever want special handling for any of them, we can easily add a special generator. // Note that these will not usually be found as strategies, since they are owned in owning sequences // and ownseq has its own item. However, they can be found by the default object context generator code, // which has a special case for ownseq. case "ChkTerm": case "CmAnthroItem": case "CmAnnotationDefn": case "CmCustomItem": case "CmLocation": case "CmPerson": case "CmPossibility": case "CmSemanticDomain": case "LexEntryType": case "LexRefType": case "MoMorphType": case "PartOfSpeech": case "PhPhonRuleFeat": classStrat.ContextDescriptorGenerator = new PossibilityContextGenerator(); break; case "ConstChartRow": case "ConstChartWordGroup": case "DsConstChart": classStrat.ContextDescriptorGenerator = new DiscourseChartContextGenerator(); break; } ((FieldWorkObjectContextGenerator)classStrat.ContextDescriptorGenerator).MergeStrategies = strategiesForMerger; }
private static void AddPropertyStrategiesForClass(MergeStrategies strategiesForMerger, FdoClassInfo classInfo) { foreach (var propertyInfo in classInfo.AllProperties) { var isCustom = propertyInfo.IsCustomProperty; var propStrategy = isCustom ? CreateStrategyForKeyedElement(SharedConstants.Name, false) : CreateSingletonElementStrategy(); switch (propertyInfo.DataType) { // Block of object properties case DataType.OwningAtomic: propStrategy.NumberOfChildren = NumberOfChildrenAllowed.ZeroOrOne; break; //case DataType.OwningCollection: // Nothing special done // break; case DataType.OwningSequence: if ((classInfo.ClassName == "CmPossibilityList" && propertyInfo.PropertyName == "Possibilities") || (propertyInfo.PropertyName == "SubPossibilities" && classInfo.IsOrInheritsFrom("CmPossibility"))) { // Order may or may not be significant in possibility lists and sublists, depending on whether the list is sorted. propStrategy.ChildOrderPolicy = new PossibilityListOrderPolicy(); } else { // Normally order is significant in owning sequences; no need to ask each child. propStrategy.ChildOrderPolicy = new SignificantOrderPolicy(); } break; case DataType.ReferenceAtomic: if (classInfo.ClassName == "LexSense" && propertyInfo.PropertyName == "MorphoSyntaxAnalysis") { propStrategy.ContextDescriptorGenerator = new PosContextGenerator(); } propStrategy.NumberOfChildren = NumberOfChildrenAllowed.ZeroOrOne; break; //case DataType.ReferenceCollection: // Nothing special done // break; case DataType.ReferenceSequence: // Trying to merge the Analyses of a segment is problematic. Best to go all-or-nothing, and ensure // we get a conflict report if it fails. if (classInfo.ClassName == "Segment" && propertyInfo.PropertyName == "Analyses") propStrategy.IsAtomic = true; break; // Block of multi-somethings // In model, but nothing special done at the property element level //case DataType.MultiString: // break; //case DataType.MultiUnicode: // break; // Block of other property data types case DataType.Binary: propStrategy.IsAtomic = true; break; case DataType.Boolean: // LT-13320 "Date of Event is lost after send/receive (data loss)" // says these fields don't play nice as immutable. //if (classInfo.ClassName == "CmPerson" || classInfo.ClassName == "RnGenericRec") // propStrategy.IsImmutable = true; // Surely DateOfBirth, DateOfDeath, and DateOfEvent are fixed. onced they happen. :-) propStrategy.NumberOfChildren = NumberOfChildrenAllowed.Zero; break; //case DataType.Float: // Not used in model // break; case DataType.GenDate: // LT-13320 "Date of Event is lost after send/receive (data loss)" // says these fields don't play nice as immutable. //if (classInfo.ClassName == "CmPerson" || classInfo.ClassName == "RnGenericRec") // propStrategy.IsImmutable = true; // Surely DateOfBirth, DateOfDeath, and DateOfEvent are fixed. onced they happen. :-) propStrategy.NumberOfChildren = NumberOfChildrenAllowed.Zero; break; case DataType.Guid: if (classInfo.ClassName == "CmFilter" || classInfo.ClassName == "CmResource") propStrategy.IsImmutable = true; propStrategy.NumberOfChildren = NumberOfChildrenAllowed.Zero; break; case DataType.Integer: // Fall through if (propertyInfo.PropertyName == "HomographNumber") { // Don't fret about conflicts in merging the homograph numbers. propStrategy.AttributesToIgnoreForMerging.Add("val"); } propStrategy.NumberOfChildren = NumberOfChildrenAllowed.Zero; break; //case DataType.Numeric: // Not used in model // break; case DataType.String: // Contains one <Str> element propStrategy.NumberOfChildren = NumberOfChildrenAllowed.ZeroOrOne; break; case DataType.TextPropBinary: propStrategy.ContextDescriptorGenerator = new StyleContextGenerator(); propStrategy.NumberOfChildren = NumberOfChildrenAllowed.ZeroOrOne; break; case DataType.Time: if (propertyInfo.PropertyName == "DateCreated") { propStrategy.IsImmutable = true; } else { // Suppress conflicts and change reports for other date time properties, which currently are all // some variation on modify time, or most recent run time. // For all of them, it is appropriate to just keep the most recent. propStrategy.Premerger = new PreferMostRecentTimePreMerger(); } propStrategy.NumberOfChildren = NumberOfChildrenAllowed.Zero; break; case DataType.Unicode: // Contains one <Uni> element propStrategy.NumberOfChildren = NumberOfChildrenAllowed.ZeroOrOne; break; } strategiesForMerger.SetStrategy( String.Format("{0}{1}_{2}", isCustom ? "Custom_" : "", classInfo.ClassName, propertyInfo.PropertyName), propStrategy); } }
private static FieldWorkObjectContextGenerator MakeGenerator() { var result = new FieldWorkObjectContextGenerator(); var strategies = new MergeStrategies(); result.MergeStrategies = strategies; strategies.SetStrategy("LexEntry", MakeClassStrategy(new LexEntryContextGenerator(), strategies)); strategies.SetStrategy("ReversalIndexEntry", MakeClassStrategy(new ReversalEntryContextGenerator(), strategies)); strategies.SetStrategy("WfiWordform", MakeClassStrategy(new WfiWordformContextGenerator(), strategies)); strategies.SetStrategy("CmPossibilityList", MakeClassStrategy(new PossibilityListContextGenerator(), strategies)); strategies.SetStrategy("CmPossibility", MakeClassStrategy(new PossibilityContextGenerator(), strategies)); strategies.SetStrategy("LexEntryType", MakeClassStrategy(new PossibilityContextGenerator(), strategies)); strategies.SetStrategy("PhEnvironment", MakeClassStrategy(new EnvironmentContextGenerator(), strategies)); strategies.SetStrategy("DsChart", MakeClassStrategy(new DiscourseChartContextGenerator(), strategies)); strategies.SetStrategy("DsConstChart", MakeClassStrategy(new DiscourseChartContextGenerator(), strategies)); strategies.SetStrategy("ConstChartRow", MakeClassStrategy(new DiscourseChartContextGenerator(), strategies)); strategies.SetStrategy("ConstChartWordGroup", MakeClassStrategy(new DiscourseChartContextGenerator(), strategies)); strategies.SetStrategy("PhNCSegments", MakeClassStrategy(new MultiLingualStringsContextGenerator("Natural Class", "Name", "Abbreviation"), strategies)); strategies.SetStrategy("FsClosedFeature", MakeClassStrategy(new MultiLingualStringsContextGenerator("Phonological Features", "Name", "Abbreviation"), strategies)); strategies.SetStrategy("Text", MakeClassStrategy(new TextContextGenerator(), strategies)); strategies.SetStrategy("RnGenericRec", MakeClassStrategy(new RnGenericRecContextGenerator(), strategies)); strategies.SetStrategy("ScrBook", MakeClassStrategy(new ScrBookContextGenerator(), strategies)); strategies.SetStrategy("ScrSection", MakeClassStrategy(new ScrSectionContextGenerator(), strategies)); return result; }