Exemplo n.º 1
0
        /// <summary>
        /// Deal with problems of the Morph child, if any.
        /// </summary>
        /// <param name="rt"></param>
        /// <param name="logger"></param>
        /// <param name="guidString"></param>
        private void FixMorph(XElement rt, FwDataFixer.ErrorLogger logger, string guidString)
        {
            var destGuidString = ChildSurrogateGuid(rt, "Morph");

            if (destGuidString == null)
            {
                return;
            }
            var objsur = rt.Element("Morph").Element("objsur");             // parts of path must exist, we got destGuidString

            if (m_guids.Contains(new Guid(destGuidString)))
            {
                return;                 // all is well, not dangling.
            }
            var      senseGuid = ChildSurrogateGuid(rt, "Sense");
            Guid     entryGuid;
            XElement entryElt;

            if (senseGuid != null && m_owners.TryGetValue(new Guid(senseGuid), out entryGuid) && m_entrys.TryGetValue(entryGuid.ToString(), out entryElt))
            {
                var soleForm = GetSoleForm(entryElt);
                if (soleForm != null)
                {
                    // We can repair it to use the only form of the right entry, a very promising repair.
                    objsur.SetAttributeValue("guid", soleForm);
                    logger(guidString, DateTime.Now.ToShortDateString(),
                           String.Format(Strings.ksRepairingBundleFormFromEntry, guidString));
                    return;
                }
            }
            // If we can't fix it nicely, just clobber it (and its parent, since this is an atomic property).
            logger(guidString, DateTime.Now.ToShortDateString(), String.Format(Strings.ksRemovingDanglingMorph,
                                                                               destGuidString, guidString));
            objsur.Parent.Remove();
        }
Exemplo n.º 2
0
 private void ReportBadLexReference(Guid guid, Guid guidOwner, FwDataFixer.ErrorLogger errorLogger)
 {
     // Example: if guid and rt belong to a "LexReference" that has fewer than two Targets,
     //			then the LexReference will be removed from the file and this will report it.
     //			The objsur reference to the row gets removed elsewhere.
     errorLogger(String.Format(Strings.ksRemovingBadLexReference, guid, guidOwner), true);
 }
Exemplo n.º 3
0
        /// <summary>
        /// This is the main routine that does actual repair on list names.
        /// </summary>
        /// <param name="rt"></param>
        /// <param name="logger"></param>
        /// <returns>true (always, currently) to indicate that the list should survive.</returns>
        internal override bool FixElement(XElement rt, FwDataFixer.ErrorLogger logger)
        {
            var    guid = rt.Attribute("guid").Value;
            string name;

            if (!m_guidToName.TryGetValue(guid, out name))
            {
                return(true);                // we didn't see a list with this guid; do nothing
            }
            string firstGuid = m_nameToGuid[name];

            if (firstGuid == guid)
            {
                return(true);                // This one is allowed to keep this name
            }
            int    append    = 1;
            string fixedName = name + append;

            while (m_nameToGuid.ContainsKey(fixedName))
            {
                fixedName = name + append++;
            }
            m_nameToGuid[fixedName] = guid;             // this name is now taken too.
            rt.Element("Name").Element("AUni").SetValue(fixedName);
            logger(guid, DateTime.Now.ToShortDateString(),
                   String.Format(Strings.ksRepairingDuplicateListName, name, firstGuid, guid, fixedName));
            return(true);
        }
        /// <summary>
        /// This is called in the second pass that actually changes the objects. It does the following:
        /// - Deletes wordforms that have been merged (by returning false for them).
        /// - Adds analyses of deleted wordforms to the Analysis of the survivor that replaces them.
        /// - Fixes the ownerguid of those transferred analyses.
        /// - Fixes any segments which refer to deleted wordforms to refer instead to the replacement.
        /// </summary>
        /// <param name="rt"></param>
        /// <param name="logger"></param>
        /// <returns></returns>
        internal override bool FixElement(XElement rt, FwDataFixer.ErrorLogger logger)
        {
            var className = rt.Attribute("class").Value;

            if (className == "WfiWordform")
            {
                // Arrange for it to be deleted if that's what we decided to do.
                string replacement;
                var    guid = rt.Attribute("guid").Value;
                if (m_guidsToDelete.TryGetValue(guid, out replacement))
                {
                    logger(guid, DateTime.Now.ToShortDateString(),
                           String.Format(Strings.ksDuplicateWordform, guid, GetWordformKey(rt), replacement));
                    return(false);                    // discard this element
                }
                // Modify it if we need to add to its analyses.
                string modifiedAnalyses;
                if (m_modifiedWordforms.TryGetValue(guid, out modifiedAnalyses))
                {
                    var analyses = rt.Element("Analyses");
                    if (analyses != null)
                    {
                        analyses.Remove();
                    }
                    var mergedAnalyses = XElement.Parse(modifiedAnalyses);
                    rt.Add(mergedAnalyses);
                }
            }
            else if (className == "Segment")
            {
                // Fix refs to deleted wordforms.
                var analyses = rt.Element("Analyses");
                if (analyses != null)
                {
                    foreach (var objsur in analyses.Elements())
                    {
                        var    oldGuid = objsur.Attribute("guid").Value;
                        string newGuid;
                        if (m_guidsToDelete.TryGetValue(oldGuid, out newGuid))
                        {
                            objsur.Attribute("guid").SetValue(newGuid);
                        }
                    }
                }
            }
            else if (className == "WfiAnalysis")
            {
                // Fix ownerguid for moved analyses.
                var ownerAttr = rt.Attribute("ownerguid");
                if (ownerAttr != null)
                {
                    string newGuid;
                    if (m_guidsToDelete.TryGetValue(ownerAttr.Value, out newGuid))
                    {
                        ownerAttr.SetValue(newGuid);
                    }
                }
            }
            return(true);            // keep the current element.
        }
Exemplo n.º 5
0
        //Go through the list of MSA references in the file and remove those which do not occur in any sense
        //Why? Because the Chorus merge will flag a conflict for the users but end up placing both references
        //in the entry. This incorrectly causes parts of speech to be referenced in the Entry which no sense uses.
        internal override bool FixElement(XElement rt, FwDataFixer.ErrorLogger logger)
        {
            var guid = rt.Attribute("guid");

            if (guid == null)
            {
                return(true);
            }
            if (rt.Attribute("class").Value == "LexEntry")
            {
                var MSAs    = rt.Element("MorphoSyntaxAnalyses");
                var rejects = new List <XNode>();
                if (MSAs != null)
                {
                    var entryGuidString = guid.Value;
                    foreach (var objsur in MSAs.Descendants("objsur"))
                    {
                        if (IsRejectedMsa(objsur))
                        {
                            rejects.Add(objsur);
                        }
                    }
                    foreach (var reject in rejects)
                    {
                        logger(Strings.ksRemovedUnusedMsa, true);
                        reject.Remove();
                    }
                }
            }
            return(true);
        }
Exemplo n.º 6
0
        //For each LexEntry element, set the homograph number as determined in the FinalFixerInitialization method.
        internal override bool FixElement(XElement rt, FwDataFixer.ErrorLogger logger)
        {
            var guid      = new Guid(rt.Attribute("guid").Value);
            var xaClass   = rt.Attribute("class");
            var className = xaClass == null ? kUnknown : xaClass.Value;

            switch (className)
            {
            case "LexEntry":
                string homographNum;
                if (!m_LexEntryHomographNumbers.TryGetValue(guid, out homographNum))
                {
                    homographNum = "0";                             // If it's not a homograph, its HN must be zero.
                }
                var homographElement = rt.Element("HomographNumber");
                if (homographElement == null)
                {
                    if (homographNum != "0")                             // no need to make a change if already implicitly zero.
                    {
                        rt.Add(new XElement("HomographNumber", new XAttribute("val", homographNum)));
                    }
                    break;
                }
                homographElement.SetAttributeValue("val", homographNum);
                break;

            default:
                break;
            }
            return(true);
        }
Exemplo n.º 7
0
 private void ReportOwnerOfBadSegmentReferences(Guid guid, Guid guidOwner, string className,
                                                FwDataFixer.ErrorLogger errorLogger)
 {
     // Example: if guid, className, and rt belong to a "ConstChartWordGroup" that has no Begin
     //          or EndSegment reference (being earlier deleted by OriginalFixer's dangling reference
     //          repair), then this will remove the ConstChartWordGroup from the file and report it.
     //			The objsur reference to the cell gets removed elsewhere.
     errorLogger(String.Format(Strings.ksRemovingBadAnalysisRefObj, guid, className, guidOwner), true);
 }
Exemplo n.º 8
0
        private void AdjustBadSegmentReferenceAndReport(XElement rt, Guid guid, Guid guidOwner,
                                                        string className, FwDataFixer.ErrorLogger errorLogger)
        {
            // Example: if guid, className, and rt belong to a "ConstChartWordGroup" that has only one valid
            //          Begin or EndSegment reference (the other being earlier deleted by OriginalFixer's
            //          dangling reference repair), then this will replace the missing Segment reference
            //          with the valid one and report the repair.
            var fieldModified = ReplaceMissingSegmentReferenceWithOtherOne(rt);

            // TODO: Fix message string
            errorLogger(String.Format(Strings.ksAdjustingAnalysisRefObj, guid, className, fieldModified), true);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Make any required fixes to the MSA child element.
        /// </summary>
        /// <param name="rt"></param>
        /// <param name="logger"></param>
        /// <param name="guidString"></param>
        private void FixMsa(XElement rt, FwDataFixer.ErrorLogger logger, string guidString)
        {
            var destGuidString = ChildSurrogateGuid(rt, "Msa");

            if (destGuidString == null)
            {
                return;
            }
            var objsur = rt.Element("Msa").Element("objsur");             // parts of path must exist, we got destGuidString

            if (m_guids.Contains(new Guid(destGuidString)) && !m_senseFixer.IsRejectedMsa(objsur))
            {
                return;                 // msa is not dangling.
            }
            var    senseGuid = ChildSurrogateGuid(rt, "Sense");
            string senseMsaGuid;

            if (senseGuid != null && m_senseToMsa.TryGetValue(senseGuid, out senseMsaGuid) && m_guids.Contains(new Guid(senseMsaGuid)))
            {
                // We can repair it to match the sense's msa, an ideal repair, since we checked the sense's msa IS valid.
                objsur.SetAttributeValue("guid", senseMsaGuid);
                logger(guidString, DateTime.Now.ToShortDateString(),
                       String.Format(Strings.ksRepairingMorphBundleFromSense, guidString));
                return;
            }
            // Next see if we can link to a unique msa via our morph child.
            var      morphGuidString = ChildSurrogateGuid(rt, "Morph");
            Guid     entryGuid;
            XElement entryElt;

            if (morphGuidString != null &&
                m_owners.TryGetValue(new Guid(morphGuidString), out entryGuid) &&
                m_entrys.TryGetValue(entryGuid.ToString(), out entryElt))
            {
                var soleEntryMsa = GetSoleMsaGuid(entryElt);
                if (soleEntryMsa != null)
                {
                    objsur.SetAttributeValue("guid", soleEntryMsa);
                    logger(guidString, DateTime.Now.ToShortDateString(),
                           String.Format(Strings.ksRepairingMorphBundleFromEntry, guidString));
                    return;
                }
            }
            // If we can't fix it nicely, just clobber it (and its parent, since this is an atomic property).
            logger(guidString, DateTime.Now.ToShortDateString(), String.Format(Strings.ksRemovingDanglingMsa,
                                                                               destGuidString, guidString));
            objsur.Parent.Remove();
        }
Exemplo n.º 10
0
        internal override bool FixElement(XElement rt, FwDataFixer.ErrorLogger logger)
        {
            var guid             = new Guid(rt.Attribute("guid").Value);
            var xaClass          = rt.Attribute("class");
            var className        = xaClass == null ? "<unknown>" : xaClass.Value;
            var customProperties = GetAllCustomProperties(rt);

            foreach (var kvp in customProperties)
            {
                if (!string.IsNullOrEmpty(kvp.Key) && m_customFieldNames.ContainsKey(kvp.Key))
                {
                    continue;
                }
                logger(String.Format(Strings.ksRemovingUndefinedCustomProperty, kvp.Key.Substring(0, kvp.Key.LastIndexOf('_')), className, guid), true);
                kvp.Value.Remove();
            }
            return(true);
        }
Exemplo n.º 11
0
        internal override bool FixElement(XElement rt, FwDataFixer.ErrorLogger logger)
        {
            var classAttr = rt.Attribute("class");

            if (classAttr == null)
            {
                return(true);                // bizarre, but leave it alone
            }
            List <string> requiredFields;

            if (!m_customFields.TryGetValue(classAttr.Value, out requiredFields))
            {
                return(true);                // has no custom fields we care about
            }
            var missingFields = new HashSet <string>(requiredFields);

            foreach (var child in rt.Elements())
            {
                if (child.Name == "Custom")
                {
                    var nameAttr = child.Attribute("name");
                    if (nameAttr != null)
                    {
                        missingFields.Remove(nameAttr.Value);                         // not missing, we don't need to add it.
                    }
                }
            }
            foreach (var fieldName in missingFields)
            {
                rt.Add(new XElement("Custom",
                                    new XAttribute("name", fieldName),
                                    new XAttribute("val", "0")));
                var guid = rt.Attribute("guid").Value;
                // This is such an insignificant fix from the user's point of view that we might prefer not
                // even to report it. But don't remove the logging without adding another mechanism for
                // the system to know that a problem has been fixed...this controls the important behavior
                // of re-splitting the file before we commit.
                logger(guid, DateTime.Now.ToShortDateString(),
                       String.Format(Strings.ksAddingMissingDefaultForValueType, guid));
            }
            return(true);
        }
Exemplo n.º 12
0
        /// <summary>
        /// This is the main routine that does actual repair on morph bundles.
        /// </summary>
        /// <param name="rt"></param>
        /// <param name="logger"></param>
        /// <returns>true (always, currently) to indicate that the bundle should survive.</returns>
        internal override bool FixElement(XElement rt, FwDataFixer.ErrorLogger logger)
        {
            var guidString = rt.Attribute("guid").Value;
            var xaClass    = rt.Attribute("class");

            if (xaClass == null)
            {
                return(true);                // we can't fix it, anyway.
            }
            var className = xaClass.Value;

            switch (className)
            {
            case "WfiMorphBundle":
                FixMsa(rt, logger, guidString);
                FixMorph(rt, logger, guidString);
                break;
            }
            return(true);
        }
Exemplo n.º 13
0
        internal override bool FixElement(XElement rt, FwDataFixer.ErrorLogger errorLogger)
        {
            var xaClass = rt.Attribute("class").Value;

            switch (xaClass)
            {
            case "StStyle":
                var guid = rt.Attribute("guid").Value;
                if (!m_deletedGuids.Contains(guid))
                {
                    return(true);                                   // keep it as far as we're concerned.
                }
                var name = rt.Element("Name").Element("Uni").Value; // none can be null or we wouldn't have listed it for deletion
                errorLogger(guid.ToString(), DateTime.Now.ToShortDateString(),
                            String.Format(Strings.ksRemovingDuplicateStyle, name));
                return(false);                        // This element must go away!

            case "LangProject":
            case "Scripture":
                var styles = rt.Element("Styles");
                if (styles == null)
                {
                    return(true);
                }
                // Removing these here prevents additional error messages about missing objects, since the
                // targets of these objsurs are no longer present.
                foreach (var objsur in styles.Elements().ToArray())                         // ToArray so as not to modify collection we're iterating over
                {
                    var surGuid = objsur.Attribute("guid").Value;
                    if (m_deletedGuids.Contains(surGuid))
                    {
                        objsur.Remove();
                    }
                }
                break;
            }
            return(true);            // we're not deleting it.
        }
Exemplo n.º 14
0
 private static void ReportOwnerOfEmptySequence(Guid guid, Guid guidOwner, string className, FwDataFixer.ErrorLogger errorLogger)
 {
     // Example: if guid, className, and rt belong to a "ConstChartRow" that has no cells and guidOwner belongs
     //			to a DsConstChart, then this will remove the ConstChartRow from the file and report it.
     //			The objsur reference to the row gets removed elsewhere.
     errorLogger(guid.ToString(), DateTime.Now.ToShortDateString(), String.Format(Strings.ksRemovingOwnerOfEmptySequence,
                                                                                  guid, className, guidOwner));
 }
Exemplo n.º 15
0
        /// <summary>
        /// Do any fixes to this particular root element here.
        /// Return true if we are done fixing this element and can write it out.
        /// Return false if we need to delete this root element.
        /// </summary>
        /// <param name="rt"></param>
        /// <param name="errorLogger"></param>
        /// <returns></returns>
        internal override bool FixElement(XElement rt, FwDataFixer.ErrorLogger errorLogger)
        {
            var guid      = new Guid(rt.Attribute("guid").Value);
            var guidOwner = SafelyGetOwnerGuid(guid);
            var xaClass   = rt.Attribute("class");
            var className = xaClass == null ? kUnknown : xaClass.Value;

            if (guidOwner == Guid.Empty || className == kUnknown)
            {
                return(true);                // these should have been fixed by another fixer!
            }
            List <Guid> danglingRefList;     // used in 2 cases below.

            switch (className)
            {
            case "DsConstChart":
                // Check all chart rows for deletion and remove dangling references.
                if (!m_rowsToDelete.TryGetValue(guid, out danglingRefList))
                {
                    return(true);                            // this chart has no rows to delete.
                }
                // Report not needed: we will report deleting the row in case ConstChartRow
                rt.Descendants("objsur").Where(
                    objsur => danglingRefList.Contains(GetObjsurGuid(objsur))).Remove();
                break;

            case "StText":
                // Check for cell refs to delete and remove reference.
                if (m_ownerThatWillLoseOwnee.TryGetValue(guid, out danglingRefList))
                {
                    // Report not needed: we will report deleting the row in case TextTag or similar
                    rt.Descendants("objsur").Where(
                        objsur => danglingRefList.Contains(GetObjsurGuid(objsur))).Remove();
                }
                break;

            case "ConstChartRow":
                // Step 1: if row is set for deletion, remove, report, and return.
                // guidOwner is chart, guid is row
                if (m_rowsToDelete.TryGetValue(guidOwner, out danglingRefList))
                {
                    if (danglingRefList.Contains(guid))
                    {
                        ReportOwnerOfEmptySequence(guid, guidOwner, className, errorLogger);
                        return(false);                                // delete this rt element
                    }
                }

                // Step 2: check for cell refs to remove due to clause marker problem.
                if (m_cellRefsToDelete.TryGetValue(guid, out danglingRefList))
                {
                    rt.Descendants("objsur").Where(
                        objsur => danglingRefList.Contains(GetObjsurGuid(objsur))).Remove();
                }
                // Step 3: check for cell refs to delete because of Segment problem.
                if (m_ownerThatWillLoseOwnee.TryGetValue(guid, out danglingRefList))
                {
                    rt.Descendants("objsur").Where(
                        objsur => danglingRefList.Contains(GetObjsurGuid(objsur))).Remove();
                }
                break;

            case "ConstChartClauseMarker":
                // If marker guid is in m_emptyClauseMarkers remove and report.
                if (!m_emptyClauseMarkers.Contains(guid))
                {
                    return(true);
                }
                ReportOwnerOfEmptySequence(guid, guidOwner, className, errorLogger);
                return(false);                        // delete this rt element

            case "ConstChartWordGroup":
            case "TextTag":
                // If WordGroup or TextTag guid is in m_objsToDelete, remove it and report.
                if (m_objsToDelete.Contains(guid))
                {
                    ReportOwnerOfBadSegmentReferences(guid, guidOwner, className, errorLogger);
                    return(false);                            // delete this rt element
                }
                // If WordGroup or TextTag guid is in m_objsToAdjust, adjust and report.
                if (m_objsToAdjust.Contains(guid))
                {
                    AdjustBadSegmentReferenceAndReport(rt, guid, guidOwner, className, errorLogger);
                }
                break;

            case "PhSegRuleRHS":
                // Check for sequence context refs to delete and remove reference.
                if (!m_phContextRefsToDelete.TryGetValue(guid, out danglingRefList))
                {
                    return(true);
                }
                rt.Descendants("objsur").Where(
                    objsur => danglingRefList.Contains(GetObjsurGuid(objsur))).Remove();
                break;

            case "PhSequenceContext":
                // Remove a PhSequenceContext from the correct side of its owning rule,
                // if it has no Members.
                if (!m_emptySequenceContexts.Contains(guid))
                {
                    return(true);
                }
                ReportOwnerOfEmptySequence(guid, guidOwner, className, errorLogger);
                return(false);                        // delete this rt element

            case "LexRefType":
                // Check for LexRefTypes to remove reference.
                if (!m_typeRefsLosingReferences.TryGetValue(guid, out danglingRefList))
                {
                    return(true);
                }
                rt.Descendants("objsur").Where(
                    objsur => danglingRefList.Contains(GetObjsurGuid(objsur))).Remove();
                break;

            case "LexReference":
                // Remove a LexReference that only has one (or fewer) Targets.
                if (!m_lexReferencesToDelete.Contains(guid))
                {
                    return(true);
                }
                ReportBadLexReference(guid, guidOwner, errorLogger);
                return(false);                        // delete this rt element

            default:
                break;
            }
            return(true);
        }
Exemplo n.º 16
0
 /// <summary>
 /// Do any fixes to this particular root element here.
 /// Return true if we are done fixing this element and can write it out.
 /// Return false if we need to delete this root element.
 /// </summary>
 /// <param name="rt"></param>
 /// <param name="logger"></param>
 /// <returns></returns>
 internal abstract bool FixElement(XElement rt, FwDataFixer.ErrorLogger logger);