Merge pull request #146 from flutos/207ce0bccceec3ff7860ea986086fedb5a92d822
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Dispatcher / XmlMessagesFormatter.cs
1 //
2 // XmlMessagesFormatter.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //      Eyal Alaluf <eyala@mainsoft.com>
7 //
8 // Copyright (C) 2005-2010 Novell, Inc.  http://www.novell.com
9 // Copyright (C) 2008 Mainsoft Co. http://www.mainsoft.com
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 using System;
31 using System.Collections.Generic;
32 using System.Linq;
33 using System.Reflection;
34 using System.Runtime.Serialization;
35 using System.ServiceModel;
36 using System.ServiceModel.Channels;
37 using System.ServiceModel.Description;
38 using System.Text;
39 using System.Xml;
40 using System.Xml.Serialization;
41
42 namespace System.ServiceModel.Dispatcher
43 {
44         class XmlMessagesFormatter : BaseMessagesFormatter
45         {
46                 XmlSerializerFormatAttribute attr;
47                 Dictionary<MessageBodyDescription,XmlSerializer> bodySerializers
48                         = new Dictionary<MessageBodyDescription,XmlSerializer> ();
49
50                 public XmlMessagesFormatter (OperationDescription desc, XmlSerializerFormatAttribute attr)
51                         : base (desc)
52                 {
53                         this.attr = attr;
54                 }
55
56                 public XmlMessagesFormatter (MessageDescriptionCollection messages, XmlSerializerFormatAttribute attr)
57                         : base (messages)
58                 {
59                         this.attr = attr;
60                 }
61
62                 private XmlReflectionMember CreateReflectionMember (MessagePartDescription partDesc, bool isReturnValue)
63                 {
64                         XmlReflectionMember m = new XmlReflectionMember ();
65                         m.IsReturnValue = isReturnValue;
66                         m.MemberName = partDesc.Name;
67                         m.MemberType = partDesc.Type;
68                         m.XmlAttributes = new XmlAttributes(partDesc.MemberInfo);
69                         return m;
70                 }
71
72                 protected override Message PartsToMessage (
73                         MessageDescription md, MessageVersion version, string action, object [] parts)
74                 {
75                         return Message.CreateMessage (version, action, new XmlBodyWriter (GetSerializer (md.Body), parts));
76                 }
77
78                 protected override object [] MessageToParts (MessageDescription md, Message message)
79                 {
80                         if (message.IsEmpty)
81                                 return null;
82                                 
83                         XmlDictionaryReader r = message.GetReaderAtBodyContents ();
84                         return (object []) GetSerializer (md.Body).Deserialize (r);
85                 }
86
87                 protected override Dictionary<MessageHeaderDescription,object> MessageToHeaderObjects (MessageDescription md, Message message)
88                 {
89                         // FIXME: do we need header serializers?
90                         return null;
91                 }
92
93                 XmlSerializer GetSerializer (MessageBodyDescription desc)
94                 {
95                         if (bodySerializers.ContainsKey (desc))
96                                 return bodySerializers [desc];
97
98                         int count = desc.Parts.Count + (HasReturnValue (desc) ? 1 : 0);
99                         XmlReflectionMember [] members = new XmlReflectionMember [count];
100
101                         int ind = 0;
102                         if (HasReturnValue (desc))
103                                 members [ind++] = CreateReflectionMember (desc.ReturnValue, true);
104
105                         foreach (MessagePartDescription partDesc in desc.Parts)
106                                 members [ind++] = CreateReflectionMember (partDesc, false);
107
108                         XmlReflectionImporter xmlImporter = new XmlReflectionImporter ();
109                         // Register known types into xmlImporter.
110                         foreach (var type in OperationKnownTypes)
111                                 xmlImporter.IncludeType (type);
112                         XmlMembersMapping [] partsMapping = new XmlMembersMapping [1];
113                         partsMapping [0] = xmlImporter.ImportMembersMapping (desc.WrapperName, desc.WrapperNamespace, members, true);
114                         bodySerializers [desc] = XmlSerializer.FromMappings (partsMapping) [0];
115                         return bodySerializers [desc];
116                 }
117
118                 class XmlBodyWriter : BodyWriter
119                 {
120                         XmlSerializer serializer;
121                         object body;
122
123                         public XmlBodyWriter (XmlSerializer serializer, object parts)
124                                 : base (false)
125                         {
126                                 this.serializer = serializer;
127                                 this.body = parts;
128                         }
129
130                         protected override BodyWriter OnCreateBufferedCopy (int maxBufferSize)
131                         {
132                                 return new XmlBodyWriter (serializer, body);
133                         }
134
135                         protected override void OnWriteBodyContents (XmlDictionaryWriter writer)
136                         {
137                                 serializer.Serialize (writer, body);
138                         }
139                 }
140         }
141 }