//-----------------------------------------------------------------------
//
// Copyright (c) Andrew Arnott. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOAuth.Messaging {
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Linq;
using DotNetOAuth.Messaging.Reflection;
///
/// Serializes/deserializes OAuth messages for/from transit.
///
internal class MessageSerializer {
///
/// The specific -derived type
/// that will be serialized and deserialized using this class.
///
private readonly Type messageType;
///
/// Initializes a new instance of the MessageSerializer class.
///
/// The specific -derived type
/// that will be serialized and deserialized using this class.
private MessageSerializer(Type messageType) {
Debug.Assert(messageType != null, "messageType == null");
if (!typeof(IProtocolMessage).IsAssignableFrom(messageType)) {
throw new ArgumentException(
string.Format(
CultureInfo.CurrentCulture,
MessagingStrings.UnexpectedType,
typeof(IProtocolMessage).FullName,
messageType.FullName),
"messageType");
}
this.messageType = messageType;
}
///
/// Creates or reuses a message serializer for a given message type.
///
/// The type of message that will be serialized/deserialized.
/// A message serializer for the given message type.
internal static MessageSerializer Get(Type messageType) {
if (messageType == null) {
throw new ArgumentNullException("messageType");
}
return new MessageSerializer(messageType);
}
///
/// Reads the data from a message instance and returns a series of name=value pairs for the fields that must be included in the message.
///
/// The message to be serialized.
/// The dictionary of values to send for the message.
internal IDictionary Serialize(IProtocolMessage message) {
if (message == null) {
throw new ArgumentNullException("message");
}
var result = new Reflection.MessageDictionary(message);
return result;
}
///
/// Reads name=value pairs into an OAuth message.
///
/// The name=value pairs that were read in from the transport.
/// The instantiated and initialized instance.
internal IProtocolMessage Deserialize(IDictionary fields) {
if (fields == null) {
throw new ArgumentNullException("fields");
}
// Before we deserialize the message, make sure all the required parts are present.
MessageDescription.Get(this.messageType).EnsureRequiredMessagePartsArePresent(fields.Keys);
IProtocolMessage result ;
try {
result = (IProtocolMessage)Activator.CreateInstance(this.messageType, true);
} catch (MissingMethodException ex) {
throw new ProtocolException("Failed to instantiate type " + this.messageType.FullName, ex);
}
foreach (var pair in fields) {
IDictionary dictionary = new MessageDictionary(result);
dictionary.Add(pair);
}
result.EnsureValidMessage();
return result;
}
}
}