private static AtomCategoryMetadata CreateCategoryMetadata(IEnumerable <XmlTreeAnnotation> children) { AtomCategoryMetadata metadata = null; foreach (XmlTreeAnnotation epmTree in children.Where(child => child.IsAttribute)) { if (string.IsNullOrEmpty(epmTree.NamespaceName)) { if (metadata == null) { metadata = new AtomCategoryMetadata(); } string localName = epmTree.LocalName; if (localName == TestAtomConstants.AtomCategoryTermAttributeName) { metadata.Term = epmTree.PropertyValue; } else if (localName == TestAtomConstants.AtomCategorySchemeAttributeName) { metadata.Scheme = string.IsNullOrEmpty(epmTree.PropertyValue) ? null : epmTree.PropertyValue; } else if (localName == TestAtomConstants.AtomCategoryLabelAttributeName) { metadata.Label = epmTree.PropertyValue; } else { throw new NotSupportedException("Unsupported metadata '" + localName + "' found for category."); } } } return(metadata); }
/// <summary> /// Adds a new category to feed metadata. /// </summary> /// <param name="feedMetadata">The feed metadata to add the category to.</param> /// <param name="categoryMetadata">The category metadata to add.</param> internal static void AddCategory(this AtomFeedMetadata feedMetadata, AtomCategoryMetadata categoryMetadata) { Debug.Assert(feedMetadata != null, "feedMetadata != null"); Debug.Assert(categoryMetadata != null, "categoryMetadata != null"); feedMetadata.Categories = feedMetadata.Categories.ConcatToReadOnlyEnumerable("Categories", categoryMetadata); }
/// <summary> /// Adds a new category to entry metadata. /// </summary> /// <param name="entryMetadata">The entry metadata to add the category to.</param> /// <param name="categoryMetadata">The category metadata to add.</param> internal static void AddCategory(this AtomEntryMetadata entryMetadata, AtomCategoryMetadata categoryMetadata) { Debug.Assert(entryMetadata != null, "entryMetadata != null"); Debug.Assert(categoryMetadata != null, "categoryMetadata != null"); entryMetadata.Categories = entryMetadata.Categories.ConcatToReadOnlyEnumerable("Categories", categoryMetadata); }
/// <summary> /// Writes the 'atom:category' element given category metadata. /// </summary> /// <param name="writer">The Xml writer to write to.</param> /// <param name="category">The category information to write.</param> internal static void WriteCategory(XmlWriter writer, AtomCategoryMetadata category) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(writer != null, "writer != null"); Debug.Assert(category != null, "Category must not be null."); WriteCategory(writer, category.Term, category.Scheme, category.Label); }
/// <summary> /// Copy constructor. /// </summary> /// <param name="other">The <see cref="AtomCategoryMetadata"/> instance to copy the values from; can be null.</param> internal AtomCategoryMetadata(AtomCategoryMetadata other) { if (other == null) { return; } this.Term = other.Term; this.Scheme = other.Scheme; this.Label = other.Label; }
/// <summary> /// Copy constructor. /// </summary> /// <param name="other">The <see cref="AtomCategoryMetadata"/> instance to copy the values from; can be null.</param> internal AtomCategoryMetadata(AtomCategoryMetadata other) { DebugUtils.CheckNoExternalCallers(); if (other == null) { return; } this.Term = other.Term; this.Scheme = other.Scheme; this.Label = other.Label; }
private static void AddEntryMetadata(EntityInstance payloadElement, ODataEntry entry) { AtomEntryMetadata metadata = null; foreach (XmlTreeAnnotation epmTree in payloadElement.Annotations.OfType <XmlTreeAnnotation>()) { if (epmTree.NamespaceName == TestAtomConstants.AtomNamespace) { if (metadata == null) { metadata = new AtomEntryMetadata(); } string localName = epmTree.LocalName; if (localName == TestAtomConstants.AtomAuthorElementName) { Debug.Assert(!epmTree.IsAttribute); AtomPersonMetadata author = CreateAuthorMetadata(epmTree.Children); List <AtomPersonMetadata> authors; if (metadata.Authors == null) { authors = new List <AtomPersonMetadata>(); metadata.Authors = authors; } else { authors = (List <AtomPersonMetadata>)metadata.Authors; } authors.Add(author); } else if (localName == TestAtomConstants.AtomCategoryElementName) { Debug.Assert(!epmTree.IsAttribute); AtomCategoryMetadata category = CreateCategoryMetadata(epmTree.Children); List <AtomCategoryMetadata> categories; if (metadata.Categories == null) { categories = new List <AtomCategoryMetadata>(); metadata.Categories = categories; } else { categories = (List <AtomCategoryMetadata>)metadata.Categories; } categories.Add(category); } else if (localName == TestAtomConstants.AtomContributorElementName) { Debug.Assert(!epmTree.IsAttribute); AtomPersonMetadata contributor = CreateAuthorMetadata(epmTree.Children); List <AtomPersonMetadata> contributors; if (metadata.Contributors == null) { contributors = new List <AtomPersonMetadata>(); metadata.Contributors = contributors; } else { contributors = (List <AtomPersonMetadata>)metadata.Contributors; } contributors.Add(contributor); } else if (localName == TestAtomConstants.AtomIdElementName) { Debug.Assert(!epmTree.IsAttribute); entry.Id = string.IsNullOrEmpty(epmTree.PropertyValue) ? null : new Uri(epmTree.PropertyValue); } else if (localName == TestAtomConstants.AtomLinkElementName) { Debug.Assert(!epmTree.IsAttribute); AtomLinkMetadata link = CreateLinkMetadata(epmTree.Children); List <AtomLinkMetadata> links; if (metadata.Links == null) { links = new List <AtomLinkMetadata>(); metadata.Links = links; } else { links = (List <AtomLinkMetadata>)metadata.Links; } links.Add(link); } else if (localName == TestAtomConstants.AtomPublishedElementName) { Debug.Assert(!epmTree.IsAttribute); metadata.Published = string.IsNullOrEmpty(epmTree.PropertyValue) ? (DateTimeOffset?)null : DateTimeOffset.Parse(epmTree.PropertyValue); } else if (localName == TestAtomConstants.AtomRightsElementName) { Debug.Assert(!epmTree.IsAttribute); AtomTextConstructKind atomConstructKind = GetAtomConstructKind(epmTree.Children); metadata.Rights = new AtomTextConstruct { Kind = atomConstructKind, Text = epmTree.PropertyValue }; } else if (localName == TestAtomConstants.AtomSourceElementName) { Debug.Assert(!epmTree.IsAttribute); metadata.Source = CreateFeedMetadata(epmTree.Children, null); } else if (localName == TestAtomConstants.AtomSummaryElementName) { Debug.Assert(!epmTree.IsAttribute); AtomTextConstructKind atomConstructKind = GetAtomConstructKind(epmTree.Children); metadata.Summary = new AtomTextConstruct { Kind = atomConstructKind, Text = epmTree.PropertyValue }; } else if (localName == TestAtomConstants.AtomTitleElementName) { Debug.Assert(!epmTree.IsAttribute); AtomTextConstructKind atomConstructKind = GetAtomConstructKind(epmTree.Children); metadata.Title = new AtomTextConstruct { Kind = atomConstructKind, Text = epmTree.PropertyValue }; } else if (localName == TestAtomConstants.AtomUpdatedElementName) { Debug.Assert(!epmTree.IsAttribute); metadata.Updated = string.IsNullOrEmpty(epmTree.PropertyValue) ? (DateTimeOffset?)null : DateTimeOffset.Parse(epmTree.PropertyValue); } else { throw new NotSupportedException("Unsupported atom metadata '" + localName + "' found for entry!"); } } } // Fix up metadata for baselining metadata = metadata.Fixup(); if (metadata != null) { entry.SetAnnotation <AtomEntryMetadata>(metadata); } }
public void FeedMetadataWriterTest() { AtomTextConstruct testRights = new AtomTextConstruct { Text = "Copyright Data Fx team." }; AtomTextConstruct testTitle = new AtomTextConstruct { Text = "Test title" }; AtomTextConstruct testSubtitle = new AtomTextConstruct { Text = "Test subtitle" }; const string testUpdated = "2010-11-01T00:04:00Z"; const string testIcon = "http://odata.org/icon"; const string testLogo = "http://odata.org/logo"; const string testAuthorName = "Test Author 1"; const string testAuthorEmail = "*****@*****.**"; const string testAuthorUri = "http://odata.org/authors/1"; var testAuthors = new AtomPersonMetadata[] { new AtomPersonMetadata() { Email = testAuthorEmail, Name = testAuthorName, Uri = new Uri(testAuthorUri) } }; const string testCategoryTerm = "Test category 1 term"; const string testCategoryLabel = "Test category 1 label"; const string testCategoryScheme = "http://odata.org/categories/1"; var testCategories = new AtomCategoryMetadata[] { new AtomCategoryMetadata() { Term = testCategoryTerm, Label = testCategoryLabel, Scheme = testCategoryScheme } }; const string testContributorName = "Test Contributor 1"; const string testContributorEmail = "*****@*****.**"; const string testContributorUri = "http://odata.org/contributors/1"; var testContributors = new AtomPersonMetadata[] { new AtomPersonMetadata() { Email = testContributorEmail, Name = testContributorName, Uri = new Uri(testContributorUri) } }; const string testGeneratorName = "Test generator"; const string testGeneratorUri = "http://odata.org/generator"; const string testGeneratorVersion = "3.0"; var testGenerator = new AtomGeneratorMetadata() { Name = testGeneratorName, Uri = new Uri(testGeneratorUri), Version = testGeneratorVersion }; const string testLinkRelation = "http://odata.org/links/1"; const string testLinkTitle = "Test link 1"; const string testLinkHref = "http://odata.org/links/1"; const string testLinkHrefLang = "de-AT"; int? testLinkLength = 999; const string testLinkMediaType = "image/png"; var testLinks = new AtomLinkMetadata[] { new AtomLinkMetadata() { Relation = testLinkRelation, Title = testLinkTitle, Href = new Uri(testLinkHref), HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType } }; var selfLink = new AtomLinkMetadata() { Relation = TestAtomConstants.AtomSelfRelationAttributeValue, Title = testLinkTitle, Href = new Uri(testLinkHref), HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType }; Func <string, Func <XElement, XElement> > fragmentExtractor = (localName) => (e) => e.Element(TestAtomConstants.AtomXNamespace + localName); // TODO, ckerer: specify an Id via metadata if the entry does not specify one; we first have to decide what rules // we want to apply to merging of metadata and ODataLib OM data. var testCases = new FeedMetadataTestCase[] { new FeedMetadataTestCase { // specify an icon via metadata CustomizeMetadata = metadata => metadata.Icon = new Uri(testIcon), Xml = @"<icon xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testIcon + @"</icon>", Extractor = fragmentExtractor(TestAtomConstants.AtomIconElementName) }, new FeedMetadataTestCase { // specify a logo via metadata CustomizeMetadata = metadata => metadata.Logo = new Uri(testLogo), Xml = @"<logo xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testLogo + @"</logo>", Extractor = fragmentExtractor(TestAtomConstants.AtomLogoElementName) }, new FeedMetadataTestCase { // specify rights via metadata CustomizeMetadata = metadata => metadata.Rights = testRights, Xml = @"<rights type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testRights.Text + @"</rights>", Extractor = fragmentExtractor(TestAtomConstants.AtomRightsElementName) }, new FeedMetadataTestCase { // specify a subtitle via metadata CustomizeMetadata = metadata => metadata.Subtitle = testSubtitle, Xml = @"<subtitle type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testSubtitle.Text + @"</subtitle>", Extractor = fragmentExtractor(TestAtomConstants.AtomSubtitleElementName) }, new FeedMetadataTestCase { // specify a title via metadata CustomizeMetadata = metadata => metadata.Title = testTitle, Xml = @"<title type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testTitle.Text + @"</title>", Extractor = fragmentExtractor(TestAtomConstants.AtomTitleElementName) }, new FeedMetadataTestCase { // specify an updated date via metadata CustomizeMetadata = metadata => metadata.Updated = DateTimeOffset.Parse(testUpdated), Xml = @"<updated xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testUpdated + @"</updated>", Extractor = fragmentExtractor(TestAtomConstants.AtomUpdatedElementName) }, new FeedMetadataTestCase { // no author specified, the default author with empty name is written CustomizeMetadata = metadata => metadata.Authors = null, Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name />", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new FeedMetadataTestCase { // specify an author via metadata CustomizeMetadata = metadata => metadata.Authors = testAuthors, Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name>" + testAuthorName + @"</name>", @" <uri>" + testAuthorUri + @"</uri>", @" <email>" + testAuthorEmail + @"</email>", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new FeedMetadataTestCase { // no author specified but some entries written, no author should be written CustomizeMetadata = metadata => metadata.Authors = null, CustomizePayload = feed => new ODataItem[] { feed, ObjectModelUtils.CreateDefaultEntry() }, Xml = "<authors />", Extractor = result => new XElement("authors", fragmentExtractor(TestAtomConstants.AtomAuthorElementName)(result)) }, new FeedMetadataTestCase { // specify an author via metadata and some entries (the author should be written anyway) CustomizeMetadata = metadata => metadata.Authors = testAuthors, CustomizePayload = feed => new ODataItem[] { feed, ObjectModelUtils.CreateDefaultEntry() }, Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name>" + testAuthorName + @"</name>", @" <uri>" + testAuthorUri + @"</uri>", @" <email>" + testAuthorEmail + @"</email>", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new FeedMetadataTestCase { // specify a category via metadata CustomizeMetadata = metadata => metadata.Categories = testCategories, Xml = @"<category term=""" + testCategoryTerm + @""" scheme=""" + testCategoryScheme + @""" label=""" + testCategoryLabel + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @""" />", Extractor = fragmentExtractor(TestAtomConstants.AtomCategoryElementName) }, new FeedMetadataTestCase { // specify a contributor via metadata CustomizeMetadata = metadata => metadata.Contributors = testContributors, Xml = string.Join( "$(NL)", @"<contributor xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name>" + testContributorName + @"</name>", @" <uri>" + testContributorUri + @"</uri>", @" <email>" + testContributorEmail + @"</email>", @"</contributor>"), Extractor = fragmentExtractor(TestAtomConstants.AtomContributorElementName) }, new FeedMetadataTestCase { // specify a generator via metadata CustomizeMetadata = metadata => metadata.Generator = testGenerator, Xml = @"<generator uri=""" + testGeneratorUri + @""" version=""" + testGeneratorVersion + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testGeneratorName + @"</generator>", Extractor = fragmentExtractor(TestAtomConstants.AtomGeneratorElementName) }, new FeedMetadataTestCase { // specify a link via metadata CustomizeMetadata = metadata => metadata.Links = testLinks, Xml = @"<link rel=""" + testLinkRelation + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Single() }, new FeedMetadataTestCase { // no self link specified CustomizeMetadata = metadata => metadata.SelfLink = null, Xml = @"<selflink/>", Extractor = (e) => new XElement("selflink", e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomSelfRelationAttributeValue)) }, new FeedMetadataTestCase { // Some self link specified CustomizeMetadata = metadata => metadata.SelfLink = selfLink, Xml = @"<link rel=""" + TestAtomConstants.AtomSelfRelationAttributeValue + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomSelfRelationAttributeValue) }, new FeedMetadataTestCase { // Non-self relation CustomizeMetadata = metadata => metadata.SelfLink = new AtomLinkMetadata { Relation = "SelF", Href = new Uri(testLinkHref) }, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_LinkRelationsMustMatch", "self", "SelF"), }, new FeedMetadataTestCase { // no next link on either OM or metadata specified CustomizeMetadata = metadata => metadata.NextPageLink = null, Xml = @"<nextlink/>", Extractor = (e) => new XElement("nextlink", e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomNextRelationAttributeValue)), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // the next link is only specified on metadata - nothing is written CustomizeMetadata = metadata => metadata.NextPageLink = new AtomLinkMetadata { Relation = "next", Href = new Uri(testLinkHref) }, Xml = @"<nextlink/>", Extractor = (e) => new XElement("nextlink", e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomNextRelationAttributeValue)), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // Next link specified only on the OM CustomizeMetadata = metadata => metadata.NextPageLink = null, CustomizePayload = feed => { feed.NextPageLink = new Uri(testLinkHref); return(new ODataItem[] { feed }); }, Xml = @"<link rel=""" + TestAtomConstants.AtomNextRelationAttributeValue + @""" href=""" + testLinkHref + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomNextRelationAttributeValue), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // Next link specified both on OM and on metadata - no conflicts CustomizeMetadata = metadata => metadata.NextPageLink = new AtomLinkMetadata { Title = testLinkTitle, HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType }, CustomizePayload = feed => { feed.NextPageLink = new Uri(testLinkHref); return(new ODataItem[] { feed }); }, Xml = @"<link rel=""" + TestAtomConstants.AtomNextRelationAttributeValue + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomNextRelationAttributeValue), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // Next link specified both on OM and on metadata - no conflicts cause values are identical CustomizeMetadata = metadata => metadata.NextPageLink = new AtomLinkMetadata { Relation = TestAtomConstants.AtomNextRelationAttributeValue, Href = new Uri(testLinkHref), Title = testLinkTitle, HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType }, CustomizePayload = feed => { feed.NextPageLink = new Uri(testLinkHref); return(new ODataItem[] { feed }); }, Xml = @"<link rel=""" + TestAtomConstants.AtomNextRelationAttributeValue + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomNextRelationAttributeValue), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // Next link specified both on OM and on metadata - conflict on relation CustomizeMetadata = metadata => metadata.NextPageLink = new AtomLinkMetadata { Relation = "Next", Title = testLinkTitle, HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType }, CustomizePayload = feed => { feed.NextPageLink = new Uri(testLinkHref); return(new ODataItem[] { feed }); }, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_LinkRelationsMustMatch", "next", "Next"), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // Next link specified both on OM and on metadata - conflict on href CustomizeMetadata = metadata => metadata.NextPageLink = new AtomLinkMetadata { Href = new Uri("http://odata.org/different"), Title = testLinkTitle, HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType }, CustomizePayload = feed => { feed.NextPageLink = new Uri(testLinkHref); return(new ODataItem[] { feed }); }, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_LinkHrefsMustMatch", testLinkHref, "http://odata.org/different"), SkipTestConfiguration = tc => tc.IsRequest }, }; this.CreateTestDescriptorsAndRunTests(testCases, WriterPayloads.FeedPayloads); }
/// <summary> /// Converts the Object Model representation of Atom metadata for entries into appropriate PayloadElement annotations /// </summary> /// <param name="entryMetadata">the Atom entry metadata, in Object Model representation, to convert</param> /// <param name="entry">the EntityInstance to annotate</param> private static void ConvertAtomEntryMetadata(AtomEntryMetadata entryMetadata, EntityInstance entry) { ExceptionUtilities.CheckArgumentNotNull(entryMetadata, "entryMetadata"); ExceptionUtilities.CheckArgumentNotNull(entry, "entry"); foreach (var author in entryMetadata.Authors) { entry.AtomAuthor(author.Name, author.Uri == null ? null : author.Uri.OriginalString, author.Email); } foreach (var category in entryMetadata.Categories) { entry.AtomCategory(category.Term, category.Scheme, category.Label); } foreach (var contributor in entryMetadata.Contributors) { entry.AtomContributor(contributor.Name, contributor.Uri == null? null : contributor.Uri.OriginalString, contributor.Email); } if (entryMetadata.EditLink != null) { AtomLinkMetadata editLink = entryMetadata.EditLink; entry.AtomEditLink(editLink.Href == null ? null : editLink.Href.OriginalString, editLink.MediaType, editLink.HrefLang, editLink.Title, ToString(editLink.Length)); } foreach (var link in entryMetadata.Links) { entry.AtomLink(link.Href == null ? null : link.Href.OriginalString, link.Relation, link.MediaType, link.HrefLang, link.Title, ToString(link.Length)); } if (entryMetadata.Published.HasValue) { entry.AtomPublished(ToString(entryMetadata.Published)); } if (entryMetadata.Rights != null) { entry.AtomRights(entryMetadata.Rights.Text, ToString(entryMetadata.Rights.Kind)); } if (entryMetadata.SelfLink != null) { AtomLinkMetadata selfLink = entryMetadata.SelfLink; entry.AtomSelfLink(selfLink.Href == null ? null : selfLink.Href.OriginalString, selfLink.MediaType, selfLink.HrefLang, selfLink.Title, ToString(selfLink.Length)); } if (entryMetadata.CategoryWithTypeName != null) { AtomCategoryMetadata categoryWithTypeName = entryMetadata.CategoryWithTypeName; entry.AtomCategoryWithTypeName(categoryWithTypeName.Term, categoryWithTypeName.Label); } if (entryMetadata.Source != null) { EntitySetInstance tempSourceFeed = new EntitySetInstance(); ConvertAtomFeedMetadata(entryMetadata.Source, tempSourceFeed); entry.AtomSource(tempSourceFeed); } if (entryMetadata.Summary != null) { entry.AtomSummary(entryMetadata.Summary.Text, ToString(entryMetadata.Summary.Kind)); } if (entryMetadata.Title != null) { entry.AtomTitle(entryMetadata.Title.Text, ToString(entryMetadata.Title.Kind)); } if (entryMetadata.Updated.HasValue) { entry.AtomUpdated(ToString(entryMetadata.Updated)); } }
internal static void AddCategoryToFeedMetadata(AtomFeedMetadata feedMetadata, AtomCategoryMetadata categoryMetadata) { if (object.ReferenceEquals(feedMetadata.Categories, EmptyCategoriesList)) { feedMetadata.Categories = new ReadOnlyEnumerable <AtomCategoryMetadata>(); } ReaderUtils.GetSourceListOfEnumerable <AtomCategoryMetadata>(feedMetadata.Categories, "Categories").Add(categoryMetadata); }
public void EntryMetadataWriterTest() { const string testPublished = "2010-10-20T20:10:00Z"; AtomTextConstruct testRights = new AtomTextConstruct { Text = "Copyright Data Fx team." }; AtomTextConstruct testSummary = new AtomTextConstruct { Text = "Test summary." }; AtomTextConstruct testTitle = new AtomTextConstruct { Text = "Test title" }; const string testUpdated = "2010-11-01T00:04:00Z"; const string testIcon = "http://odata.org/icon"; const string testSourceId = "http://odata.org/id/random"; const string testLogo = "http://odata.org/logo"; AtomTextConstruct testSubtitle = new AtomTextConstruct { Text = "Test subtitle." }; const string testAuthorName = "Test Author 1"; const string testAuthorEmail = "*****@*****.**"; const string testAuthorUri = "http://odata.org/authors/1"; var testAuthors = new AtomPersonMetadata[] { new AtomPersonMetadata() { Email = testAuthorEmail, Name = testAuthorName, Uri = new Uri(testAuthorUri) } }; var testAuthors2 = new AtomPersonMetadata[0]; const string testCategoryTerm = "Test category 1 term"; const string testCategoryLabel = "Test category 1 label"; const string testCategoryScheme = "http://odata.org/categories/1"; var testCategories = new AtomCategoryMetadata[] { new AtomCategoryMetadata() { Term = testCategoryTerm, Label = testCategoryLabel, Scheme = testCategoryScheme } }; const string testContributorName = "Test Contributor 1"; const string testContributorEmail = "*****@*****.**"; const string testContributorUri = "http://odata.org/contributors/1"; var testContributors = new AtomPersonMetadata[] { new AtomPersonMetadata() { Email = testContributorEmail, Name = testContributorName, Uri = new Uri(testContributorUri) } }; const string testGeneratorName = "Test generator"; const string testGeneratorUri = "http://odata.org/generator"; const string testGeneratorVersion = "3.0"; var testGenerator = new AtomGeneratorMetadata() { Name = testGeneratorName, Uri = new Uri(testGeneratorUri), Version = testGeneratorVersion }; const string testLinkRelation = "http://odata.org/links/1"; const string testLinkTitle = "Test link 1"; const string testLinkHref = "http://odata.org/links/1"; const string testLinkHrefLang = "de-AT"; int? testLinkLength = 999; const string testLinkMediaType = "image/png"; var testLinks = new AtomLinkMetadata[] { new AtomLinkMetadata() { Relation = testLinkRelation, Title = testLinkTitle, Href = new Uri(testLinkHref), HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType } }; AtomFeedMetadata testSource = new AtomFeedMetadata() { Authors = testAuthors, Categories = testCategories, Contributors = testContributors, Generator = testGenerator, Icon = new Uri(testIcon), SourceId = new Uri(testSourceId), Links = testLinks, Logo = new Uri(testLogo), Rights = testRights, Subtitle = testSubtitle, Title = testTitle, Updated = DateTimeOffset.Parse(testUpdated) }; Func <string, Func <XElement, XElement> > fragmentExtractor = (localName) => (e) => e.Element(TestAtomConstants.AtomXNamespace + localName); // TODO, ckerer: specify an Id via metadata if the entry does not specify one; we first have to decide what rules // we want to apply to merging of metadata and ODataLib OM data. var testCases = new[] { new { // specify an author via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Authors = testAuthors), Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name>" + testAuthorName + @"</name>", @" <uri>" + testAuthorUri + @"</uri>", @" <email>" + testAuthorEmail + @"</email>", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new { // specify an empty author array via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Authors = testAuthors2), Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name />", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new { // specify no authors via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Authors = null), Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @"$(Indent)<name />", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new { // specify a category via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Categories = testCategories), Xml = @"<category term=""" + testCategoryTerm + @""" scheme=""" + testCategoryScheme + @""" label=""" + testCategoryLabel + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @""" />", Extractor = fragmentExtractor(TestAtomConstants.AtomCategoryElementName) }, new { // specify a contributor via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Contributors = testContributors), Xml = string.Join( "$(NL)", @"<contributor xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name>" + testContributorName + @"</name>", @" <uri>" + testContributorUri + @"</uri>", @" <email>" + testContributorEmail + @"</email>", @"</contributor>"), Extractor = fragmentExtractor(TestAtomConstants.AtomContributorElementName) }, new { // specify a link via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Links = testLinks), Xml = @"<link rel=""" + testLinkRelation + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = new Func <XElement, XElement>( (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Where(l => l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value != TestAtomConstants.AtomSelfRelationAttributeValue) .Single()) }, new { // specify a published date via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Published = DateTimeOffset.Parse(testPublished)), Xml = @"<published xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testPublished + @"</published>", Extractor = fragmentExtractor(TestAtomConstants.AtomPublishedElementName) }, new { // specify rights via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Rights = testRights), Xml = @"<rights type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testRights.Text + @"</rights>", Extractor = fragmentExtractor(TestAtomConstants.AtomRightsElementName) }, new { // specify a source via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Source = testSource), Xml = string.Join( "$(NL)", @"<source xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <id>" + testSourceId + "</id>", @" <title type=""text"">" + testTitle.Text + @"</title>", @" <subtitle type=""text"">" + testSubtitle.Text + @"</subtitle>", @" <updated>" + testUpdated + @"</updated>", @" <link rel=""" + testLinkRelation + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @"""/>", @" <category term=""" + testCategoryTerm + @""" scheme=""" + testCategoryScheme + @""" label=""" + testCategoryLabel + @""" />", @" <logo>" + testLogo + @"</logo>", @" <rights type=""text"">" + testRights.Text + @"</rights>", @" <contributor>", @" <name>" + testContributorName + @"</name>", @" <uri>" + testContributorUri + @"</uri>", @" <email>" + testContributorEmail + @"</email>", @" </contributor>", @" <generator uri=""" + testGeneratorUri + @""" version=""" + testGeneratorVersion + @""">" + testGeneratorName + @"</generator>", @" <icon>" + testIcon + @"</icon>", @" <author>", @" <name>" + testAuthorName + @"</name>", @" <uri>" + testAuthorUri + @"</uri>", @" <email>" + testAuthorEmail + @"</email>", @" </author>", @"</source>"), Extractor = fragmentExtractor(TestAtomConstants.AtomSourceElementName) }, new { // specify default feed metadata as source CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Source = new AtomFeedMetadata()), Xml = string.Join( "$(NL)", @"<source xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <id />", @" <title />", @" <updated />", @"</source>"), Extractor = new Func <XElement, XElement>(result => { var source = fragmentExtractor(TestAtomConstants.AtomSourceElementName)(result); // Remove the value of updates as it can't be reliably predicted source.Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomUpdatedElementName).Nodes().Remove(); return(source); }) }, new { // specify a summary via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Summary = testSummary), Xml = @"<summary type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testSummary.Text + @"</summary>", Extractor = fragmentExtractor(TestAtomConstants.AtomSummaryElementName) }, new { // specify a title via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Title = testTitle), Xml = @"<title type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testTitle.Text + @"</title>", Extractor = fragmentExtractor(TestAtomConstants.AtomTitleElementName) }, new { // specify an updated date via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Updated = DateTimeOffset.Parse(testUpdated)), Xml = @"<updated xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testUpdated + @"</updated>", Extractor = fragmentExtractor(TestAtomConstants.AtomUpdatedElementName) }, }; // Convert test cases to test descriptions IEnumerable <Func <ODataEntry> > entryCreators = new Func <ODataEntry>[] { () => ObjectModelUtils.CreateDefaultEntry(), () => ObjectModelUtils.CreateDefaultEntryWithAtomMetadata(), }; var testDescriptors = testCases.SelectMany(testCase => entryCreators.Select(entryCreator => { ODataEntry entry = entryCreator(); AtomEntryMetadata metadata = entry.Atom(); this.Assert.IsNotNull(metadata, "Expected default entry metadata on a default entry."); testCase.CustomizeMetadata(metadata); return(new PayloadWriterTestDescriptor <ODataItem>(this.Settings, entry, testConfiguration => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.Xml, FragmentExtractor = testCase.Extractor })); })); this.CombinatorialEngineProvider.RunCombinations( testDescriptors.PayloadCases(WriterPayloads.EntryPayloads), this.WriterTestConfigurationProvider.AtomFormatConfigurations, (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger); }); }
/// <summary> /// Writes the syndication part of EPM for an entry into ATOM metadata OM. /// </summary> /// <param name="epmTargetTree">The EPM target tree to use.</param> /// <param name="epmValueCache">The entry properties value cache to use to access the properties.</param> /// <param name="resourceType">The resource type of the entry.</param> /// <param name="metadata">The metadata provider to use.</param> /// <param name="version">The version of OData protocol to use.</param> /// <returns>The ATOM metadata OM with the EPM values populated.</returns> internal static AtomEntryMetadata WriteEntryEpm( EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, ResourceType resourceType, DataServiceMetadataProviderWrapper metadata, ODataVersion version) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(epmTargetTree != null, "epmTargetTree != null"); Debug.Assert(epmValueCache != null, "epmValueCache != null"); Debug.Assert(resourceType != null, "For any EPM to exist the metadata must be available."); // If there are no syndication mappings, just return null. EpmTargetPathSegment syndicationRootSegment = epmTargetTree.SyndicationRoot; Debug.Assert(syndicationRootSegment != null, "EPM Target tree must always have syndication root."); if (syndicationRootSegment.SubSegments.Count == 0) { return(null); } AtomEntryMetadata entryMetadata = new AtomEntryMetadata(); foreach (EpmTargetPathSegment targetSegment in syndicationRootSegment.SubSegments) { if (targetSegment.IsMultiValueProperty) { Debug.Assert( targetSegment.EpmInfo != null && targetSegment.EpmInfo.Attribute != null, "MultiValue property target segment must have EpmInfo and the Epm Attribute."); ODataVersionChecker.CheckMultiValueProperties(version, targetSegment.EpmInfo.Attribute.SourcePath); // WriteMultiValueEpm(entry, targetSegment, epmValueCache); throw new NotImplementedException(); } else if (targetSegment.HasContent) { EntityPropertyMappingInfo epmInfo = targetSegment.EpmInfo; Debug.Assert( epmInfo != null && epmInfo.Attribute != null, "If the segment has content it must have EpmInfo which in turn must have the Epm attribute"); bool nullOnParentProperty; object propertyValue = epmInfo.ReadEntryPropertyValue(epmValueCache, resourceType, metadata, out nullOnParentProperty); string textPropertyValue = EpmWriterUtils.GetPropertyValueAsText(propertyValue); switch (epmInfo.Attribute.TargetSyndicationItem) { case SyndicationItemProperty.Updated: entryMetadata.Updated = CreateDateTimeValue(propertyValue, SyndicationItemProperty.Updated, version); break; case SyndicationItemProperty.Published: entryMetadata.Published = CreateDateTimeValue(propertyValue, SyndicationItemProperty.Published, version); break; case SyndicationItemProperty.Rights: entryMetadata.Rights = CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind, version); break; case SyndicationItemProperty.Summary: entryMetadata.Summary = CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind, version); break; case SyndicationItemProperty.Title: entryMetadata.Title = CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind, version); break; default: throw new ODataException(Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteEntryEpm_ContentTarget)); } } else if (targetSegment.SegmentName == AtomConstants.AtomAuthorElementName) { AtomPersonMetadata authorMetadata = WritePersonEpm(targetSegment, epmValueCache, resourceType, metadata); Debug.Assert(entryMetadata.Authors == null, "Found two mappings to author, that is invalid."); if (authorMetadata != null) { entryMetadata.Authors = CreateSinglePersonList(authorMetadata); } } else if (targetSegment.SegmentName == AtomConstants.AtomContributorElementName) { AtomPersonMetadata contributorMetadata = WritePersonEpm(targetSegment, epmValueCache, resourceType, metadata); Debug.Assert(entryMetadata.Contributors == null, "Found two mappings to contributor, that is invalid."); if (contributorMetadata != null) { entryMetadata.Contributors = CreateSinglePersonList(contributorMetadata); } } else if (targetSegment.SegmentName == AtomConstants.AtomLinkElementName) { AtomLinkMetadata linkMetadata = new AtomLinkMetadata(); //// WriteLinkEpm(entry, targetSegment, epmValueCache); Debug.Assert(targetSegment.CriteriaValue != null, "Mapping to link must be conditional."); linkMetadata.Relation = targetSegment.CriteriaValue; List <AtomLinkMetadata> links; if (entryMetadata.Links == null) { links = new List <AtomLinkMetadata>(); entryMetadata.Links = links; } else { links = entryMetadata.Links as List <AtomLinkMetadata>; Debug.Assert(links != null, "AtomEntryMetadata.Links must be of type List<AtomLinkMetadata> since we create it like that."); } links.Add(linkMetadata); throw new NotImplementedException(); } else if (targetSegment.SegmentName == AtomConstants.AtomCategoryElementName) { AtomCategoryMetadata categoryMetadata = new AtomCategoryMetadata(); //// WriteCategoryEpm(entry, targetSegment, epmValueCache) Debug.Assert(targetSegment.CriteriaValue != null, "Mapping to category must be conditional."); categoryMetadata.Scheme = targetSegment.CriteriaValue; List <AtomCategoryMetadata> categories; if (entryMetadata.Categories == null) { categories = new List <AtomCategoryMetadata>(); entryMetadata.Categories = categories; } else { categories = entryMetadata.Links as List <AtomCategoryMetadata>; Debug.Assert(categories != null, "AtomEntryMetadata.Categories must be of type List<AtomCategoryMetadata> since we create it like that."); } categories.Add(categoryMetadata); throw new NotImplementedException(); } else { throw new ODataException(Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteEntryEpm_TargetSegment)); } } return(entryMetadata); }
private static AtomFeedMetadata CreateFeedMetadata(IEnumerable <XmlTreeAnnotation> children, ODataFeed feed) { AtomFeedMetadata metadata = null; foreach (XmlTreeAnnotation epmTree in children) { if (epmTree.NamespaceName == TestAtomConstants.AtomNamespace) { if (metadata == null) { metadata = new AtomFeedMetadata(); } string localName = epmTree.LocalName; if (localName == TestAtomConstants.AtomAuthorElementName) { AtomPersonMetadata author = CreateAuthorMetadata(epmTree.Children); List <AtomPersonMetadata> authors; if (metadata.Authors == null) { authors = new List <AtomPersonMetadata>(); metadata.Authors = authors; } else { authors = (List <AtomPersonMetadata>)metadata.Authors; } authors.Add(author); } else if (localName == TestAtomConstants.AtomCategoryElementName) { AtomCategoryMetadata category = CreateCategoryMetadata(epmTree.Children); List <AtomCategoryMetadata> categories; if (metadata.Categories == null) { categories = new List <AtomCategoryMetadata>(); metadata.Categories = categories; } else { categories = (List <AtomCategoryMetadata>)metadata.Categories; } categories.Add(category); } else if (localName == TestAtomConstants.AtomContributorElementName) { AtomPersonMetadata contributor = CreateAuthorMetadata(epmTree.Children); List <AtomPersonMetadata> contributors; if (metadata.Contributors == null) { contributors = new List <AtomPersonMetadata>(); metadata.Contributors = contributors; } else { contributors = (List <AtomPersonMetadata>)metadata.Contributors; } contributors.Add(contributor); } else if (localName == TestAtomConstants.AtomGeneratorElementName) { metadata.Generator = CreateGeneratorMetadata(epmTree); } else if (localName == TestAtomConstants.AtomIconElementName) { metadata.Icon = string.IsNullOrEmpty(epmTree.PropertyValue) ? null : new Uri(epmTree.PropertyValue); } else if (localName == TestAtomConstants.AtomIdElementName) { Debug.Assert(!epmTree.IsAttribute); Uri id = string.IsNullOrEmpty(epmTree.PropertyValue) ? null : new Uri(epmTree.PropertyValue, UriKind.Absolute); if (feed == null) { // we are creating the metadata for an entry's 'source' metadata; // we don't have a feed to store the Id on so it has to go into metadata metadata.SourceId = id; } else { feed.Id = id; } } else if (localName == TestAtomConstants.AtomLinkElementName) { AtomLinkMetadata link = CreateLinkMetadata(epmTree.Children); List <AtomLinkMetadata> links; if (metadata.Links == null) { links = new List <AtomLinkMetadata>(); metadata.Links = links; } else { links = (List <AtomLinkMetadata>)metadata.Contributors; } links.Add(link); } else if (localName == TestAtomConstants.AtomLogoElementName) { metadata.Logo = string.IsNullOrEmpty(epmTree.PropertyValue) ? null : new Uri(epmTree.PropertyValue); } else if (localName == TestAtomConstants.AtomRightsElementName) { AtomTextConstructKind atomConstructKind = GetAtomConstructKind(epmTree.Children); metadata.Rights = new AtomTextConstruct { Kind = atomConstructKind, Text = epmTree.PropertyValue }; } else if (localName == TestAtomConstants.AtomSubtitleElementName) { AtomTextConstructKind atomConstructKind = GetAtomConstructKind(epmTree.Children); metadata.Subtitle = new AtomTextConstruct { Kind = atomConstructKind, Text = epmTree.PropertyValue }; } else if (localName == TestAtomConstants.AtomTitleElementName) { AtomTextConstructKind atomConstructKind = GetAtomConstructKind(epmTree.Children); metadata.Title = new AtomTextConstruct { Kind = atomConstructKind, Text = epmTree.PropertyValue }; } else if (localName == TestAtomConstants.AtomUpdatedElementName) { Debug.Assert(!epmTree.IsAttribute); metadata.Updated = string.IsNullOrEmpty(epmTree.PropertyValue) ? (DateTimeOffset?)null : DateTimeOffset.Parse(epmTree.PropertyValue); } else { throw new NotSupportedException("Unsupported atom metadata found!"); } } } return(metadata); }
/// <summary> /// Visits an ATOM category metadata. /// </summary> /// <param name="atomCategoryMetadata">The category metadata to visit.</param> protected virtual void VisitAtomCategoryMetadata(AtomCategoryMetadata atomCategoryMetadata) { }
/// <summary> /// Visits an ATOM metadata object. /// </summary> /// <param name="atomMetadata"></param> protected virtual void VisitAtomMetadata(object atomMetadata) { if (atomMetadata == null) { return; } AtomCategoryMetadata atomCategoryMetadata = atomMetadata as AtomCategoryMetadata; if (atomCategoryMetadata != null) { this.VisitAtomCategoryMetadata(atomCategoryMetadata); return; } AtomEntryMetadata atomEntryMetadata = atomMetadata as AtomEntryMetadata; if (atomEntryMetadata != null) { this.VisitAtomEntryMetadata(atomEntryMetadata); return; } AtomFeedMetadata atomFeedMetadata = atomMetadata as AtomFeedMetadata; if (atomFeedMetadata != null) { this.VisitAtomFeedMetadata(atomFeedMetadata); return; } AtomGeneratorMetadata atomGeneratorMetadata = atomMetadata as AtomGeneratorMetadata; if (atomGeneratorMetadata != null) { this.VisitAtomGeneratorMetadata(atomGeneratorMetadata); return; } AtomLinkMetadata atomLinkMetadata = atomMetadata as AtomLinkMetadata; if (atomLinkMetadata != null) { this.VisitAtomLinkMetadata(atomLinkMetadata); return; } AtomPersonMetadata atomPersonMetadata = atomMetadata as AtomPersonMetadata; if (atomPersonMetadata != null) { this.VisitAtomPersonMetadata(atomPersonMetadata); return; } AtomResourceCollectionMetadata atomResourceCollectionMetadata = atomMetadata as AtomResourceCollectionMetadata; if (atomResourceCollectionMetadata != null) { this.VisitAtomResourceCollectionMetadata(atomResourceCollectionMetadata); return; } AtomStreamReferenceMetadata atomStreamReferenceMetadata = atomMetadata as AtomStreamReferenceMetadata; if (atomStreamReferenceMetadata != null) { this.VisitAtomStreamReferenceMetadata(atomStreamReferenceMetadata); return; } AtomTextConstruct atomTextConstruct = atomMetadata as AtomTextConstruct; if (atomTextConstruct != null) { this.VisitAtomTextConstruct(atomTextConstruct); return; } AtomWorkspaceMetadata atomWorkspaceMetadata = atomMetadata as AtomWorkspaceMetadata; if (atomWorkspaceMetadata != null) { this.VisitAtomWorkspaceMetadata(atomWorkspaceMetadata); return; } AtomCategoriesMetadata atomCategoriesMetadata = atomMetadata as AtomCategoriesMetadata; if (atomCategoriesMetadata != null) { this.VisitAtomCategoriesMetadata(atomCategoriesMetadata); return; } ExceptionUtilities.Assert(false, "Unrecognized ATOM metadata object {0} of type {1}.", atomMetadata.ToString(), atomMetadata.GetType().ToString()); }
/// <summary> /// Adds a new category to feed metadata. /// </summary> /// <param name="feedMetadata">The feed metadata to add the category to.</param> /// <param name="categoryMetadata">The category metadata to add.</param> internal static void AddCategoryToFeedMetadata(AtomFeedMetadata feedMetadata, AtomCategoryMetadata categoryMetadata) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(feedMetadata != null, "feedMetadata != null"); Debug.Assert(categoryMetadata != null, "categoryMetadata != null"); if (object.ReferenceEquals(feedMetadata.Categories, EmptyCategoriesList)) { feedMetadata.Categories = new ReadOnlyEnumerable <AtomCategoryMetadata>(); } ReaderUtils.GetSourceListOfEnumerable(feedMetadata.Categories, "Categories").Add(categoryMetadata); }
/// <summary> /// Writes the syndication part of EPM for an entry into ATOM metadata OM. /// </summary> /// <param name="epmTargetTree">The EPM target tree to use.</param> /// <param name="epmValueCache">The entry properties value cache to use to access the properties.</param> /// <param name="resourceType">The resource type of the entry.</param> /// <param name="metadata">The metadata provider to use.</param> /// <param name="version">The version of OData protocol to use.</param> /// <returns>The ATOM metadata OM with the EPM values populated.</returns> internal static AtomEntryMetadata WriteEntryEpm( EpmTargetTree epmTargetTree, EntryPropertiesValueCache epmValueCache, ResourceType resourceType, DataServiceMetadataProviderWrapper metadata, ODataVersion version) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(epmTargetTree != null, "epmTargetTree != null"); Debug.Assert(epmValueCache != null, "epmValueCache != null"); Debug.Assert(resourceType != null, "For any EPM to exist the metadata must be available."); // If there are no syndication mappings, just return null. EpmTargetPathSegment syndicationRootSegment = epmTargetTree.SyndicationRoot; Debug.Assert(syndicationRootSegment != null, "EPM Target tree must always have syndication root."); if (syndicationRootSegment.SubSegments.Count == 0) { return null; } AtomEntryMetadata entryMetadata = new AtomEntryMetadata(); foreach (EpmTargetPathSegment targetSegment in syndicationRootSegment.SubSegments) { if (targetSegment.IsMultiValueProperty) { Debug.Assert( targetSegment.EpmInfo != null && targetSegment.EpmInfo.Attribute != null, "MultiValue property target segment must have EpmInfo and the Epm Attribute."); ODataVersionChecker.CheckMultiValueProperties(version, targetSegment.EpmInfo.Attribute.SourcePath); // WriteMultiValueEpm(entry, targetSegment, epmValueCache); throw new NotImplementedException(); } else if (targetSegment.HasContent) { EntityPropertyMappingInfo epmInfo = targetSegment.EpmInfo; Debug.Assert( epmInfo != null && epmInfo.Attribute != null, "If the segment has content it must have EpmInfo which in turn must have the Epm attribute"); bool nullOnParentProperty; object propertyValue = epmInfo.ReadEntryPropertyValue(epmValueCache, resourceType, metadata, out nullOnParentProperty); string textPropertyValue = EpmWriterUtils.GetPropertyValueAsText(propertyValue); switch (epmInfo.Attribute.TargetSyndicationItem) { case SyndicationItemProperty.Updated: entryMetadata.Updated = CreateDateTimeValue(propertyValue, SyndicationItemProperty.Updated, version); break; case SyndicationItemProperty.Published: entryMetadata.Published = CreateDateTimeValue(propertyValue, SyndicationItemProperty.Published, version); break; case SyndicationItemProperty.Rights: entryMetadata.Rights = CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind, version); break; case SyndicationItemProperty.Summary: entryMetadata.Summary = CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind, version); break; case SyndicationItemProperty.Title: entryMetadata.Title = CreateAtomTextConstruct(textPropertyValue, epmInfo.Attribute.TargetTextContentKind, version); break; default: throw new ODataException(Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteEntryEpm_ContentTarget)); } } else if (targetSegment.SegmentName == AtomConstants.AtomAuthorElementName) { AtomPersonMetadata authorMetadata = WritePersonEpm(targetSegment, epmValueCache, resourceType, metadata); Debug.Assert(entryMetadata.Authors == null, "Found two mappings to author, that is invalid."); if (authorMetadata != null) { entryMetadata.Authors = CreateSinglePersonList(authorMetadata); } } else if (targetSegment.SegmentName == AtomConstants.AtomContributorElementName) { AtomPersonMetadata contributorMetadata = WritePersonEpm(targetSegment, epmValueCache, resourceType, metadata); Debug.Assert(entryMetadata.Contributors == null, "Found two mappings to contributor, that is invalid."); if (contributorMetadata != null) { entryMetadata.Contributors = CreateSinglePersonList(contributorMetadata); } } else if (targetSegment.SegmentName == AtomConstants.AtomLinkElementName) { AtomLinkMetadata linkMetadata = new AtomLinkMetadata(); //// WriteLinkEpm(entry, targetSegment, epmValueCache); Debug.Assert(targetSegment.CriteriaValue != null, "Mapping to link must be conditional."); linkMetadata.Relation = targetSegment.CriteriaValue; List<AtomLinkMetadata> links; if (entryMetadata.Links == null) { links = new List<AtomLinkMetadata>(); entryMetadata.Links = links; } else { links = entryMetadata.Links as List<AtomLinkMetadata>; Debug.Assert(links != null, "AtomEntryMetadata.Links must be of type List<AtomLinkMetadata> since we create it like that."); } links.Add(linkMetadata); throw new NotImplementedException(); } else if (targetSegment.SegmentName == AtomConstants.AtomCategoryElementName) { AtomCategoryMetadata categoryMetadata = new AtomCategoryMetadata(); //// WriteCategoryEpm(entry, targetSegment, epmValueCache) Debug.Assert(targetSegment.CriteriaValue != null, "Mapping to category must be conditional."); categoryMetadata.Scheme = targetSegment.CriteriaValue; List<AtomCategoryMetadata> categories; if (entryMetadata.Categories == null) { categories = new List<AtomCategoryMetadata>(); entryMetadata.Categories = categories; } else { categories = entryMetadata.Links as List<AtomCategoryMetadata>; Debug.Assert(categories != null, "AtomEntryMetadata.Categories must be of type List<AtomCategoryMetadata> since we create it like that."); } categories.Add(categoryMetadata); throw new NotImplementedException(); } else { throw new ODataException(Strings.General_InternalError(InternalErrorCodes.EpmSyndicationWriter_WriteEntryEpm_TargetSegment)); } } return entryMetadata; }