Ejemplo n.º 1
0
        private static void AddTranslationStrategy(MergeStrategies mergeStrategies)
        {
            var strategy = new ElementStrategy(false)
            {
                MergePartnerFinder = new OptionalKeyAttrFinder("type", new FormMatchingFinder())
            };

            mergeStrategies.SetStrategy("translation", strategy);
        }
        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 ElementStrategy AddSingletonElementType(MergeStrategies mergeStrategies, string name)
        {
            var strategy = new ElementStrategy(false)
            {
                MergePartnerFinder = new FindFirstElementWithSameName()
            };

            mergeStrategies.SetStrategy(name, strategy);
            return(strategy);
        }
Ejemplo n.º 4
0
        private static void AddExampleSentenceStrategy(MergeStrategies mergeStrategies)
        {
            var strategy = new ElementStrategy(false)
            {
                MergePartnerFinder = new OptionalKeyAttrFinder("source", new FormMatchingFinder())
            };

            strategy.AttributesToIgnoreForMerging.Add("dateModified");
            mergeStrategies.SetStrategy("example", strategy);
        }
Ejemplo n.º 5
0
        /* 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);
        }
Ejemplo n.º 6
0
        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;
        }
Ejemplo n.º 8
0
        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
        }
Ejemplo n.º 9
0
        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);
            }
        }
Ejemplo n.º 10
0
        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;
        }