Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mcs / class / System.ServiceModel.Web / System.ServiceModel.Syndication / ServiceDocument.cs
1 //
2 // ServiceDocument.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.Collections.ObjectModel;
31 using System.IO;
32 using System.ServiceModel;
33 using System.ServiceModel.Channels;
34 using System.Xml;
35
36 namespace System.ServiceModel.Syndication
37 {
38         public class ServiceDocument
39         {
40                 public static TServiceDocument Load<TServiceDocument> (XmlReader reader)
41                         where TServiceDocument : ServiceDocument, new()
42                 {
43                         var doc = new TServiceDocument ();
44                         new AtomPub10ServiceDocumentFormatter<TServiceDocument> (doc).ReadFrom (reader);
45                         return doc;
46                 }
47
48                 public static ServiceDocument Load (XmlReader reader)
49                 {
50                         return Load<ServiceDocument> (reader);
51                 }
52
53
54                 public ServiceDocument ()
55                 {
56                         Workspaces = new Collection<Workspace> ();
57                 }
58
59                 public ServiceDocument (IEnumerable<Workspace> workspaces)
60                         : this ()
61                 {
62                         if (workspaces != null)
63                                 foreach (var w in workspaces)
64                                         Workspaces.Add (w);
65                 }
66
67                 ServiceDocumentFormatter formatter;
68                 SyndicationExtensions extensions = new SyndicationExtensions ();
69
70                 internal ServiceDocumentFormatter InternalFormatter {
71                         set { formatter = value; }
72                 }
73
74                 public Dictionary<XmlQualifiedName, string> AttributeExtensions {
75                         get { return extensions.Attributes; }
76                 }
77
78                 public Uri BaseUri { get; set; }
79
80                 public SyndicationElementExtensionCollection ElementExtensions {
81                         get { return extensions.Elements; }
82                 }
83
84                 public string Language { get; set; }
85
86                 public Collection<Workspace> Workspaces { get; private set; }
87
88
89                 protected internal virtual Workspace CreateWorkspace ()
90                 {
91                         return new Workspace ();
92                 }
93
94                 public ServiceDocumentFormatter GetFormatter ()
95                 {
96                         if (formatter == null)
97                                 formatter = new AtomPub10ServiceDocumentFormatter (this);
98                         return formatter;
99                 }
100
101                 public void Save (XmlWriter writer)
102                 {
103                         GetFormatter ().WriteTo (writer);
104                 }
105
106                 protected internal virtual bool TryParseAttribute (string name, string ns, string value, string version)
107                 {
108                         if (version != "http://www.w3.org/2007/app")
109                                 return false;
110
111                         switch (ns) {
112                         case "http://www.w3.org/XML/1998/namespace":
113                                 switch (name) {
114                                 case "base":
115                                         BaseUri = new Uri (value, UriKind.RelativeOrAbsolute);
116                                         return true;
117                                 case "lang":
118                                         Language = value;
119                                         return true;
120                                 }
121                                 return false;
122                         }
123                         return false;
124                 }
125
126                 protected internal virtual bool TryParseElement (XmlReader reader, string version)
127                 {
128                         if (reader == null)
129                                 throw new ArgumentNullException ("reader");
130
131                         reader.MoveToContent ();
132
133                         if (reader.LocalName != "service" || reader.NamespaceURI != version)
134                                 return false;
135
136                         for (int i = 0; i < reader.AttributeCount; i++) {
137                                 reader.MoveToAttribute (i);
138                                 if (!TryParseAttribute (reader.LocalName, reader.NamespaceURI, reader.Value, version))
139                                         AttributeExtensions.Add (new XmlQualifiedName (reader.LocalName, reader.NamespaceURI), reader.Value);
140                         }
141                         reader.MoveToElement ();
142
143                         if (reader.IsEmptyElement)
144                                 throw new XmlException ("AtomPP service element requires at least one workspace element");
145
146                         reader.ReadStartElement ();
147
148                         for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) {
149                                 if (reader.LocalName == "workspace" && reader.NamespaceURI == version) {
150                                         var ws = CreateWorkspace ();
151                                         if (ws.TryParseElement (reader, version)) {
152                                                 Workspaces.Add (ws);
153                                                 continue;
154                                         }
155                                 }
156                                 ElementExtensions.Add (new SyndicationElementExtension (reader));
157                         }
158
159                         reader.ReadEndElement ();
160
161                         return true;
162                 }
163
164                 protected internal virtual void WriteAttributeExtensions (XmlWriter writer, string version)
165                 {
166                         extensions.WriteAttributeExtensions (writer, version);
167                 }
168
169                 protected internal virtual void WriteElementExtensions (XmlWriter writer, string version)
170                 {
171                         extensions.WriteElementExtensions (writer, version);
172                 }
173         }
174 }