1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 5 namespace System.ServiceModel.Syndication 6 { 7 using System.Collections.ObjectModel; 8 using System.Runtime.Serialization; 9 using System.Xml.Serialization; 10 using System.Collections.Generic; 11 using System.Xml; 12 using System.Xml.Schema; 13 using System.ServiceModel.Channels; 14 using System.ServiceModel.Diagnostics; 15 using System.Diagnostics; 16 using System.Diagnostics.CodeAnalysis; 17 using System.Runtime.CompilerServices; 18 19 [TypeForwardedFrom("System.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")] 20 [XmlRoot(ElementName = App10Constants.Categories, Namespace = App10Constants.Namespace)] 21 public class AtomPub10CategoriesDocumentFormatter : CategoriesDocumentFormatter, IXmlSerializable 22 { 23 Type inlineDocumentType; 24 int maxExtensionSize; 25 bool preserveAttributeExtensions; 26 bool preserveElementExtensions; 27 Type referencedDocumentType; 28 AtomPub10CategoriesDocumentFormatter()29 public AtomPub10CategoriesDocumentFormatter() 30 : this(typeof(InlineCategoriesDocument), typeof(ReferencedCategoriesDocument)) 31 { 32 } 33 AtomPub10CategoriesDocumentFormatter(Type inlineDocumentType, Type referencedDocumentType)34 public AtomPub10CategoriesDocumentFormatter(Type inlineDocumentType, Type referencedDocumentType) 35 : base() 36 { 37 if (inlineDocumentType == null) 38 { 39 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inlineDocumentType"); 40 } 41 if (!typeof(InlineCategoriesDocument).IsAssignableFrom(inlineDocumentType)) 42 { 43 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("inlineDocumentType", 44 SR.GetString(SR.InvalidObjectTypePassed, "inlineDocumentType", "InlineCategoriesDocument")); 45 } 46 if (referencedDocumentType == null) 47 { 48 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("referencedDocumentType"); 49 } 50 if (!typeof(ReferencedCategoriesDocument).IsAssignableFrom(referencedDocumentType)) 51 { 52 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("referencedDocumentType", 53 SR.GetString(SR.InvalidObjectTypePassed, "referencedDocumentType", "ReferencedCategoriesDocument")); 54 } 55 this.maxExtensionSize = int.MaxValue; 56 this.preserveAttributeExtensions = true; 57 this.preserveElementExtensions = true; 58 this.inlineDocumentType = inlineDocumentType; 59 this.referencedDocumentType = referencedDocumentType; 60 } 61 AtomPub10CategoriesDocumentFormatter(CategoriesDocument documentToWrite)62 public AtomPub10CategoriesDocumentFormatter(CategoriesDocument documentToWrite) 63 : base(documentToWrite) 64 { 65 // No need to check that the parameter passed is valid - it is checked by the c'tor of the base class 66 this.maxExtensionSize = int.MaxValue; 67 preserveAttributeExtensions = true; 68 preserveElementExtensions = true; 69 if (documentToWrite.IsInline) 70 { 71 this.inlineDocumentType = documentToWrite.GetType(); 72 this.referencedDocumentType = typeof(ReferencedCategoriesDocument); 73 } 74 else 75 { 76 this.referencedDocumentType = documentToWrite.GetType(); 77 this.inlineDocumentType = typeof(InlineCategoriesDocument); 78 } 79 } 80 81 public override string Version 82 { 83 get { return App10Constants.Namespace; } 84 } 85 CanRead(XmlReader reader)86 public override bool CanRead(XmlReader reader) 87 { 88 if (reader == null) 89 { 90 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); 91 } 92 return reader.IsStartElement(App10Constants.Categories, App10Constants.Namespace); 93 } 94 95 [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")] IXmlSerializable.GetSchema()96 XmlSchema IXmlSerializable.GetSchema() 97 { 98 return null; 99 } 100 101 [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")] IXmlSerializable.ReadXml(XmlReader reader)102 void IXmlSerializable.ReadXml(XmlReader reader) 103 { 104 if (reader == null) 105 { 106 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); 107 } 108 TraceCategoriesDocumentReadBegin(); 109 ReadDocument(reader); 110 TraceCategoriesDocumentReadEnd(); 111 } 112 113 [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")] IXmlSerializable.WriteXml(XmlWriter writer)114 void IXmlSerializable.WriteXml(XmlWriter writer) 115 { 116 if (writer == null) 117 { 118 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer"); 119 } 120 if (this.Document == null) 121 { 122 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.DocumentFormatterDoesNotHaveDocument))); 123 } 124 TraceCategoriesDocumentWriteBegin(); 125 WriteDocument(writer); 126 TraceCategoriesDocumentWriteEnd(); 127 } 128 ReadFrom(XmlReader reader)129 public override void ReadFrom(XmlReader reader) 130 { 131 if (reader == null) 132 { 133 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); 134 } 135 if (!CanRead(reader)) 136 { 137 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.UnknownDocumentXml, reader.LocalName, reader.NamespaceURI))); 138 } 139 TraceCategoriesDocumentReadBegin(); 140 ReadDocument(reader); 141 TraceCategoriesDocumentReadEnd(); 142 } 143 WriteTo(XmlWriter writer)144 public override void WriteTo(XmlWriter writer) 145 { 146 if (writer == null) 147 { 148 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer"); 149 } 150 if (this.Document == null) 151 { 152 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.DocumentFormatterDoesNotHaveDocument))); 153 } 154 TraceCategoriesDocumentWriteBegin(); 155 writer.WriteStartElement(App10Constants.Prefix, App10Constants.Categories, App10Constants.Namespace); 156 WriteDocument(writer); 157 writer.WriteEndElement(); 158 TraceCategoriesDocumentWriteEnd(); 159 } 160 TraceCategoriesDocumentReadBegin()161 internal static void TraceCategoriesDocumentReadBegin() 162 { 163 if (DiagnosticUtility.ShouldTraceInformation) 164 { 165 TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.SyndicationReadCategoriesDocumentBegin, SR.GetString(SR.TraceCodeSyndicationReadCategoriesDocumentBegin)); 166 } 167 } 168 TraceCategoriesDocumentReadEnd()169 internal static void TraceCategoriesDocumentReadEnd() 170 { 171 if (DiagnosticUtility.ShouldTraceInformation) 172 { 173 TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.SyndicationReadCategoriesDocumentEnd, SR.GetString(SR.TraceCodeSyndicationReadCategoriesDocumentEnd)); 174 } 175 } 176 TraceCategoriesDocumentWriteBegin()177 internal static void TraceCategoriesDocumentWriteBegin() 178 { 179 if (DiagnosticUtility.ShouldTraceInformation) 180 { 181 TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.SyndicationWriteCategoriesDocumentBegin, SR.GetString(SR.TraceCodeSyndicationWriteCategoriesDocumentBegin)); 182 } 183 } 184 TraceCategoriesDocumentWriteEnd()185 internal static void TraceCategoriesDocumentWriteEnd() 186 { 187 if (DiagnosticUtility.ShouldTraceInformation) 188 { 189 TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.SyndicationWriteCategoriesDocumentEnd, SR.GetString(SR.TraceCodeSyndicationWriteCategoriesDocumentEnd)); 190 } 191 } 192 CreateInlineCategoriesDocument()193 protected override InlineCategoriesDocument CreateInlineCategoriesDocument() 194 { 195 if (inlineDocumentType == typeof(InlineCategoriesDocument)) 196 { 197 return new InlineCategoriesDocument(); 198 } 199 else 200 { 201 return (InlineCategoriesDocument)Activator.CreateInstance(this.inlineDocumentType); 202 } 203 } 204 CreateReferencedCategoriesDocument()205 protected override ReferencedCategoriesDocument CreateReferencedCategoriesDocument() 206 { 207 if (referencedDocumentType == typeof(ReferencedCategoriesDocument)) 208 { 209 return new ReferencedCategoriesDocument(); 210 } 211 else 212 { 213 return (ReferencedCategoriesDocument)Activator.CreateInstance(this.referencedDocumentType); 214 } 215 } 216 ReadDocument(XmlReader reader)217 void ReadDocument(XmlReader reader) 218 { 219 try 220 { 221 SyndicationFeedFormatter.MoveToStartElement(reader); 222 SetDocument(AtomPub10ServiceDocumentFormatter.ReadCategories(reader, null, 223 delegate() 224 { 225 return this.CreateInlineCategoriesDocument(); 226 }, 227 228 delegate() 229 { 230 return this.CreateReferencedCategoriesDocument(); 231 }, 232 this.Version, 233 this.preserveElementExtensions, 234 this.preserveAttributeExtensions, 235 this.maxExtensionSize)); 236 } 237 catch (FormatException e) 238 { 239 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(FeedUtils.AddLineInfo(reader, SR.ErrorParsingDocument), e)); 240 } 241 catch (ArgumentException e) 242 { 243 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(FeedUtils.AddLineInfo(reader, SR.ErrorParsingDocument), e)); 244 } 245 } 246 WriteDocument(XmlWriter writer)247 void WriteDocument(XmlWriter writer) 248 { 249 // declare the atom10 namespace upfront for compactness 250 writer.WriteAttributeString(Atom10Constants.Atom10Prefix, Atom10FeedFormatter.XmlNsNs, Atom10Constants.Atom10Namespace); 251 AtomPub10ServiceDocumentFormatter.WriteCategoriesInnerXml(writer, this.Document, null, this.Version); 252 } 253 } 254 } 255