summaryrefslogtreecommitdiffstats
path: root/src/DotNetOAuth/Messaging/Reflection/MessageDescription.cs
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2008-09-20 19:18:00 -0700
committerAndrew <andrewarnott@gmail.com>2008-09-20 19:18:00 -0700
commitf7fa44d6001b0c104cbf209cd7455e536e02cbe9 (patch)
treef6739f0963a031b3d7155719a7dd302bab383666 /src/DotNetOAuth/Messaging/Reflection/MessageDescription.cs
parentc9304587876374c2866f44135cf24372f432a77d (diff)
parentf7326ec97ead94425cf8b22d0aea5f7bf67ebc8f (diff)
downloadDotNetOpenAuth-f7fa44d6001b0c104cbf209cd7455e536e02cbe9.zip
DotNetOpenAuth-f7fa44d6001b0c104cbf209cd7455e536e02cbe9.tar.gz
DotNetOpenAuth-f7fa44d6001b0c104cbf209cd7455e536e02cbe9.tar.bz2
Merge branch 'sersync'
Diffstat (limited to 'src/DotNetOAuth/Messaging/Reflection/MessageDescription.cs')
-rw-r--r--src/DotNetOAuth/Messaging/Reflection/MessageDescription.cs91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/DotNetOAuth/Messaging/Reflection/MessageDescription.cs b/src/DotNetOAuth/Messaging/Reflection/MessageDescription.cs
new file mode 100644
index 0000000..9442f15
--- /dev/null
+++ b/src/DotNetOAuth/Messaging/Reflection/MessageDescription.cs
@@ -0,0 +1,91 @@
+//-----------------------------------------------------------------------
+// <copyright file="MessageDescription.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.Messaging.Reflection {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Reflection;
+ using System.Globalization;
+ using System.Diagnostics;
+
+ internal class MessageDescription {
+ private static Dictionary<Type, MessageDescription> reflectedMessageTypes = new Dictionary<Type,MessageDescription>();
+ private Type messageType;
+ private Dictionary<string, MessagePart> mapping;
+
+ private MessageDescription(Type messageType) {
+ Debug.Assert(messageType != null, "messageType == null");
+
+ if (!typeof(IProtocolMessage).IsAssignableFrom(messageType)) {
+ throw new ArgumentException(string.Format(
+ CultureInfo.CurrentCulture,
+ MessagingStrings.UnexpectedType,
+ typeof(IProtocolMessage),
+ messageType));
+ }
+
+ this.messageType = messageType;
+ this.ReflectMessageType();
+ }
+
+ internal static MessageDescription Get(Type messageType) {
+ if (messageType == null) {
+ throw new ArgumentNullException("messageType");
+ }
+
+ MessageDescription result;
+ if (!reflectedMessageTypes.TryGetValue(messageType, out result)) {
+ lock (reflectedMessageTypes) {
+ if (!reflectedMessageTypes.TryGetValue(messageType, out result)) {
+ reflectedMessageTypes[messageType] = result = new MessageDescription(messageType);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ internal IDictionary<string, MessagePart> Mapping {
+ get { return this.mapping; }
+ }
+
+ internal void ReflectMessageType() {
+ this.mapping = new Dictionary<string, MessagePart>();
+
+ Type currentType = this.messageType;
+ do {
+ foreach (MemberInfo member in currentType.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) {
+ if (member is PropertyInfo || member is FieldInfo) {
+ MessagePartAttribute partAttribute = member.GetCustomAttributes(typeof(MessagePartAttribute), true).OfType<MessagePartAttribute>().FirstOrDefault();
+ if (partAttribute != null) {
+ MessagePart part = new MessagePart(member, partAttribute);
+ this.mapping.Add(part.Name, part);
+ }
+ }
+ }
+ currentType = currentType.BaseType;
+ } while (currentType != null);
+ }
+
+ /// <summary>
+ /// Verifies that a given set of keys include all the required parameters
+ /// for this message type or throws an exception.
+ /// </summary>
+ /// <exception cref="ProtocolException">Thrown when required parts of a message are not in <paramref name="keys"/></exception>
+ internal void EnsureRequiredMessagePartsArePresent(IEnumerable<string> keys) {
+ var missingKeys = (from part in Mapping.Values
+ where part.IsRequired && !keys.Contains(part.Name)
+ select part.Name).ToArray();
+ if (missingKeys.Length > 0) {
+ throw new ProtocolException(string.Format(CultureInfo.CurrentCulture,
+ MessagingStrings.RequiredParametersMissing,
+ this.messageType.FullName,
+ string.Join(", ", missingKeys)));
+ }
+ }
+ }
+}