Merge pull request #757 from mlintner/master
[mono.git] / mcs / class / System.ServiceModel.Web / System.ServiceModel.Syndication / AtomPub10ServiceDocumentFormatter.cs
1 //
2 // AtomPub10ServiceDocumentFormatter.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2009 Novell, Inc.  http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.ServiceModel;
32 using System.ServiceModel.Channels;
33 using System.Xml;
34 using System.Xml.Schema;
35 using System.Xml.Serialization;
36
37 namespace System.ServiceModel.Syndication
38 {
39         class Namespaces
40         {
41                 public const string Xml = "http://www.w3.org/XML/1998/namespace";
42                 public const string Xmlns = "http://www.w3.org/2000/xmlns/";
43                 public const string AtomPP = "http://www.w3.org/2007/app";
44                 public const string Atom10 = "http://www.w3.org/2005/Atom";
45         }
46
47         [XmlRoot ("service", Namespace = Namespaces.AtomPP)]
48         public class AtomPub10ServiceDocumentFormatter : ServiceDocumentFormatter, IXmlSerializable
49         {
50                 public AtomPub10ServiceDocumentFormatter ()
51                 {
52                 }
53
54                 public AtomPub10ServiceDocumentFormatter (ServiceDocument documentToWrite)
55                         : base (documentToWrite)
56                 {
57                 }
58
59                 public AtomPub10ServiceDocumentFormatter (Type documentTypeToCreate)
60                 {
61                         doc_type = documentTypeToCreate;
62                 }
63
64                 Type doc_type;
65
66                 public override string Version {
67                         get { return Namespaces.AtomPP; }
68                 }
69
70                 public override bool CanRead (XmlReader reader)
71                 {
72                         if (reader == null)
73                                 throw new ArgumentNullException ("reader");
74                         reader.MoveToContent ();
75                         return reader.LocalName == "service" && reader.NamespaceURI == Version;
76                 }
77
78                 protected override ServiceDocument CreateDocumentInstance ()
79                 {
80                         var doc = doc_type != null ? (ServiceDocument) Activator.CreateInstance (doc_type, new object [0]) : base.CreateDocumentInstance ();
81                         doc.InternalFormatter = this;
82                         return doc;
83                 }
84
85                 public override void ReadFrom (XmlReader reader)
86                 {
87                         if (!Document.TryParseElement (reader, Version))
88                                 throw new XmlException (String.Format ("Unexpected element '{0}' in namespace '{1}'", reader.LocalName, reader.NamespaceURI));
89                 }
90
91                 public override void WriteTo (XmlWriter writer)
92                 {
93                         if (writer == null)
94                                 throw new ArgumentNullException ("writer");
95
96                         writer.WriteStartElement ("app", "service", Version);
97
98                         WriteContentTo (writer);
99
100                         writer.WriteEndElement ();
101                 }
102                 
103                 void WriteContentTo (XmlWriter writer)
104                 {
105                         if (writer.LookupPrefix (Namespaces.Atom10) == null)
106                                 writer.WriteAttributeString ("xmlns", "a10", Namespaces.Xmlns, Namespaces.Atom10);
107                         if (writer.LookupPrefix (Version) == null)
108                                 writer.WriteAttributeString ("xmlns", "app", Namespaces.Xmlns, Version);
109
110                         // xml:lang, xml:base, workspace*
111                         if (Document.Language != null)
112                                 writer.WriteAttributeString ("xml", "lang", Namespaces.Xml, Document.Language);
113                         if (Document.BaseUri != null)
114                                 writer.WriteAttributeString ("xml", "base", Namespaces.Xml, Document.BaseUri.ToString ());
115
116                         Document.WriteAttributeExtensions (writer, Version);
117                         Document.WriteElementExtensions (writer, Version);
118
119                         foreach (var ws in Document.Workspaces) {
120                                 writer.WriteStartElement ("app", "workspace", Version);
121
122                                 // xml:base, title, collection*
123                                 if (ws.BaseUri != null)
124                                         writer.WriteAttributeString ("xml", "base", Namespaces.Xml, ws.BaseUri.ToString ());
125
126                                 ws.WriteAttributeExtensions (writer, Version);
127                                 ws.WriteElementExtensions (writer, Version);
128
129                                 if (ws.Title != null)
130                                         ws.Title.WriteTo (writer, "title", Namespaces.Atom10);
131                                 foreach (var rc in ws.Collections) {
132                                         writer.WriteStartElement ("app", "collection", Version);
133
134                                         // accept*, xml:base, category, @href, title
135                                         if (rc.BaseUri != null)
136                                                 writer.WriteAttributeString ("xml", "base", Namespaces.Xml, rc.BaseUri.ToString ());
137                                         if (rc.Link != null)
138                                                 writer.WriteAttributeString ("href", rc.Link.ToString ());
139
140                                         rc.WriteAttributeExtensions (writer, Version);
141
142                                         if (rc.Title != null)
143                                                 rc.Title.WriteTo (writer, "title", Namespaces.Atom10);
144                                         foreach (var s in rc.Accepts) {
145                                                 writer.WriteStartElement ("app", "accept", Version);
146                                                 writer.WriteString (s);
147                                                 writer.WriteEndElement ();
148                                         }
149                                         foreach (var cat in rc.Categories)
150                                                 cat.Save (writer);
151
152                                         writer.WriteEndElement ();
153                                 }
154                                 writer.WriteEndElement ();
155                         }
156                 }
157
158                 XmlSchema IXmlSerializable.GetSchema ()
159                 {
160                         return null;
161                 }
162
163                 void IXmlSerializable.ReadXml (XmlReader reader)
164                 {
165                         ReadFrom (reader);
166                 }
167
168                 void IXmlSerializable.WriteXml (XmlWriter writer)
169                 {
170                         WriteContentTo (writer);
171                 }
172         }
173 }