1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
|
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Channels
{
using System.Runtime;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Xml;
public abstract class AddressHeader
{
ParameterHeader header;
protected AddressHeader()
{
}
internal bool IsReferenceProperty
{
get
{
BufferedAddressHeader bah = this as BufferedAddressHeader;
return bah != null && bah.IsReferencePropertyHeader;
}
}
public abstract string Name { get; }
public abstract string Namespace { get; }
public static AddressHeader CreateAddressHeader(object value)
{
Type type = GetObjectType(value);
return CreateAddressHeader(value, DataContractSerializerDefaults.CreateSerializer(type, int.MaxValue/*maxItems*/));
}
public static AddressHeader CreateAddressHeader(object value, XmlObjectSerializer serializer)
{
if (serializer == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serializer"));
return new XmlObjectSerializerAddressHeader(value, serializer);
}
public static AddressHeader CreateAddressHeader(string name, string ns, object value)
{
return CreateAddressHeader(name, ns, value, DataContractSerializerDefaults.CreateSerializer(GetObjectType(value), name, ns, int.MaxValue/*maxItems*/));
}
internal static AddressHeader CreateAddressHeader(XmlDictionaryString name, XmlDictionaryString ns, object value)
{
return new DictionaryAddressHeader(name, ns, value);
}
public static AddressHeader CreateAddressHeader(string name, string ns, object value, XmlObjectSerializer serializer)
{
if (serializer == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serializer"));
return new XmlObjectSerializerAddressHeader(name, ns, value, serializer);
}
static Type GetObjectType(object value)
{
return (value == null) ? typeof(object) : value.GetType();
}
public override bool Equals(object obj)
{
AddressHeader hdr = obj as AddressHeader;
if (hdr == null)
return false;
StringBuilder builder = new StringBuilder();
string hdr1 = GetComparableForm(builder);
builder.Remove(0, builder.Length);
string hdr2 = hdr.GetComparableForm(builder);
if (hdr1.Length != hdr2.Length)
return false;
if (string.CompareOrdinal(hdr1, hdr2) != 0)
return false;
return true;
}
internal string GetComparableForm()
{
return GetComparableForm(new StringBuilder());
}
internal string GetComparableForm(StringBuilder builder)
{
return EndpointAddressProcessor.GetComparableForm(builder, GetComparableReader());
}
public override int GetHashCode()
{
return GetComparableForm().GetHashCode();
}
public T GetValue<T>()
{
return GetValue<T>(DataContractSerializerDefaults.CreateSerializer(typeof(T), this.Name, this.Namespace, int.MaxValue/*maxItems*/));
}
public T GetValue<T>(XmlObjectSerializer serializer)
{
if (serializer == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serializer"));
using (XmlDictionaryReader reader = GetAddressHeaderReader())
{
if (serializer.IsStartObject(reader))
return (T)serializer.ReadObject(reader);
else
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ExpectedElementMissing, Name, Namespace)));
}
}
public virtual XmlDictionaryReader GetAddressHeaderReader()
{
XmlBuffer buffer = new XmlBuffer(int.MaxValue);
XmlDictionaryWriter writer = buffer.OpenSection(XmlDictionaryReaderQuotas.Max);
WriteAddressHeader(writer);
buffer.CloseSection();
buffer.Close();
return buffer.GetReader(0);
}
XmlDictionaryReader GetComparableReader()
{
XmlBuffer buffer = new XmlBuffer(int.MaxValue);
XmlDictionaryWriter writer = buffer.OpenSection(XmlDictionaryReaderQuotas.Max);
// WSAddressingAugust2004 does not write the IsReferenceParameter attribute,
// and that's good for a consistent comparable form
ParameterHeader.WriteStartHeader(writer, this, AddressingVersion.WSAddressingAugust2004);
ParameterHeader.WriteHeaderContents(writer, this);
writer.WriteEndElement();
buffer.CloseSection();
buffer.Close();
return buffer.GetReader(0);
}
protected virtual void OnWriteStartAddressHeader(XmlDictionaryWriter writer)
{
writer.WriteStartElement(Name, Namespace);
}
protected abstract void OnWriteAddressHeaderContents(XmlDictionaryWriter writer);
public MessageHeader ToMessageHeader()
{
if (header == null)
header = new ParameterHeader(this);
return header;
}
public void WriteAddressHeader(XmlWriter writer)
{
WriteAddressHeader(XmlDictionaryWriter.CreateDictionaryWriter(writer));
}
public void WriteAddressHeader(XmlDictionaryWriter writer)
{
if (writer == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
WriteStartAddressHeader(writer);
WriteAddressHeaderContents(writer);
writer.WriteEndElement();
}
public void WriteStartAddressHeader(XmlDictionaryWriter writer)
{
if (writer == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
OnWriteStartAddressHeader(writer);
}
public void WriteAddressHeaderContents(XmlDictionaryWriter writer)
{
if (writer == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
OnWriteAddressHeaderContents(writer);
}
class ParameterHeader : MessageHeader
{
AddressHeader parameter;
public override bool IsReferenceParameter
{
get { return true; }
}
public override string Name
{
get { return parameter.Name; }
}
public override string Namespace
{
get { return parameter.Namespace; }
}
public ParameterHeader(AddressHeader parameter)
{
this.parameter = parameter;
}
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
if (messageVersion == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("messageVersion"));
WriteStartHeader(writer, parameter, messageVersion.Addressing);
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
WriteHeaderContents(writer, parameter);
}
internal static void WriteStartHeader(XmlDictionaryWriter writer, AddressHeader parameter, AddressingVersion addressingVersion)
{
parameter.WriteStartAddressHeader(writer);
if (addressingVersion == AddressingVersion.WSAddressing10)
{
writer.WriteAttributeString(XD.AddressingDictionary.IsReferenceParameter, XD.Addressing10Dictionary.Namespace, "true");
}
}
internal static void WriteHeaderContents(XmlDictionaryWriter writer, AddressHeader parameter)
{
parameter.WriteAddressHeaderContents(writer);
}
}
class XmlObjectSerializerAddressHeader : AddressHeader
{
XmlObjectSerializer serializer;
object objectToSerialize;
string name;
string ns;
public XmlObjectSerializerAddressHeader(object objectToSerialize, XmlObjectSerializer serializer)
{
this.serializer = serializer;
this.objectToSerialize = objectToSerialize;
Type type = (objectToSerialize == null) ? typeof(object) : objectToSerialize.GetType();
XmlQualifiedName rootName = new XsdDataContractExporter().GetRootElementName(type);
this.name = rootName.Name;
this.ns = rootName.Namespace;
}
public XmlObjectSerializerAddressHeader(string name, string ns, object objectToSerialize, XmlObjectSerializer serializer)
{
if ((null == name) || (name.Length == 0))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("name"));
}
this.serializer = serializer;
this.objectToSerialize = objectToSerialize;
this.name = name;
this.ns = ns;
}
public override string Name
{
get { return name; }
}
public override string Namespace
{
get { return ns; }
}
object ThisLock
{
get { return this; }
}
protected override void OnWriteAddressHeaderContents(XmlDictionaryWriter writer)
{
lock (ThisLock)
{
serializer.WriteObjectContent(writer, objectToSerialize);
}
}
}
// [....], This will be kept internal for now. If the optimization needs to be public, we'll re-evaluate it.
class DictionaryAddressHeader : XmlObjectSerializerAddressHeader
{
XmlDictionaryString name;
XmlDictionaryString ns;
public DictionaryAddressHeader(XmlDictionaryString name, XmlDictionaryString ns, object value)
: base(name.Value, ns.Value, value, DataContractSerializerDefaults.CreateSerializer(GetObjectType(value), name, ns, int.MaxValue/*maxItems*/))
{
this.name = name;
this.ns = ns;
}
protected override void OnWriteStartAddressHeader(XmlDictionaryWriter writer)
{
writer.WriteStartElement(name, ns);
}
}
}
class BufferedAddressHeader : AddressHeader
{
string name;
string ns;
XmlBuffer buffer;
bool isReferenceProperty;
public BufferedAddressHeader(XmlDictionaryReader reader)
{
buffer = new XmlBuffer(int.MaxValue);
XmlDictionaryWriter writer = buffer.OpenSection(reader.Quotas);
Fx.Assert(reader.NodeType == XmlNodeType.Element, "");
name = reader.LocalName;
ns = reader.NamespaceURI;
Fx.Assert(name != null, "");
Fx.Assert(ns != null, "");
writer.WriteNode(reader, false);
buffer.CloseSection();
buffer.Close();
this.isReferenceProperty = false;
}
public BufferedAddressHeader(XmlDictionaryReader reader, bool isReferenceProperty)
: this(reader)
{
this.isReferenceProperty = isReferenceProperty;
}
public bool IsReferencePropertyHeader { get { return this.isReferenceProperty; } }
public override string Name
{
get { return name; }
}
public override string Namespace
{
get { return ns; }
}
public override XmlDictionaryReader GetAddressHeaderReader()
{
return buffer.GetReader(0);
}
protected override void OnWriteStartAddressHeader(XmlDictionaryWriter writer)
{
XmlDictionaryReader reader = GetAddressHeaderReader();
writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
writer.WriteAttributes(reader, false);
reader.Close();
}
protected override void OnWriteAddressHeaderContents(XmlDictionaryWriter writer)
{
XmlDictionaryReader reader = GetAddressHeaderReader();
reader.ReadStartElement();
while (reader.NodeType != XmlNodeType.EndElement)
writer.WriteNode(reader, false);
reader.ReadEndElement();
reader.Close();
}
}
}
|