e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
813 lines
36 KiB
C#
813 lines
36 KiB
C#
//------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//------------------------------------------------------------
|
|
|
|
namespace System.ServiceModel.Syndication
|
|
{
|
|
using System.Collections.ObjectModel;
|
|
using System.Runtime.Serialization;
|
|
using System.Xml.Serialization;
|
|
using System.Collections.Generic;
|
|
using System.Xml;
|
|
using System.Xml.Schema;
|
|
using System.ServiceModel.Channels;
|
|
using System.Diagnostics;
|
|
using System.ServiceModel.Diagnostics;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
internal delegate InlineCategoriesDocument CreateInlineCategoriesDelegate();
|
|
internal delegate ReferencedCategoriesDocument CreateReferencedCategoriesDelegate();
|
|
|
|
[TypeForwardedFrom("System.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")]
|
|
[XmlRoot(ElementName = App10Constants.Service, Namespace = App10Constants.Namespace)]
|
|
public class AtomPub10ServiceDocumentFormatter : ServiceDocumentFormatter, IXmlSerializable
|
|
{
|
|
Type documentType;
|
|
int maxExtensionSize;
|
|
bool preserveAttributeExtensions;
|
|
bool preserveElementExtensions;
|
|
|
|
public AtomPub10ServiceDocumentFormatter()
|
|
: this(typeof(ServiceDocument))
|
|
{
|
|
}
|
|
|
|
public AtomPub10ServiceDocumentFormatter(Type documentTypeToCreate)
|
|
: base()
|
|
{
|
|
if (documentTypeToCreate == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("documentTypeToCreate");
|
|
}
|
|
if (!typeof(ServiceDocument).IsAssignableFrom(documentTypeToCreate))
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("documentTypeToCreate",
|
|
SR.GetString(SR.InvalidObjectTypePassed, "documentTypeToCreate", "ServiceDocument"));
|
|
}
|
|
this.maxExtensionSize = int.MaxValue;
|
|
this.preserveAttributeExtensions = true;
|
|
this.preserveElementExtensions = true;
|
|
this.documentType = documentTypeToCreate;
|
|
}
|
|
|
|
public AtomPub10ServiceDocumentFormatter(ServiceDocument documentToWrite)
|
|
: base(documentToWrite)
|
|
{
|
|
// No need to check that the parameter passed is valid - it is checked by the c'tor of the base class
|
|
this.maxExtensionSize = int.MaxValue;
|
|
preserveAttributeExtensions = true;
|
|
preserveElementExtensions = true;
|
|
this.documentType = documentToWrite.GetType();
|
|
}
|
|
|
|
public override string Version
|
|
{
|
|
get { return App10Constants.Namespace; }
|
|
}
|
|
|
|
public override bool CanRead(XmlReader reader)
|
|
{
|
|
if (reader == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
|
|
}
|
|
return reader.IsStartElement(App10Constants.Service, App10Constants.Namespace);
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "The IXmlSerializable implementation is only for exposing under WCF DataContractSerializer. The funcionality is exposed to derived class through the ReadFrom\\WriteTo methods")]
|
|
XmlSchema IXmlSerializable.GetSchema()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "The IXmlSerializable implementation is only for exposing under WCF DataContractSerializer. The funcionality is exposed to derived class through the ReadFrom\\WriteTo methods")]
|
|
void IXmlSerializable.ReadXml(XmlReader reader)
|
|
{
|
|
if (reader == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
|
|
}
|
|
TraceServiceDocumentReadBegin();
|
|
ReadDocument(reader);
|
|
TraceServiceDocumentReadEnd();
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "The IXmlSerializable implementation is only for exposing under WCF DataContractSerializer. The funcionality is exposed to derived class through the ReadFrom\\WriteTo methods")]
|
|
void IXmlSerializable.WriteXml(XmlWriter writer)
|
|
{
|
|
if (writer == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
|
|
}
|
|
if (this.Document == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.DocumentFormatterDoesNotHaveDocument)));
|
|
}
|
|
TraceServiceDocumentWriteBegin();
|
|
WriteDocument(writer);
|
|
TraceServiceDocumentWriteEnd();
|
|
}
|
|
|
|
public override void ReadFrom(XmlReader reader)
|
|
{
|
|
if (reader == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
|
|
}
|
|
reader.MoveToContent();
|
|
if (!CanRead(reader))
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.UnknownDocumentXml, reader.LocalName, reader.NamespaceURI)));
|
|
}
|
|
TraceServiceDocumentReadBegin();
|
|
ReadDocument(reader);
|
|
TraceServiceDocumentReadEnd();
|
|
}
|
|
|
|
public override void WriteTo(XmlWriter writer)
|
|
{
|
|
if (writer == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
|
|
}
|
|
if (this.Document == null)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.DocumentFormatterDoesNotHaveDocument)));
|
|
}
|
|
TraceServiceDocumentWriteBegin();
|
|
writer.WriteStartElement(App10Constants.Prefix, App10Constants.Service, App10Constants.Namespace);
|
|
WriteDocument(writer);
|
|
writer.WriteEndElement();
|
|
TraceServiceDocumentWriteEnd();
|
|
}
|
|
|
|
internal static CategoriesDocument ReadCategories(XmlReader reader, Uri baseUri, CreateInlineCategoriesDelegate inlineCategoriesFactory, CreateReferencedCategoriesDelegate referencedCategoriesFactory, string version, bool preserveElementExtensions, bool preserveAttributeExtensions, int maxExtensionSize)
|
|
{
|
|
string link = reader.GetAttribute(App10Constants.Href, string.Empty);
|
|
if (string.IsNullOrEmpty(link))
|
|
{
|
|
InlineCategoriesDocument inlineCategories = inlineCategoriesFactory();
|
|
ReadInlineCategories(reader, inlineCategories, baseUri, version, preserveElementExtensions, preserveAttributeExtensions, maxExtensionSize);
|
|
return inlineCategories;
|
|
}
|
|
else
|
|
{
|
|
ReferencedCategoriesDocument referencedCategories = referencedCategoriesFactory();
|
|
ReadReferencedCategories(reader, referencedCategories, baseUri, new Uri(link, UriKind.RelativeOrAbsolute), version, preserveElementExtensions, preserveAttributeExtensions, maxExtensionSize);
|
|
return referencedCategories;
|
|
}
|
|
}
|
|
|
|
internal static void TraceServiceDocumentReadBegin()
|
|
{
|
|
if (DiagnosticUtility.ShouldTraceInformation)
|
|
{
|
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.SyndicationReadServiceDocumentBegin, SR.GetString(SR.TraceCodeSyndicationReadServiceDocumentBegin));
|
|
}
|
|
}
|
|
|
|
internal static void TraceServiceDocumentReadEnd()
|
|
{
|
|
if (DiagnosticUtility.ShouldTraceInformation)
|
|
{
|
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.SyndicationReadServiceDocumentEnd, SR.GetString(SR.TraceCodeSyndicationReadServiceDocumentEnd));
|
|
}
|
|
}
|
|
|
|
internal static void TraceServiceDocumentWriteBegin()
|
|
{
|
|
if (DiagnosticUtility.ShouldTraceInformation)
|
|
{
|
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.SyndicationWriteServiceDocumentBegin, SR.GetString(SR.TraceCodeSyndicationWriteServiceDocumentBegin));
|
|
}
|
|
}
|
|
|
|
internal static void TraceServiceDocumentWriteEnd()
|
|
{
|
|
if (DiagnosticUtility.ShouldTraceInformation)
|
|
{
|
|
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.SyndicationWriteServiceDocumentEnd, SR.GetString(SR.TraceCodeSyndicationWriteServiceDocumentEnd));
|
|
}
|
|
}
|
|
|
|
internal static void WriteCategoriesInnerXml(XmlWriter writer, CategoriesDocument categories, Uri baseUri, string version)
|
|
{
|
|
Uri baseUriToWrite = FeedUtils.GetBaseUriToWrite(baseUri, categories.BaseUri);
|
|
if (baseUriToWrite != null)
|
|
{
|
|
WriteXmlBase(writer, baseUriToWrite);
|
|
}
|
|
if (!string.IsNullOrEmpty(categories.Language))
|
|
{
|
|
WriteXmlLang(writer, categories.Language);
|
|
}
|
|
if (categories.IsInline)
|
|
{
|
|
WriteInlineCategoriesContent(writer, (InlineCategoriesDocument)categories, version);
|
|
}
|
|
else
|
|
{
|
|
WriteReferencedCategoriesContent(writer, (ReferencedCategoriesDocument)categories, version);
|
|
}
|
|
}
|
|
|
|
protected override ServiceDocument CreateDocumentInstance()
|
|
{
|
|
if (this.documentType == typeof(ServiceDocument))
|
|
{
|
|
return new ServiceDocument();
|
|
}
|
|
else
|
|
{
|
|
return (ServiceDocument)Activator.CreateInstance(this.documentType);
|
|
}
|
|
}
|
|
|
|
static void ReadInlineCategories(XmlReader reader, InlineCategoriesDocument inlineCategories, Uri baseUri, string version, bool preserveElementExtensions, bool preserveAttributeExtensions, int maxExtensionSize)
|
|
{
|
|
inlineCategories.BaseUri = baseUri;
|
|
if (reader.HasAttributes)
|
|
{
|
|
while (reader.MoveToNextAttribute())
|
|
{
|
|
if (reader.LocalName == "base" && reader.NamespaceURI == Atom10FeedFormatter.XmlNs)
|
|
{
|
|
inlineCategories.BaseUri = FeedUtils.CombineXmlBase(inlineCategories.BaseUri, reader.Value);
|
|
}
|
|
else if (reader.LocalName == "lang" && reader.NamespaceURI == Atom10FeedFormatter.XmlNs)
|
|
{
|
|
inlineCategories.Language = reader.Value;
|
|
}
|
|
else if (reader.LocalName == App10Constants.Fixed && reader.NamespaceURI == string.Empty)
|
|
{
|
|
inlineCategories.IsFixed = (reader.Value == "yes");
|
|
}
|
|
else if (reader.LocalName == Atom10Constants.SchemeTag && reader.NamespaceURI == string.Empty)
|
|
{
|
|
inlineCategories.Scheme = reader.Value;
|
|
}
|
|
else
|
|
{
|
|
string ns = reader.NamespaceURI;
|
|
string name = reader.LocalName;
|
|
if (FeedUtils.IsXmlns(name, ns) || FeedUtils.IsXmlSchemaType(name, ns))
|
|
{
|
|
continue;
|
|
}
|
|
string val = reader.Value;
|
|
if (!TryParseAttribute(name, ns, val, inlineCategories, version))
|
|
{
|
|
if (preserveAttributeExtensions)
|
|
{
|
|
inlineCategories.AttributeExtensions.Add(new XmlQualifiedName(reader.LocalName, reader.NamespaceURI), reader.Value);
|
|
}
|
|
else
|
|
{
|
|
SyndicationFeedFormatter.TraceSyndicationElementIgnoredOnRead(reader);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
SyndicationFeedFormatter.MoveToStartElement(reader);
|
|
bool isEmptyElement = reader.IsEmptyElement;
|
|
reader.ReadStartElement();
|
|
if (!isEmptyElement)
|
|
{
|
|
XmlBuffer buffer = null;
|
|
XmlDictionaryWriter extWriter = null;
|
|
try
|
|
{
|
|
while (reader.IsStartElement())
|
|
{
|
|
if (reader.IsStartElement(Atom10Constants.CategoryTag, Atom10Constants.Atom10Namespace))
|
|
{
|
|
SyndicationCategory category = CreateCategory(inlineCategories);
|
|
Atom10FeedFormatter.ReadCategory(reader, category, version, preserveAttributeExtensions, preserveElementExtensions, maxExtensionSize);
|
|
if (category.Scheme == null)
|
|
{
|
|
category.Scheme = inlineCategories.Scheme;
|
|
}
|
|
inlineCategories.Categories.Add(category);
|
|
}
|
|
else if (!TryParseElement(reader, inlineCategories, version))
|
|
{
|
|
if (preserveElementExtensions)
|
|
{
|
|
SyndicationFeedFormatter.CreateBufferIfRequiredAndWriteNode(ref buffer, ref extWriter, reader, maxExtensionSize);
|
|
}
|
|
else
|
|
{
|
|
SyndicationFeedFormatter.TraceSyndicationElementIgnoredOnRead(reader);
|
|
reader.Skip();
|
|
}
|
|
}
|
|
}
|
|
LoadElementExtensions(buffer, extWriter, inlineCategories);
|
|
}
|
|
finally
|
|
{
|
|
if (extWriter != null)
|
|
{
|
|
extWriter.Close();
|
|
}
|
|
}
|
|
reader.ReadEndElement();
|
|
}
|
|
}
|
|
|
|
static void ReadReferencedCategories(XmlReader reader, ReferencedCategoriesDocument referencedCategories, Uri baseUri, Uri link, string version, bool preserveElementExtensions, bool preserveAttributeExtensions, int maxExtensionSize)
|
|
{
|
|
referencedCategories.BaseUri = baseUri;
|
|
referencedCategories.Link = link;
|
|
if (reader.HasAttributes)
|
|
{
|
|
while (reader.MoveToNextAttribute())
|
|
{
|
|
if (reader.LocalName == "base" && reader.NamespaceURI == Atom10FeedFormatter.XmlNs)
|
|
{
|
|
referencedCategories.BaseUri = FeedUtils.CombineXmlBase(referencedCategories.BaseUri, reader.Value);
|
|
}
|
|
else if (reader.LocalName == "lang" && reader.NamespaceURI == Atom10FeedFormatter.XmlNs)
|
|
{
|
|
referencedCategories.Language = reader.Value;
|
|
}
|
|
else if (reader.LocalName == App10Constants.Href && reader.NamespaceURI == string.Empty)
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
string ns = reader.NamespaceURI;
|
|
string name = reader.LocalName;
|
|
if (FeedUtils.IsXmlns(name, ns) || FeedUtils.IsXmlSchemaType(name, ns))
|
|
{
|
|
continue;
|
|
}
|
|
string val = reader.Value;
|
|
if (!TryParseAttribute(name, ns, val, referencedCategories, version))
|
|
{
|
|
if (preserveAttributeExtensions)
|
|
{
|
|
referencedCategories.AttributeExtensions.Add(new XmlQualifiedName(reader.LocalName, reader.NamespaceURI), reader.Value);
|
|
}
|
|
else
|
|
{
|
|
SyndicationFeedFormatter.TraceSyndicationElementIgnoredOnRead(reader);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
reader.MoveToElement();
|
|
bool isEmptyElement = reader.IsEmptyElement;
|
|
reader.ReadStartElement();
|
|
if (!isEmptyElement)
|
|
{
|
|
XmlBuffer buffer = null;
|
|
XmlDictionaryWriter extWriter = null;
|
|
try
|
|
{
|
|
while (reader.IsStartElement())
|
|
{
|
|
if (!TryParseElement(reader, referencedCategories, version))
|
|
{
|
|
if (preserveElementExtensions)
|
|
{
|
|
SyndicationFeedFormatter.CreateBufferIfRequiredAndWriteNode(ref buffer, ref extWriter, reader, maxExtensionSize);
|
|
}
|
|
else
|
|
{
|
|
SyndicationFeedFormatter.TraceSyndicationElementIgnoredOnRead(reader);
|
|
reader.Skip();
|
|
}
|
|
}
|
|
}
|
|
LoadElementExtensions(buffer, extWriter, referencedCategories);
|
|
}
|
|
finally
|
|
{
|
|
if (extWriter != null)
|
|
{
|
|
extWriter.Close();
|
|
}
|
|
}
|
|
reader.ReadEndElement();
|
|
}
|
|
}
|
|
|
|
static void WriteCategories(XmlWriter writer, CategoriesDocument categories, Uri baseUri, string version)
|
|
{
|
|
writer.WriteStartElement(App10Constants.Prefix, App10Constants.Categories, App10Constants.Namespace);
|
|
WriteCategoriesInnerXml(writer, categories, baseUri, version);
|
|
writer.WriteEndElement();
|
|
}
|
|
|
|
static void WriteInlineCategoriesContent(XmlWriter writer, InlineCategoriesDocument categories, string version)
|
|
{
|
|
if (!string.IsNullOrEmpty(categories.Scheme))
|
|
{
|
|
writer.WriteAttributeString(Atom10Constants.SchemeTag, categories.Scheme);
|
|
}
|
|
// by default, categories are not fixed
|
|
if (categories.IsFixed)
|
|
{
|
|
writer.WriteAttributeString(App10Constants.Fixed, "yes");
|
|
}
|
|
WriteAttributeExtensions(writer, categories, version);
|
|
for (int i = 0; i < categories.Categories.Count; ++i)
|
|
{
|
|
Atom10FeedFormatter.WriteCategory(writer, categories.Categories[i], version);
|
|
}
|
|
WriteElementExtensions(writer, categories, version);
|
|
}
|
|
|
|
static void WriteReferencedCategoriesContent(XmlWriter writer, ReferencedCategoriesDocument categories, string version)
|
|
{
|
|
if (categories.Link != null)
|
|
{
|
|
writer.WriteAttributeString(App10Constants.Href, FeedUtils.GetUriString(categories.Link));
|
|
}
|
|
WriteAttributeExtensions(writer, categories, version);
|
|
WriteElementExtensions(writer, categories, version);
|
|
}
|
|
|
|
static void WriteXmlBase(XmlWriter writer, Uri baseUri)
|
|
{
|
|
writer.WriteAttributeString("xml", "base", Atom10FeedFormatter.XmlNs, FeedUtils.GetUriString(baseUri));
|
|
}
|
|
|
|
static void WriteXmlLang(XmlWriter writer, string lang)
|
|
{
|
|
writer.WriteAttributeString("xml", "lang", Atom10FeedFormatter.XmlNs, lang);
|
|
|
|
}
|
|
|
|
ResourceCollectionInfo ReadCollection(XmlReader reader, Workspace workspace)
|
|
{
|
|
ResourceCollectionInfo result = CreateCollection(workspace);
|
|
result.BaseUri = workspace.BaseUri;
|
|
if (reader.HasAttributes)
|
|
{
|
|
while (reader.MoveToNextAttribute())
|
|
{
|
|
if (reader.LocalName == "base" && reader.NamespaceURI == Atom10FeedFormatter.XmlNs)
|
|
{
|
|
result.BaseUri = FeedUtils.CombineXmlBase(result.BaseUri, reader.Value);
|
|
}
|
|
else if (reader.LocalName == App10Constants.Href && reader.NamespaceURI == string.Empty)
|
|
{
|
|
result.Link = new Uri(reader.Value, UriKind.RelativeOrAbsolute);
|
|
}
|
|
else
|
|
{
|
|
string ns = reader.NamespaceURI;
|
|
string name = reader.LocalName;
|
|
if (FeedUtils.IsXmlns(name, ns) || FeedUtils.IsXmlSchemaType(name, ns))
|
|
{
|
|
continue;
|
|
}
|
|
string val = reader.Value;
|
|
if (!TryParseAttribute(name, ns, val, result, this.Version))
|
|
{
|
|
if (this.preserveAttributeExtensions)
|
|
{
|
|
result.AttributeExtensions.Add(new XmlQualifiedName(reader.LocalName, reader.NamespaceURI), reader.Value);
|
|
}
|
|
else
|
|
{
|
|
SyndicationFeedFormatter.TraceSyndicationElementIgnoredOnRead(reader);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
XmlBuffer buffer = null;
|
|
XmlDictionaryWriter extWriter = null;
|
|
|
|
reader.ReadStartElement();
|
|
try
|
|
{
|
|
while (reader.IsStartElement())
|
|
{
|
|
if (reader.IsStartElement(Atom10Constants.TitleTag, Atom10Constants.Atom10Namespace))
|
|
{
|
|
result.Title = Atom10FeedFormatter.ReadTextContentFrom(reader, "//app:service/app:workspace/app:collection/atom:title[@type]", this.preserveAttributeExtensions);
|
|
}
|
|
else if (reader.IsStartElement(App10Constants.Categories, App10Constants.Namespace))
|
|
{
|
|
result.Categories.Add(ReadCategories(reader,
|
|
result.BaseUri,
|
|
delegate()
|
|
{
|
|
return CreateInlineCategories(result);
|
|
},
|
|
|
|
delegate()
|
|
{
|
|
return CreateReferencedCategories(result);
|
|
},
|
|
this.Version,
|
|
this.preserveElementExtensions,
|
|
this.preserveAttributeExtensions,
|
|
this.maxExtensionSize));
|
|
}
|
|
else if (reader.IsStartElement(App10Constants.Accept, App10Constants.Namespace))
|
|
{
|
|
result.Accepts.Add(reader.ReadElementString());
|
|
}
|
|
else if (!TryParseElement(reader, result, this.Version))
|
|
{
|
|
if (this.preserveElementExtensions)
|
|
{
|
|
SyndicationFeedFormatter.CreateBufferIfRequiredAndWriteNode(ref buffer, ref extWriter, reader, this.maxExtensionSize);
|
|
}
|
|
else
|
|
{
|
|
SyndicationFeedFormatter.TraceSyndicationElementIgnoredOnRead(reader);
|
|
reader.Skip();
|
|
}
|
|
}
|
|
}
|
|
LoadElementExtensions(buffer, extWriter, result);
|
|
}
|
|
finally
|
|
{
|
|
if (extWriter != null)
|
|
{
|
|
extWriter.Close();
|
|
}
|
|
}
|
|
reader.ReadEndElement();
|
|
return result;
|
|
}
|
|
|
|
void ReadDocument(XmlReader reader)
|
|
{
|
|
ServiceDocument result = CreateDocumentInstance();
|
|
try
|
|
{
|
|
SyndicationFeedFormatter.MoveToStartElement(reader);
|
|
bool elementIsEmpty = reader.IsEmptyElement;
|
|
if (reader.HasAttributes)
|
|
{
|
|
while (reader.MoveToNextAttribute())
|
|
{
|
|
if (reader.LocalName == "lang" && reader.NamespaceURI == Atom10FeedFormatter.XmlNs)
|
|
{
|
|
result.Language = reader.Value;
|
|
}
|
|
else if (reader.LocalName == "base" && reader.NamespaceURI == Atom10FeedFormatter.XmlNs)
|
|
{
|
|
result.BaseUri = new Uri(reader.Value, UriKind.RelativeOrAbsolute);
|
|
}
|
|
else
|
|
{
|
|
string ns = reader.NamespaceURI;
|
|
string name = reader.LocalName;
|
|
if (FeedUtils.IsXmlns(name, ns) || FeedUtils.IsXmlSchemaType(name, ns))
|
|
{
|
|
continue;
|
|
}
|
|
string val = reader.Value;
|
|
if (!TryParseAttribute(name, ns, val, result, this.Version))
|
|
{
|
|
if (this.preserveAttributeExtensions)
|
|
{
|
|
result.AttributeExtensions.Add(new XmlQualifiedName(reader.LocalName, reader.NamespaceURI), reader.Value);
|
|
}
|
|
else
|
|
{
|
|
SyndicationFeedFormatter.TraceSyndicationElementIgnoredOnRead(reader);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
XmlBuffer buffer = null;
|
|
XmlDictionaryWriter extWriter = null;
|
|
|
|
reader.ReadStartElement();
|
|
if (!elementIsEmpty)
|
|
{
|
|
try
|
|
{
|
|
while (reader.IsStartElement())
|
|
{
|
|
if (reader.IsStartElement(App10Constants.Workspace, App10Constants.Namespace))
|
|
{
|
|
result.Workspaces.Add(ReadWorkspace(reader, result));
|
|
}
|
|
else if (!TryParseElement(reader, result, this.Version))
|
|
{
|
|
if (this.preserveElementExtensions)
|
|
{
|
|
SyndicationFeedFormatter.CreateBufferIfRequiredAndWriteNode(ref buffer, ref extWriter, reader, this.maxExtensionSize);
|
|
}
|
|
else
|
|
{
|
|
SyndicationFeedFormatter.TraceSyndicationElementIgnoredOnRead(reader);
|
|
reader.Skip();
|
|
}
|
|
}
|
|
}
|
|
LoadElementExtensions(buffer, extWriter, result);
|
|
}
|
|
finally
|
|
{
|
|
if (extWriter != null)
|
|
{
|
|
extWriter.Close();
|
|
}
|
|
}
|
|
}
|
|
reader.ReadEndElement();
|
|
}
|
|
catch (FormatException e)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(FeedUtils.AddLineInfo(reader, SR.ErrorParsingDocument), e));
|
|
}
|
|
catch (ArgumentException e)
|
|
{
|
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(FeedUtils.AddLineInfo(reader, SR.ErrorParsingDocument), e));
|
|
}
|
|
SetDocument(result);
|
|
}
|
|
|
|
Workspace ReadWorkspace(XmlReader reader, ServiceDocument document)
|
|
{
|
|
Workspace result = CreateWorkspace(document);
|
|
result.BaseUri = document.BaseUri;
|
|
if (reader.HasAttributes)
|
|
{
|
|
while (reader.MoveToNextAttribute())
|
|
{
|
|
if (reader.LocalName == "base" && reader.NamespaceURI == Atom10FeedFormatter.XmlNs)
|
|
{
|
|
result.BaseUri = FeedUtils.CombineXmlBase(result.BaseUri, reader.Value);
|
|
}
|
|
else
|
|
{
|
|
string ns = reader.NamespaceURI;
|
|
string name = reader.LocalName;
|
|
if (FeedUtils.IsXmlns(name, ns) || FeedUtils.IsXmlSchemaType(name, ns))
|
|
{
|
|
continue;
|
|
}
|
|
string val = reader.Value;
|
|
if (!TryParseAttribute(name, ns, val, result, this.Version))
|
|
{
|
|
if (this.preserveAttributeExtensions)
|
|
{
|
|
result.AttributeExtensions.Add(new XmlQualifiedName(reader.LocalName, reader.NamespaceURI), reader.Value);
|
|
}
|
|
else
|
|
{
|
|
SyndicationFeedFormatter.TraceSyndicationElementIgnoredOnRead(reader);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
XmlBuffer buffer = null;
|
|
XmlDictionaryWriter extWriter = null;
|
|
|
|
reader.ReadStartElement();
|
|
try
|
|
{
|
|
while (reader.IsStartElement())
|
|
{
|
|
if (reader.IsStartElement(Atom10Constants.TitleTag, Atom10Constants.Atom10Namespace))
|
|
{
|
|
result.Title = Atom10FeedFormatter.ReadTextContentFrom(reader, "//app:service/app:workspace/atom:title[@type]", this.preserveAttributeExtensions);
|
|
}
|
|
else if (reader.IsStartElement(App10Constants.Collection, App10Constants.Namespace))
|
|
{
|
|
result.Collections.Add(ReadCollection(reader, result));
|
|
}
|
|
else if (!TryParseElement(reader, result, this.Version))
|
|
{
|
|
if (this.preserveElementExtensions)
|
|
{
|
|
SyndicationFeedFormatter.CreateBufferIfRequiredAndWriteNode(ref buffer, ref extWriter, reader, this.maxExtensionSize);
|
|
}
|
|
else
|
|
{
|
|
SyndicationFeedFormatter.TraceSyndicationElementIgnoredOnRead(reader);
|
|
reader.Skip();
|
|
}
|
|
}
|
|
}
|
|
LoadElementExtensions(buffer, extWriter, result);
|
|
}
|
|
finally
|
|
{
|
|
if (extWriter != null)
|
|
{
|
|
extWriter.Close();
|
|
}
|
|
}
|
|
reader.ReadEndElement();
|
|
return result;
|
|
}
|
|
|
|
void WriteCollection(XmlWriter writer, ResourceCollectionInfo collection, Uri baseUri)
|
|
{
|
|
writer.WriteStartElement(App10Constants.Prefix, App10Constants.Collection, App10Constants.Namespace);
|
|
Uri baseUriToWrite = FeedUtils.GetBaseUriToWrite(baseUri, collection.BaseUri);
|
|
if (baseUriToWrite != null)
|
|
{
|
|
baseUri = collection.BaseUri;
|
|
WriteXmlBase(writer, baseUriToWrite);
|
|
}
|
|
if (collection.Link != null)
|
|
{
|
|
writer.WriteAttributeString(App10Constants.Href, FeedUtils.GetUriString(collection.Link));
|
|
}
|
|
WriteAttributeExtensions(writer, collection, this.Version);
|
|
if (collection.Title != null)
|
|
{
|
|
collection.Title.WriteTo(writer, Atom10Constants.TitleTag, Atom10Constants.Atom10Namespace);
|
|
}
|
|
for (int i = 0; i < collection.Accepts.Count; ++i)
|
|
{
|
|
writer.WriteElementString(App10Constants.Prefix, App10Constants.Accept, App10Constants.Namespace, collection.Accepts[i]);
|
|
}
|
|
for (int i = 0; i < collection.Categories.Count; ++i)
|
|
{
|
|
WriteCategories(writer, collection.Categories[i], baseUri, this.Version);
|
|
}
|
|
WriteElementExtensions(writer, collection, this.Version);
|
|
writer.WriteEndElement();
|
|
}
|
|
|
|
void WriteDocument(XmlWriter writer)
|
|
{
|
|
// declare the atom10 namespace upfront for compactness
|
|
writer.WriteAttributeString(Atom10Constants.Atom10Prefix, Atom10FeedFormatter.XmlNsNs, Atom10Constants.Atom10Namespace);
|
|
if (!string.IsNullOrEmpty(this.Document.Language))
|
|
{
|
|
WriteXmlLang(writer, this.Document.Language);
|
|
}
|
|
Uri baseUri = this.Document.BaseUri;
|
|
if (baseUri != null)
|
|
{
|
|
WriteXmlBase(writer, baseUri);
|
|
}
|
|
WriteAttributeExtensions(writer, this.Document, this.Version);
|
|
|
|
for (int i = 0; i < this.Document.Workspaces.Count; ++i)
|
|
{
|
|
WriteWorkspace(writer, this.Document.Workspaces[i], baseUri);
|
|
}
|
|
WriteElementExtensions(writer, this.Document, this.Version);
|
|
}
|
|
|
|
void WriteWorkspace(XmlWriter writer, Workspace workspace, Uri baseUri)
|
|
{
|
|
writer.WriteStartElement(App10Constants.Prefix, App10Constants.Workspace, App10Constants.Namespace);
|
|
Uri baseUriToWrite = FeedUtils.GetBaseUriToWrite(baseUri, workspace.BaseUri);
|
|
if (baseUriToWrite != null)
|
|
{
|
|
baseUri = workspace.BaseUri;
|
|
WriteXmlBase(writer, baseUriToWrite);
|
|
}
|
|
WriteAttributeExtensions(writer, workspace, this.Version);
|
|
if (workspace.Title != null)
|
|
{
|
|
workspace.Title.WriteTo(writer, Atom10Constants.TitleTag, Atom10Constants.Atom10Namespace);
|
|
}
|
|
for (int i = 0; i < workspace.Collections.Count; ++i)
|
|
{
|
|
WriteCollection(writer, workspace.Collections[i], baseUri);
|
|
}
|
|
WriteElementExtensions(writer, workspace, this.Version);
|
|
writer.WriteEndElement();
|
|
}
|
|
}
|
|
|
|
[TypeForwardedFrom("System.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")]
|
|
[XmlRoot(ElementName = App10Constants.Service, Namespace = App10Constants.Namespace)]
|
|
public class AtomPub10ServiceDocumentFormatter<TServiceDocument> : AtomPub10ServiceDocumentFormatter
|
|
where TServiceDocument : ServiceDocument, new()
|
|
{
|
|
public AtomPub10ServiceDocumentFormatter() :
|
|
base(typeof(TServiceDocument))
|
|
{
|
|
}
|
|
|
|
public AtomPub10ServiceDocumentFormatter(TServiceDocument documentToWrite)
|
|
: base(documentToWrite)
|
|
{
|
|
}
|
|
|
|
protected override ServiceDocument CreateDocumentInstance()
|
|
{
|
|
return new TServiceDocument();
|
|
}
|
|
}
|
|
}
|