Пример #1
0
        private void ProcessTermStore(XElement xmlNode, LocalTermStore termStore)
        {
            this.ReadTaxmlComments(xmlNode, termStore);

            int?defaultLanguge = GetIntegerAttributeValue(xmlNode, TaxmlSpec.DefaultLanguageToken);

            if (defaultLanguge != null)
            {
                termStore.DefaultLanguageLcid = defaultLanguge.Value;
            }
            else
            {
                termStore.DefaultLanguageLcid = LocalTermStore.EnglishLanguageLcid;
            }

            // Stage 1: Create everything that can be immediately created
            foreach (XElement childNode in xmlNode.Elements())
            {
                switch (childNode.Name.LocalName)
                {
                case TaxmlSpec.TermSetGroupToken:
                    this.ProcessTermSetGroup(childNode, termStore);
                    break;

                case TaxmlSpec.SyncActionToken:
                    this.ProcessSyncAction(childNode, termStore);
                    break;

                default:
                    throw new ParseException("Unimplemented XML tag \"" + childNode.Name.LocalName + "\"", childNode);
                }
            }
        }
Пример #2
0
 public void SaveToFile(string fileName, LocalTermStore termStore)
 {
     using (StreamWriter streamWriter = new StreamWriter(fileName))
     {
         this.SaveToStream(streamWriter, termStore);
     }
 }
Пример #3
0
 public static string SaveToString(LocalTermStore termStore)
 {
     using (var writer = new StringWriter())
     {
         TaxmlSaver saver = new TaxmlSaver();
         saver.SaveToStream(writer, termStore);
         return(writer.ToString());
     }
 }
Пример #4
0
        protected void SetParentItem <T>(ref T parentItem, T newValue) where T : LocalTaxonomyItem
        {
            if (parentItem == newValue)
            {
                return;
            }

            if (newValue != null)
            {
                string objection = newValue.ExplainIsAllowableParentFor(this);
                if (objection != null)
                {
                    throw new InvalidOperationException(objection);
                }

                if (newValue.defaultLanguageLcid != this.defaultLanguageLcid)
                {
                    // We could do this automatically, but changing the default langauge can
                    // cause copying of term labels whose effects may be counterintuitive.
                    // In most cases, the child object should have been created with the same
                    // default language as its intended parent.
                    throw new InvalidOperationException("The child object cannot be attached"
                                                        + " unless its default language matches the parent.");
                }
            }

            if (parentItem != null)
            {
                LocalTermStore oldTermStore = parentItem.GetTermStore();
                if (oldTermStore != null)
                {
                    oldTermStore.OnBeforeRemoveSubtree(this);
                }

                parentItem.OnRemoveChildItem(this);
            }

            if (newValue != null)
            {
                LocalTermStore newTermStore = newValue.GetTermStore();
                if (newTermStore != null)
                {
                    newTermStore.OnBeforeAddSubtree(this);
                }
            }

            LocalTaxonomyItem oldValue = parentItem;

            parentItem = newValue;

            if (parentItem != null)
            {
                parentItem.OnAddChildItem(this);
            }

            this.OnParentItemChanged(oldValue, newValue);
        }
Пример #5
0
        private void ProcessTermSetGroup(XElement xmlNode, LocalTermStore termStore)
        {
            string name = this.GetRequiredAttributeValue(xmlNode, TaxmlSpec.NameToken);

            if (TaxmlSpec.IsReservedName(name))
            {
                // TODO: Handle system groups here
                throw new NotImplementedException();
            }

            Guid id = this.GetGuidAttributeValue(xmlNode, TaxmlSpec.IdToken) ?? Guid.Empty;

            LocalTermGroup termGroup = new LocalTermGroup(id, name, termStore.DefaultLanguageLcid);

            this.ReadTaxmlComments(xmlNode, termGroup);

            string description = this.GetAttributeValue(xmlNode, TaxmlSpec.DescriptionToken);

            if (description != null)
            {
                termGroup.Description = description;
            }

            // Add the group to the term store
            termStore.AddTermGroup(termGroup);

            bool processedDescription = false;

            foreach (XElement childNode in xmlNode.Elements())
            {
                switch (childNode.Name.LocalName)
                {
                case TaxmlSpec.DescriptionToken:
                    if (processedDescription)
                    {
                        throw new ParseException("The description cannot be specified more than once", childNode);
                    }
                    processedDescription  = true;
                    termGroup.Description = childNode.Value;
                    break;

                case TaxmlSpec.TermSetToken:
                    this.ProcessTermSet(childNode, termGroup);
                    break;

                case TaxmlSpec.SyncActionToken:
                    this.ProcessSyncAction(childNode, termGroup);
                    break;

                default:
                    throw new ParseException("Unimplemented XML tag \"" + childNode.Name.LocalName + "\"", childNode);
                }
            }
        }
Пример #6
0
        public LocalTermStore LoadFromFile(string csvFileName)
        {
            LocalTermStore termStore = new LocalTermStore(Guid.Empty, "Term Store");
            LocalTermGroup termGroup = termStore.AddTermGroup(Guid.Empty, Path.GetFileNameWithoutExtension(csvFileName));

            using (CsvReader csvReader = new CsvReader(csvFileName))
            {
                csvReader.WrapExceptions(() =>
                {
                    ProcessCsvLines(termGroup, csvReader);
                });
            }

            return(termStore);
        }
Пример #7
0
        public LocalTermStore LoadFromStream(TextReader textReader)
        {
            XDocument document = XDocument.Load(textReader, LoadOptions.SetLineInfo);

            document.Validate(TaxmlSpec.TaxmlSchema,
                              delegate(object sender, ValidationEventArgs e)
            {
                throw new ParseException(e.Message, sender as XObject, e.Exception);
            }
                              );

            LocalTermStore termStore = new LocalTermStore(Guid.NewGuid(), "Term Store");

            XElement rootElement = document.Root;
            XElement termStoreElement;

            if (rootElement.Name == TaxmlSpec.TermStoreToken)
            {
                // For backwards compatibility, if the root element is the "TermStore" element
                // then wrap it inside a TaxmlFile element
                termStoreElement = rootElement;
                rootElement      = new XElement(TaxmlSpec.TaxmlFileToken, termStoreElement);
                rootElement.SetAttributeValue(TaxmlSpec.VersionToken, TaxmlSpec.Versions.V2_0.ToString());
            }
            else
            {
                termStoreElement = rootElement.Element(TaxmlSpec.TermStoreToken);
            }

            // Check the version
            string  versionString = this.GetAttributeValue(rootElement, TaxmlSpec.VersionToken);
            Version fileVersion   = Version.Parse(versionString);

            if (fileVersion < TaxmlSpec.Versions.OldestLoadable)
            {
                throw new InvalidOperationException(
                          "The TAXML file version is too old and is no longer supported by this tool");
            }
            if (fileVersion > TaxmlSpec.Versions.Current)
            {
                throw new InvalidOperationException(
                          "The TAXML file is using a newer version that is not supported; consider upgrading to a newer tool");
            }

            this.ProcessTermStore(termStoreElement, termStore);

            return(termStore);
        }
Пример #8
0
        public void SaveToStream(TextWriter textWriter, LocalTermStore termStore)
        {
            XElement rootElement = new XElement(TaxmlSpec.TaxmlFileToken);

            rootElement.SetAttributeValue(TaxmlSpec.VersionToken, TaxmlSpec.Versions.Current.ToString());

            XDocument xmlDocument = new XDocument(
                new XDeclaration("1.0", "utf-8", "yes"),
                rootElement
                );

            this.ProcessTree(rootElement, termStore);

            var xmlWriterSettings = new XmlWriterSettings()
            {
                Indent      = true,
                IndentChars = "    "
            };

            using (var xmlWriter = XmlWriter.Create(textWriter, xmlWriterSettings))
            {
                xmlDocument.Save(xmlWriter);
            }

            textWriter.WriteLine(); // append a newline

#if DEBUG
            // Verify that the generated XML conforms to the schema
            xmlDocument.Validate(TaxmlSpec.TaxmlSchema,
                                 delegate(object sender, ValidationEventArgs e)
            {
                throw new ParseException(e.Message, sender as XObject, e.Exception);
            }
                                 );
#endif
        }
Пример #9
0
 protected override void SetParentItem(LocalTaxonomyItem value)
 {
     this.ParentItem = (LocalTermStore)value;
 }
Пример #10
0
        private void ProcessChildTerms(XElement termContainerElement,
                                       LocalTermContainer termContainer, List <CustomOrderedTerm> orderedTerms)
        {
            LocalTermStore termStore = termContainer.GetTermStore();

            foreach (CustomOrderedTerm customOrderedTerm in orderedTerms)
            {
                LocalTerm term = customOrderedTerm.Term;

                bool isTermLink = term.TermKind != LocalTermKind.NormalTerm;

                XElement termElement;
                if (isTermLink)
                {
                    termElement = new XElement(TaxmlSpec.TermLinkToken);
                    if (term.TermKind == LocalTermKind.TermLinkUsingId &&
                        term.TermLinkNameHint.Length > 0)
                    {
                        termElement.Add(new XAttribute(TaxmlSpec.NameHintToken, term.TermLinkNameHint));
                    }
                }
                else
                {
                    termElement = new XElement(TaxmlSpec.TermToken, new XAttribute(TaxmlSpec.NameToken, term.Name));
                }

                termContainerElement.Add(termElement);
                this.ProcessTaxmlComments(termElement, term);

                if (term.Id != Guid.Empty)
                {
                    termElement.Add(new XAttribute(TaxmlSpec.IdToken, term.Id.ToString("B")));
                }

                if (customOrderedTerm.WriteInOrderAttribute)
                {
                    if (termContainer.CustomSortOrder.Contains(term.Id))
                    {
                        termElement.Add(new XAttribute(TaxmlSpec.InOrderToken, true));
                    }
                }

                if (!term.IsAvailableForTagging)
                {
                    termElement.Add(new XAttribute(TaxmlSpec.IsAvailableForTaggingToken, false));
                }

                this.ProcessSyncActionElement(term, termElement);

                if (isTermLink)
                {
                    if (!string.IsNullOrWhiteSpace(term.TermLinkSourcePath))
                    {
                        termElement.Add(new XAttribute(TaxmlSpec.TermLinkSourcePathToken, term.TermLinkSourcePath));
                    }
                    if (term.IsPinnedRoot)
                    {
                        termElement.Add(new XAttribute(TaxmlSpec.IsPinnedRootToken, true));
                    }
                }
                else
                {
                    // TODO: If the Term.Owner is the same as the parent object, can we omit it?
                    if (!string.IsNullOrEmpty(term.Owner))
                    {
                        termElement.Add(new XAttribute(TaxmlSpec.OwnerToken, term.Owner));
                    }

                    if (term.IsDeprecated)
                    {
                        termElement.Add(new XAttribute(TaxmlSpec.IsDeprecatedToken, true));
                    }

                    foreach (LocalizedString description in term.Descriptions)
                    {
                        XElement descriptionElement = new XElement(TaxmlSpec.LocalizedDescriptionToken, description);
                        termElement.Add(descriptionElement);

                        if (description.Lcid != term.DefaultLanguageLcid)
                        {
                            descriptionElement.Add(new XAttribute(TaxmlSpec.LanguageToken, description.Lcid));
                            descriptionElement.Value = description.Value;
                        }
                    }

                    this.ProcessCustomProperties(term.CustomProperties, termElement, isLocal: false);
                }

                this.ProcessCustomProperties(term.LocalCustomProperties, termElement, isLocal: true);

                List <CustomOrderedTerm> orderedChildTerms = this.ProcessCustomSortOrder(term, termElement);

                if (!isTermLink)
                {
                    foreach (LocalTermLabel label in term.Labels)
                    {
                        // If this is the Term.Name label, then it doesn't need to be specified explicitly
                        if (label.IsDefault && label.Lcid == term.DefaultLanguageLcid)
                        {
                            continue;
                        }

                        XElement labelElement = new XElement(TaxmlSpec.LabelToken, label.Value);
                        termElement.Add(labelElement);

                        if (label.Lcid != term.DefaultLanguageLcid)
                        {
                            labelElement.Add(new XAttribute(TaxmlSpec.LanguageToken, label.Lcid));
                        }

                        if (label.IsDefault)
                        {
                            labelElement.Add(new XAttribute(TaxmlSpec.IsDefaultForLanguageToken, true));
                        }
                    }
                }

                this.ProcessChildTerms(termElement, term, orderedChildTerms);
            }
        }
Пример #11
0
        private void ProcessTree(XElement rootElement, LocalTermStore termStore)
        {
            XElement termStoreElement = new XElement(TaxmlSpec.TermStoreToken);

            rootElement.Add(termStoreElement);

            termStoreElement.SetAttributeValue(TaxmlSpec.DefaultLanguageToken, termStore.DefaultLanguageLcid);

            this.ProcessTaxmlComments(termStoreElement, termStore);
            this.ProcessSyncActionElement(termStore, termStoreElement);

            foreach (LocalTermGroup termGroup in termStore.TermGroups)
            {
                // Replace e.g. "System" with the reserved symbol "|SystemGroup|"
                string adjustedGroupName = termGroup.Name;
                if (termGroup.IsSystemGroup)
                {
                    adjustedGroupName = TaxmlSpec.SystemGroupReservedName;
                }

                XElement groupElement = new XElement(TaxmlSpec.TermSetGroupToken,
                                                     new XAttribute(TaxmlSpec.NameToken, adjustedGroupName));
                termStoreElement.Add(groupElement);

                this.ProcessTaxmlComments(groupElement, termGroup);

                if (termGroup.Id != Guid.Empty)
                {
                    groupElement.Add(new XAttribute(TaxmlSpec.IdToken, termGroup.Id.ToString("B")));
                }

                this.ProcessSyncActionElement(termGroup, groupElement);

                if (!string.IsNullOrEmpty(termGroup.Description))
                {
                    groupElement.Add(new XElement(TaxmlSpec.DescriptionToken, termGroup.Description));
                }

                foreach (LocalTermSet termSet in termGroup.TermSets)
                {
                    bool isOrphanedTermsTermSet = false;
                    bool isKeywordsTermSet      = false;

                    // Replace e.g. "Orphaned Terms" with the reserved symbol "|OrphanedTermsTermSet|"
                    string adjustedTermSetName = termSet.Name;
#if false
                    // TODO
                    if (termGroup.IsSystemGroup)
                    {
                        if (termSet.Id == termStore.OrphanedTermsTermSet.Id)
                        {
                            adjustedTermSetName    = TaxmlSpec.OrphanedTermsTermSetReservedName;
                            isOrphanedTermsTermSet = true;
                        }
                        else if (termSet.Id == this.termStoreAdapter.KeywordsTermSet.Id)
                        {
                            adjustedTermSetName = TaxmlSpec.KeywordsTermSetReservedName;
                            isKeywordsTermSet   = true;
                        }
                    }
#endif
                    XElement termSetElement = new XElement(TaxmlSpec.TermSetToken,
                                                           new XAttribute(TaxmlSpec.NameToken, adjustedTermSetName));
                    groupElement.Add(termSetElement);

                    this.ProcessTaxmlComments(termSetElement, termSet);

                    this.ProcessSyncActionElement(termSet, termSetElement);


                    if (!isOrphanedTermsTermSet && !isKeywordsTermSet)
                    {
                        if (termSet.Id != Guid.Empty)
                        {
                            termSetElement.Add(new XAttribute(TaxmlSpec.IdToken, termSet.Id.ToString("B")));
                        }

                        if (!termSet.IsAvailableForTagging)
                        {
                            termSetElement.Add(new XAttribute(TaxmlSpec.IsAvailableForTaggingToken, false));
                        }

                        if (termSet.IsOpenForTermCreation)
                        {
                            termSetElement.Add(new XAttribute(TaxmlSpec.IsOpenForTermCreationToken, true));
                        }
                    }

                    if (!string.IsNullOrEmpty(termSet.Owner) && !isKeywordsTermSet)
                    {
                        termSetElement.Add(new XAttribute(TaxmlSpec.OwnerToken, termSet.Owner));
                    }

                    if (!string.IsNullOrEmpty(termSet.Contact) && !isKeywordsTermSet)
                    {
                        termSetElement.Add(new XAttribute(TaxmlSpec.ContactToken, termSet.Contact));
                    }

                    foreach (var localizedName in termSet.LocalizedNames)
                    {
                        if (localizedName.Lcid != termSet.DefaultLanguageLcid)
                        {
                            termSetElement.Add(
                                new XElement(TaxmlSpec.LocalizedNameToken, localizedName,
                                             new XAttribute(TaxmlSpec.LanguageToken, localizedName.Lcid))
                                );
                        }
                    }

                    // Technically the TermSet.Description property can be modified for the special "Keywords"
                    // term set, but it's not recommended, so we don't support that
                    if (!string.IsNullOrEmpty(termSet.Description) && !isOrphanedTermsTermSet && !isKeywordsTermSet)
                    {
                        termSetElement.Add(new XElement(TaxmlSpec.DescriptionToken, termSet.Description));
                    }

                    this.ProcessCustomProperties(termSet.CustomProperties, termSetElement, isLocal: false);

                    List <CustomOrderedTerm> orderedChildTerms = this.ProcessCustomSortOrder(termSet, termSetElement);

                    foreach (string stakeholder in termSet.Stakeholders)
                    {
                        termSetElement.Add(new XElement(TaxmlSpec.StakeHolderToken, stakeholder));
                    }

                    this.ProcessChildTerms(termSetElement, termSet, orderedChildTerms);
                }
            }
        }