|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime;
using Microsoft.Xml;
namespace System.ServiceModel.Channels
{
internal abstract class AddressingHeader : DictionaryHeader, IMessageHeaderWithSharedNamespace
{
private AddressingVersion _version;
protected AddressingHeader(AddressingVersion version)
{
_version = version;
}
internal AddressingVersion Version
{
get { return _version; }
}
XmlDictionaryString IMessageHeaderWithSharedNamespace.SharedPrefix
{
get { return XD.AddressingDictionary.Prefix; }
}
XmlDictionaryString IMessageHeaderWithSharedNamespace.SharedNamespace
{
get { return _version.DictionaryNamespace; }
}
public override XmlDictionaryString DictionaryNamespace
{
get { return _version.DictionaryNamespace; }
}
}
internal class ActionHeader : AddressingHeader
{
private string _action;
private const bool mustUnderstandValue = true;
private ActionHeader(string action, AddressingVersion version)
: base(version)
{
_action = action;
}
public string Action
{
get { return _action; }
}
public override bool MustUnderstand
{
get { return mustUnderstandValue; }
}
public override XmlDictionaryString DictionaryName
{
get { return XD.AddressingDictionary.Action; }
}
public static ActionHeader Create(string action, AddressingVersion addressingVersion)
{
if (action == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("action"));
if (addressingVersion == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion");
return new ActionHeader(action, addressingVersion);
}
public static ActionHeader Create(XmlDictionaryString dictionaryAction, AddressingVersion addressingVersion)
{
if (dictionaryAction == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("action"));
if (addressingVersion == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion");
return new DictionaryActionHeader(dictionaryAction, addressingVersion);
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteString(_action);
}
public static string ReadHeaderValue(XmlDictionaryReader reader, AddressingVersion addressingVersion)
{
Fx.Assert(reader.IsStartElement(XD.AddressingDictionary.Action, addressingVersion.DictionaryNamespace), "");
string act = reader.ReadElementContentAsString();
if (act.Length > 0 && (act[0] <= 32 || act[act.Length - 1] <= 32))
act = XmlUtil.Trim(act);
return act;
}
public static ActionHeader ReadHeader(XmlDictionaryReader reader, AddressingVersion version,
string actor, bool mustUnderstand, bool relay)
{
string action = ReadHeaderValue(reader, version);
if (actor.Length == 0 && mustUnderstand == mustUnderstandValue && !relay)
{
return new ActionHeader(action, version);
}
else
{
return new FullActionHeader(action, actor, mustUnderstand, relay, version);
}
}
internal class DictionaryActionHeader : ActionHeader
{
private XmlDictionaryString _dictionaryAction;
public DictionaryActionHeader(XmlDictionaryString dictionaryAction, AddressingVersion version)
: base(dictionaryAction.Value, version)
{
_dictionaryAction = dictionaryAction;
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteString(_dictionaryAction);
}
}
internal class FullActionHeader : ActionHeader
{
private string _actor;
private bool _mustUnderstand;
private bool _relay;
public FullActionHeader(string action, string actor, bool mustUnderstand, bool relay, AddressingVersion version)
: base(action, version)
{
_actor = actor;
_mustUnderstand = mustUnderstand;
_relay = relay;
}
public override string Actor
{
get { return _actor; }
}
public override bool MustUnderstand
{
get { return _mustUnderstand; }
}
public override bool Relay
{
get { return _relay; }
}
}
}
internal class FromHeader : AddressingHeader
{
private EndpointAddress _from;
private const bool mustUnderstandValue = false;
private FromHeader(EndpointAddress from, AddressingVersion version)
: base(version)
{
_from = from;
}
public EndpointAddress From
{
get { return _from; }
}
public override XmlDictionaryString DictionaryName
{
get { return XD.AddressingDictionary.From; }
}
public override bool MustUnderstand
{
get { return mustUnderstandValue; }
}
public static FromHeader Create(EndpointAddress from, AddressingVersion addressingVersion)
{
if (from == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("from"));
if (addressingVersion == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion");
return new FromHeader(from, addressingVersion);
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
_from.WriteContentsTo(this.Version, writer);
}
public static FromHeader ReadHeader(XmlDictionaryReader reader, AddressingVersion version,
string actor, bool mustUnderstand, bool relay)
{
EndpointAddress from = ReadHeaderValue(reader, version);
if (actor.Length == 0 && mustUnderstand == mustUnderstandValue && !relay)
{
return new FromHeader(from, version);
}
else
{
return new FullFromHeader(from, actor, mustUnderstand, relay, version);
}
}
public static EndpointAddress ReadHeaderValue(XmlDictionaryReader reader, AddressingVersion addressingVersion)
{
Fx.Assert(reader.IsStartElement(XD.AddressingDictionary.From, addressingVersion.DictionaryNamespace), "");
return EndpointAddress.ReadFrom(addressingVersion, reader);
}
internal class FullFromHeader : FromHeader
{
private string _actor;
private bool _mustUnderstand;
private bool _relay;
public FullFromHeader(EndpointAddress from, string actor, bool mustUnderstand, bool relay, AddressingVersion version)
: base(from, version)
{
_actor = actor;
_mustUnderstand = mustUnderstand;
_relay = relay;
}
public override string Actor
{
get { return _actor; }
}
public override bool MustUnderstand
{
get { return _mustUnderstand; }
}
public override bool Relay
{
get { return _relay; }
}
}
}
internal class FaultToHeader : AddressingHeader
{
private EndpointAddress _faultTo;
private const bool mustUnderstandValue = false;
private FaultToHeader(EndpointAddress faultTo, AddressingVersion version)
: base(version)
{
_faultTo = faultTo;
}
public EndpointAddress FaultTo
{
get { return _faultTo; }
}
public override XmlDictionaryString DictionaryName
{
get { return XD.AddressingDictionary.FaultTo; }
}
public override bool MustUnderstand
{
get { return mustUnderstandValue; }
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
_faultTo.WriteContentsTo(this.Version, writer);
}
public static FaultToHeader Create(EndpointAddress faultTo, AddressingVersion addressingVersion)
{
if (faultTo == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("faultTo"));
if (addressingVersion == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion");
return new FaultToHeader(faultTo, addressingVersion);
}
public static FaultToHeader ReadHeader(XmlDictionaryReader reader, AddressingVersion version,
string actor, bool mustUnderstand, bool relay)
{
EndpointAddress faultTo = ReadHeaderValue(reader, version);
if (actor.Length == 0 && mustUnderstand == mustUnderstandValue && !relay)
{
return new FaultToHeader(faultTo, version);
}
else
{
return new FullFaultToHeader(faultTo, actor, mustUnderstand, relay, version);
}
}
public static EndpointAddress ReadHeaderValue(XmlDictionaryReader reader, AddressingVersion version)
{
Fx.Assert(reader.IsStartElement(XD.AddressingDictionary.FaultTo, version.DictionaryNamespace), "");
return EndpointAddress.ReadFrom(version, reader);
}
internal class FullFaultToHeader : FaultToHeader
{
private string _actor;
private bool _mustUnderstand;
private bool _relay;
public FullFaultToHeader(EndpointAddress faultTo, string actor, bool mustUnderstand, bool relay, AddressingVersion version)
: base(faultTo, version)
{
_actor = actor;
_mustUnderstand = mustUnderstand;
_relay = relay;
}
public override string Actor
{
get { return _actor; }
}
public override bool MustUnderstand
{
get { return _mustUnderstand; }
}
public override bool Relay
{
get { return _relay; }
}
}
}
internal class ToHeader : AddressingHeader
{
private Uri _to;
private const bool mustUnderstandValue = true;
private static ToHeader s_anonymousToHeader10;
protected ToHeader(Uri to, AddressingVersion version)
: base(version)
{
_to = to;
}
private static ToHeader AnonymousTo10
{
get
{
if (s_anonymousToHeader10 == null)
s_anonymousToHeader10 = new AnonymousToHeader(AddressingVersion.WSAddressing10);
return s_anonymousToHeader10;
}
}
public override XmlDictionaryString DictionaryName
{
get { return XD.AddressingDictionary.To; }
}
public override bool MustUnderstand
{
get { return mustUnderstandValue; }
}
public Uri To
{
get { return _to; }
}
public static ToHeader Create(Uri toUri, XmlDictionaryString dictionaryTo, AddressingVersion addressingVersion)
{
if (addressingVersion == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion");
if (((object)toUri == (object)addressingVersion.AnonymousUri))
{
if (addressingVersion == AddressingVersion.WSAddressing10)
return AnonymousTo10;
else
// Verify that only WSA10 is supported
throw ExceptionHelper.PlatformNotSupported();
}
else
{
return new DictionaryToHeader(toUri, dictionaryTo, addressingVersion);
}
}
public static ToHeader Create(Uri to, AddressingVersion addressingVersion)
{
if ((object)to == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("to"));
}
else if ((object)to == (object)addressingVersion.AnonymousUri)
{
if (addressingVersion == AddressingVersion.WSAddressing10)
return AnonymousTo10;
else
// Verify that only WSA10 is supported
throw ExceptionHelper.PlatformNotSupported();
}
else
{
return new ToHeader(to, addressingVersion);
}
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteString(_to.AbsoluteUri);
}
public static Uri ReadHeaderValue(XmlDictionaryReader reader, AddressingVersion version)
{
return ReadHeaderValue(reader, version, null);
}
public static Uri ReadHeaderValue(XmlDictionaryReader reader, AddressingVersion version, UriCache uriCache)
{
Fx.Assert(reader.IsStartElement(XD.AddressingDictionary.To, version.DictionaryNamespace), "");
string toString = reader.ReadElementContentAsString();
if ((object)toString == (object)version.Anonymous)
{
return version.AnonymousUri;
}
if (uriCache == null)
{
return new Uri(toString);
}
return uriCache.CreateUri(toString);
}
public static ToHeader ReadHeader(XmlDictionaryReader reader, AddressingVersion version, UriCache uriCache,
string actor, bool mustUnderstand, bool relay)
{
Uri to = ReadHeaderValue(reader, version, uriCache);
if (actor.Length == 0 && mustUnderstand == mustUnderstandValue && !relay)
{
if ((object)to == (object)version.Anonymous)
{
if (version == AddressingVersion.WSAddressing10)
return AnonymousTo10;
else
throw ExceptionHelper.PlatformNotSupported();
}
else
{
return new ToHeader(to, version);
}
}
else
{
return new FullToHeader(to, actor, mustUnderstand, relay, version);
}
}
private class AnonymousToHeader : ToHeader
{
public AnonymousToHeader(AddressingVersion version)
: base(version.AnonymousUri, version)
{
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteString(this.Version.DictionaryAnonymous);
}
}
internal class DictionaryToHeader : ToHeader
{
private XmlDictionaryString _dictionaryTo;
public DictionaryToHeader(Uri to, XmlDictionaryString dictionaryTo, AddressingVersion version)
: base(to, version)
{
_dictionaryTo = dictionaryTo;
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteString(_dictionaryTo);
}
}
internal class FullToHeader : ToHeader
{
private string _actor;
private bool _mustUnderstand;
private bool _relay;
public FullToHeader(Uri to, string actor, bool mustUnderstand, bool relay, AddressingVersion version)
: base(to, version)
{
_actor = actor;
_mustUnderstand = mustUnderstand;
_relay = relay;
}
public override string Actor
{
get { return _actor; }
}
public override bool MustUnderstand
{
get { return _mustUnderstand; }
}
public override bool Relay
{
get { return _relay; }
}
}
}
internal class ReplyToHeader : AddressingHeader
{
private EndpointAddress _replyTo;
private const bool mustUnderstandValue = false;
private static ReplyToHeader s_anonymousReplyToHeader10;
private ReplyToHeader(EndpointAddress replyTo, AddressingVersion version)
: base(version)
{
_replyTo = replyTo;
}
public EndpointAddress ReplyTo
{
get { return _replyTo; }
}
public override XmlDictionaryString DictionaryName
{
get { return XD.AddressingDictionary.ReplyTo; }
}
public override bool MustUnderstand
{
get { return mustUnderstandValue; }
}
public static ReplyToHeader AnonymousReplyTo10
{
get
{
if (s_anonymousReplyToHeader10 == null)
s_anonymousReplyToHeader10 = new ReplyToHeader(EndpointAddress.AnonymousAddress, AddressingVersion.WSAddressing10);
return s_anonymousReplyToHeader10;
}
}
public static ReplyToHeader Create(EndpointAddress replyTo, AddressingVersion addressingVersion)
{
if (replyTo == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("replyTo"));
if (addressingVersion == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("addressingVersion"));
return new ReplyToHeader(replyTo, addressingVersion);
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
_replyTo.WriteContentsTo(this.Version, writer);
}
public static ReplyToHeader ReadHeader(XmlDictionaryReader reader, AddressingVersion version,
string actor, bool mustUnderstand, bool relay)
{
EndpointAddress replyTo = ReadHeaderValue(reader, version);
if (actor.Length == 0 && mustUnderstand == mustUnderstandValue && !relay)
{
if ((object)replyTo == (object)EndpointAddress.AnonymousAddress)
{
if (version == AddressingVersion.WSAddressing10)
return AnonymousReplyTo10;
else
// Verify that only WSA10 is supported
throw ExceptionHelper.PlatformNotSupported();
}
return new ReplyToHeader(replyTo, version);
}
else
{
return new FullReplyToHeader(replyTo, actor, mustUnderstand, relay, version);
}
}
public static EndpointAddress ReadHeaderValue(XmlDictionaryReader reader, AddressingVersion version)
{
Fx.Assert(reader.IsStartElement(XD.AddressingDictionary.ReplyTo, version.DictionaryNamespace), "");
return EndpointAddress.ReadFrom(version, reader);
}
internal class FullReplyToHeader : ReplyToHeader
{
private string _actor;
private bool _mustUnderstand;
private bool _relay;
public FullReplyToHeader(EndpointAddress replyTo, string actor, bool mustUnderstand, bool relay, AddressingVersion version)
: base(replyTo, version)
{
_actor = actor;
_mustUnderstand = mustUnderstand;
_relay = relay;
}
public override string Actor
{
get { return _actor; }
}
public override bool MustUnderstand
{
get { return _mustUnderstand; }
}
public override bool Relay
{
get { return _relay; }
}
}
}
internal class MessageIDHeader : AddressingHeader
{
private UniqueId _messageId;
private const bool mustUnderstandValue = false;
private MessageIDHeader(UniqueId messageId, AddressingVersion version)
: base(version)
{
_messageId = messageId;
}
public override XmlDictionaryString DictionaryName
{
get { return XD.AddressingDictionary.MessageId; }
}
public UniqueId MessageId
{
get { return _messageId; }
}
public override bool MustUnderstand
{
get { return mustUnderstandValue; }
}
public static MessageIDHeader Create(UniqueId messageId, AddressingVersion addressingVersion)
{
if (object.ReferenceEquals(messageId, null))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("messageId"));
if (addressingVersion == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("addressingVersion"));
return new MessageIDHeader(messageId, addressingVersion);
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteValue(_messageId);
}
public static UniqueId ReadHeaderValue(XmlDictionaryReader reader, AddressingVersion version)
{
Fx.Assert(reader.IsStartElement(XD.AddressingDictionary.MessageId, version.DictionaryNamespace), "");
return reader.ReadElementContentAsUniqueId();
}
public static MessageIDHeader ReadHeader(XmlDictionaryReader reader, AddressingVersion version,
string actor, bool mustUnderstand, bool relay)
{
UniqueId messageId = ReadHeaderValue(reader, version);
if (actor.Length == 0 && mustUnderstand == mustUnderstandValue && !relay)
{
return new MessageIDHeader(messageId, version);
}
else
{
return new FullMessageIDHeader(messageId, actor, mustUnderstand, relay, version);
}
}
internal class FullMessageIDHeader : MessageIDHeader
{
private string _actor;
private bool _mustUnderstand;
private bool _relay;
public FullMessageIDHeader(UniqueId messageId, string actor, bool mustUnderstand, bool relay, AddressingVersion version)
: base(messageId, version)
{
_actor = actor;
_mustUnderstand = mustUnderstand;
_relay = relay;
}
public override string Actor
{
get { return _actor; }
}
public override bool MustUnderstand
{
get { return _mustUnderstand; }
}
public override bool Relay
{
get { return _relay; }
}
}
}
internal class RelatesToHeader : AddressingHeader
{
private UniqueId _messageId;
private const bool mustUnderstandValue = false;
internal static readonly Uri ReplyRelationshipType = new Uri(Addressing10Strings.ReplyRelationship);
private RelatesToHeader(UniqueId messageId, AddressingVersion version)
: base(version)
{
_messageId = messageId;
}
public override XmlDictionaryString DictionaryName
{
get { return XD.AddressingDictionary.RelatesTo; }
}
public UniqueId UniqueId
{
get { return _messageId; }
}
public override bool MustUnderstand
{
get { return mustUnderstandValue; }
}
public virtual Uri RelationshipType
{
get { return ReplyRelationshipType; }
}
public static RelatesToHeader Create(UniqueId messageId, AddressingVersion addressingVersion)
{
if (object.ReferenceEquals(messageId, null))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("messageId"));
if (addressingVersion == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("addressingVersion"));
return new RelatesToHeader(messageId, addressingVersion);
}
public static RelatesToHeader Create(UniqueId messageId, AddressingVersion addressingVersion, Uri relationshipType)
{
if (object.ReferenceEquals(messageId, null))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("messageId"));
if (addressingVersion == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("addressingVersion"));
if (relationshipType == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("relationshipType"));
if (relationshipType == ReplyRelationshipType)
{
return new RelatesToHeader(messageId, addressingVersion);
}
else
{
return new FullRelatesToHeader(messageId, "", false, false, addressingVersion);
}
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteValue(_messageId);
}
public static void ReadHeaderValue(XmlDictionaryReader reader, AddressingVersion version, out Uri relationshipType, out UniqueId messageId)
{
AddressingDictionary addressingDictionary = XD.AddressingDictionary;
// The RelationshipType attribute has no namespace.
relationshipType = ReplyRelationshipType;
/*
string relation = reader.GetAttribute(addressingDictionary.RelationshipType, addressingDictionary.Empty);
if (relation == null)
{
relationshipType = ReplyRelationshipType;
}
else
{
relationshipType = new Uri(relation);
}
*/
Fx.Assert(reader.IsStartElement(addressingDictionary.RelatesTo, version.DictionaryNamespace), "");
messageId = reader.ReadElementContentAsUniqueId();
}
public static RelatesToHeader ReadHeader(XmlDictionaryReader reader, AddressingVersion version,
string actor, bool mustUnderstand, bool relay)
{
UniqueId messageId;
Uri relationship;
ReadHeaderValue(reader, version, out relationship, out messageId);
if (actor.Length == 0 && mustUnderstand == mustUnderstandValue && !relay && (object)relationship == (object)ReplyRelationshipType)
{
return new RelatesToHeader(messageId, version);
}
else
{
return new FullRelatesToHeader(messageId, actor, mustUnderstand, relay, version);
}
}
internal class FullRelatesToHeader : RelatesToHeader
{
private string _actor;
private bool _mustUnderstand;
private bool _relay;
//Uri relationship;
public FullRelatesToHeader(UniqueId messageId, string actor, bool mustUnderstand, bool relay, AddressingVersion version)
: base(messageId, version)
{
//this.relationship = relationship;
_actor = actor;
_mustUnderstand = mustUnderstand;
_relay = relay;
}
public override string Actor
{
get { return _actor; }
}
public override bool MustUnderstand
{
get { return _mustUnderstand; }
}
/*
public override Uri RelationshipType
{
get { return relationship; }
}
*/
public override bool Relay
{
get { return _relay; }
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
/*
if ((object)relationship != (object)ReplyRelationshipType)
{
// The RelationshipType attribute has no namespace.
writer.WriteStartAttribute(AddressingStrings.RelationshipType, AddressingStrings.Empty);
writer.WriteString(relationship.AbsoluteUri);
writer.WriteEndAttribute();
}
*/
writer.WriteValue(_messageId);
}
}
}
}
|