//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOAuth.Messaging.Reflection { using System; using System.Collections.Generic; using System.Net.Security; using System.Reflection; internal class MessagePart { private static readonly Dictionary converters = new Dictionary(); private ValueMapping converter; private PropertyInfo property; private FieldInfo field; static MessagePart() { Map(uri => uri.AbsoluteUri, str => new Uri(str)); } internal MessagePart(MemberInfo member, MessagePartAttribute attribute) { if (member == null) { throw new ArgumentNullException("member"); } this.field = member as FieldInfo; this.property = member as PropertyInfo; if (this.field == null && this.property == null) { throw new ArgumentOutOfRangeException("member"); // TODO: add descriptive message } if (attribute == null) { throw new ArgumentNullException("attribute"); } this.Name = attribute.Name ?? member.Name; this.Signed = attribute.Signed; this.IsRequired = !attribute.Optional; if (!converters.TryGetValue(member.DeclaringType, out this.converter)) { Type memberDeclaredType = (this.field != null) ? this.field.FieldType : this.property.PropertyType; this.converter = new ValueMapping( obj => obj != null ? obj.ToString() : null, str => str != null ? Convert.ChangeType(str, memberDeclaredType) : null); } } internal string Name { get; set; } internal ProtectionLevel Signed { get; set; } internal bool IsRequired { get; set; } internal object ToValue(string value) { return this.converter.StringToValue(value); } internal string ToString(object value) { return this.converter.ValueToString(value); } internal void SetValue(IProtocolMessage message, string value) { if (this.property != null) { this.property.SetValue(message, this.ToValue(value), null); } else { this.field.SetValue(message, this.ToValue(value)); } } internal string GetValue(IProtocolMessage message) { if (this.property != null) { return this.ToString(this.property.GetValue(message, null)); } else { return this.ToString(this.field.GetValue(message)); } } private static void Map(Func toString, Func toValue) where T : class { converters.Add( typeof(T), new ValueMapping( obj => obj != null ? toString((T)obj) : null, str => str != null ? toValue(str) : null)); } } }