public void AddLabel(string newLabel, int lcid, bool setAsDefaultLabel) { // Validate the LCID CultureInfo.GetCultureInfo(lcid); string normalizedName = ToolkitUtilities.GetNormalizedTaxonomyName(newLabel, "newLabel"); SharedData sharedData = this.GetSharedDataFromSourceTerm(exceptionIfMissing: true); List <string> labelList = null; if (!sharedData.LabelsByLcid.TryGetValue(lcid, out labelList)) { labelList = new List <string>(); sharedData.LabelsByLcid.Add(lcid, labelList); } int existingIndex = labelList.IndexOf(normalizedName); if (existingIndex >= 0) { labelList.RemoveAt(existingIndex); } if (setAsDefaultLabel) { // Check for sibling terms that are already using this name // (This constraint only applies to the default label.) if (this.TermKind == LocalTermKind.NormalTerm && this.parentItem != null) { var proposedNewLabel = new LocalTermLabel(lcid, newLabel, setAsDefaultLabel); foreach (LocalTerm siblingTerm in this.parentItem.Terms) { if (siblingTerm == this) { continue; } if (siblingTerm.TermKind == LocalTermKind.NormalTerm) { string objection = siblingTerm.ExplainHasLabelConflictWith(this, proposedNewLabel); if (objection != null) { throw new InvalidOperationException(objection); } } } } labelList.Insert(0, normalizedName); } else { labelList.Add(normalizedName); } // Alphabetize the remaining labels labelList.Sort(1, labelList.Count - 1, StringComparer.Ordinal); }
/// <summary> /// Compares otherTerm's labels with this term's labels to see if there are any conflicts. /// A conflict occurs if the default labels (i.e. term names) are equal for a given language LCID. /// Note that we compare all LCIDs from both terms; if a term does not have a default label /// for a given LCID, then we fallback to the default language. (Recall that the "term name" /// is the "default label" for each language, and there is also a "default language" for /// the term store.) /// /// This check can also consider a proposedNewLabelForOtherTerm, which allows us to detect /// problems that would be introduced by adding/changing the otherTerm, before the change /// is performed. /// </summary> /// <returns> /// An "objection" (i.e. error message) if there is a conflict, or null otheriwse. /// </returns> internal string ExplainHasLabelConflictWith(LocalTerm otherTerm, LocalTermLabel proposedNewLabelForOtherTerm = null) { Debug.Assert(this.TermKind == LocalTermKind.NormalTerm); Debug.Assert(otherTerm.TermKind == LocalTermKind.NormalTerm); // The proposedNewLabelForOtherTerm only affects this comparison if it is the default label for a language // (i.e. we don't care about synonyms) if (proposedNewLabelForOtherTerm != null && !proposedNewLabelForOtherTerm.IsDefault) { proposedNewLabelForOtherTerm = null; } SharedData thisSharedData = this.GetSharedDataFromSourceTerm(exceptionIfMissing: true); SharedData otherSharedData = otherTerm.GetSharedDataFromSourceTerm(exceptionIfMissing: true); foreach (int lcid in // Take the union of the LCIDs from both terms, sorted in increasing order, // but compare the default language first new[] { this.DefaultLanguageLcid } .Union( thisSharedData.LabelsByLcid.Keys .Union(otherSharedData.LabelsByLcid.Keys) .Where(x => x != this.DefaultLanguageLcid) .OrderBy(x => x) .Distinct() )) { string thisName = this.GetNameWithDefault(lcid); string otherName = otherTerm.GetNameWithDefaultForConflict(otherSharedData, lcid, proposedNewLabelForOtherTerm); if (thisName.Equals(otherName, StringComparison.OrdinalIgnoreCase)) { return("The term name \"" + otherName + "\" is already in use by a sibling term" + " (LCID=" + lcid + ")"); } } return(null); }
private string GetNameWithDefaultForConflict(SharedData sharedData, int lcid, LocalTermLabel proposedNewLabelForOtherTerm) { if (proposedNewLabelForOtherTerm != null && lcid == proposedNewLabelForOtherTerm.Lcid) { return(proposedNewLabelForOtherTerm.Value); } List <string> labelList = null; if (!sharedData.LabelsByLcid.TryGetValue(lcid, out labelList) || labelList.Count == 0) { lcid = this.DefaultLanguageLcid; if (proposedNewLabelForOtherTerm != null && lcid == proposedNewLabelForOtherTerm.Lcid) { return(proposedNewLabelForOtherTerm.Value); } if (!sharedData.LabelsByLcid.TryGetValue(lcid, out labelList) || labelList.Count == 0) { // this should never occur throw new InvalidOperationException("Assertion failed"); } } return(labelList[0]); }