diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2009-03-22 21:26:56 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2009-03-22 21:26:56 -0700 |
commit | 82cb5edc410fd5dea98c7d732f4b865032f3980c (patch) | |
tree | 612ec9cf0035329a4eda4f87ecb59d1ff416bd96 /src | |
parent | d6f75f0532d71a28a4f55c88d3b59c9760989dd0 (diff) | |
download | DotNetOpenAuth-82cb5edc410fd5dea98c7d732f4b865032f3980c.zip DotNetOpenAuth-82cb5edc410fd5dea98c7d732f4b865032f3980c.tar.gz DotNetOpenAuth-82cb5edc410fd5dea98c7d732f4b865032f3980c.tar.bz2 |
Refactored AX extension and the Associations collection to use KeyedCollection to simplify their code and API.
Diffstat (limited to 'src')
11 files changed, 124 insertions, 168 deletions
diff --git a/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/AttributeExchangeRoundtripTests.cs b/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/AttributeExchangeRoundtripTests.cs index ac86156..1051092 100644 --- a/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/AttributeExchangeRoundtripTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/AttributeExchangeRoundtripTests.cs @@ -19,12 +19,12 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions { [TestMethod] public void Fetch() { var request = new FetchRequest(); - request.AddAttribute(new AttributeRequest(NicknameTypeUri)); - request.AddAttribute(new AttributeRequest(EmailTypeUri, false, int.MaxValue)); + request.Attributes.Add(new AttributeRequest(NicknameTypeUri)); + request.Attributes.Add(new AttributeRequest(EmailTypeUri, false, int.MaxValue)); var response = new FetchResponse(); - response.AddAttribute(new AttributeValues(NicknameTypeUri, "Andrew")); - response.AddAttribute(new AttributeValues(EmailTypeUri, "a@a.com", "b@b.com")); + response.Attributes.Add(new AttributeValues(NicknameTypeUri, "Andrew")); + response.Attributes.Add(new AttributeValues(EmailTypeUri, "a@a.com", "b@b.com")); ExtensionTestUtilities.Roundtrip(Protocol.Default, new[] { request }, new[] { response }); } @@ -36,7 +36,7 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions { IncrementingAttribute, "val" + (incrementingAttributeValue++).ToString(), "val" + (incrementingAttributeValue++).ToString()); - request.AddAttribute(newAttribute); + request.Attributes.Add(newAttribute); var successResponse = new StoreResponse(); successResponse.Succeeded = true; diff --git a/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/FetchRequestTests.cs b/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/FetchRequestTests.cs index 5374794..4dbb5ad 100644 --- a/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/FetchRequestTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/FetchRequestTests.cs @@ -14,26 +14,26 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions { public class FetchRequestTests : OpenIdTestBase { [TestMethod, ExpectedException(typeof(ArgumentNullException))] public void AddAttributeRequestNull() { - new FetchRequest().AddAttribute(null); + new FetchRequest().Attributes.Add(null); } [TestMethod] public void AddAttributeRequest() { var req = new FetchRequest(); - req.AddAttribute(new AttributeRequest() { TypeUri = "http://someUri" }); + req.Attributes.Add(new AttributeRequest() { TypeUri = "http://someUri" }); } [TestMethod] public void AddAttributeRequestStrangeUri() { var req = new FetchRequest(); - req.AddAttribute(new AttributeRequest() { TypeUri = "=someUri*who*knows*but*this*is*legal" }); + req.Attributes.Add(new AttributeRequest() { TypeUri = "=someUri*who*knows*but*this*is*legal" }); } [TestMethod, ExpectedException(typeof(ArgumentException))] public void AddAttributeRequestAgain() { var req = new FetchRequest(); - req.AddAttribute(new AttributeRequest() { TypeUri = "http://UriTwice" }); - req.AddAttribute(new AttributeRequest() { TypeUri = "http://UriTwice" }); + req.Attributes.Add(new AttributeRequest() { TypeUri = "http://UriTwice" }); + req.Attributes.Add(new AttributeRequest() { TypeUri = "http://UriTwice" }); } [TestMethod] @@ -86,13 +86,13 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions { Assert.AreEqual(req1, req2); // Add attributes in different orders deliberately. - req1.AddAttribute(new AttributeRequest("http://att1")); + req1.Attributes.Add(new AttributeRequest("http://att1")); Assert.AreNotEqual(req1, req2); - req2.AddAttribute(new AttributeRequest("http://att2")); + req2.Attributes.Add(new AttributeRequest("http://att2")); Assert.AreNotEqual(req1, req2); - req1.AddAttribute(new AttributeRequest("http://att2")); + req1.Attributes.Add(new AttributeRequest("http://att2")); Assert.AreNotEqual(req1, req2); - req2.AddAttribute(new AttributeRequest("http://att1")); + req2.Attributes.Add(new AttributeRequest("http://att1")); Assert.AreEqual(req1, req2); } } diff --git a/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/FetchResponseTests.cs b/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/FetchResponseTests.cs index 3f01498..32e723a 100644 --- a/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/FetchResponseTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/FetchResponseTests.cs @@ -15,27 +15,27 @@ namespace DotNetOpenId.Test.OpenId.Extensions { [TestMethod] public void AddAttribute() { var response = new FetchResponse(); - response.AddAttribute(new AttributeValues("http://someattribute", "Value1")); + response.Attributes.Add(new AttributeValues("http://someattribute", "Value1")); } [TestMethod] public void AddTwoAttributes() { var response = new FetchResponse(); - response.AddAttribute(new AttributeValues("http://someattribute", "Value1")); - response.AddAttribute(new AttributeValues("http://someOtherAttribute", "Value2")); + response.Attributes.Add(new AttributeValues("http://someattribute", "Value1")); + response.Attributes.Add(new AttributeValues("http://someOtherAttribute", "Value2")); } [TestMethod, ExpectedException(typeof(ArgumentException))] public void AddAttributeTwice() { var response = new FetchResponse(); - response.AddAttribute(new AttributeValues("http://someattribute", "Value1")); - response.AddAttribute(new AttributeValues("http://someattribute", "Value1")); + response.Attributes.Add(new AttributeValues("http://someattribute", "Value1")); + response.Attributes.Add(new AttributeValues("http://someattribute", "Value1")); } [TestMethod, ExpectedException(typeof(ArgumentNullException))] public void AddAttributeNull() { var response = new FetchResponse(); - response.AddAttribute(null); + response.Attributes.Add(null); } [TestMethod] @@ -50,13 +50,13 @@ namespace DotNetOpenId.Test.OpenId.Extensions { Assert.AreEqual(response1, response2); // Add attributes in different orders deliberately. - response1.AddAttribute(new AttributeValues("http://att1")); + response1.Attributes.Add(new AttributeValues("http://att1")); Assert.AreNotEqual(response1, response2); - response2.AddAttribute(new AttributeValues("http://att2")); + response2.Attributes.Add(new AttributeValues("http://att2")); Assert.AreNotEqual(response1, response2); - response1.AddAttribute(new AttributeValues("http://att2")); + response1.Attributes.Add(new AttributeValues("http://att2")); Assert.AreNotEqual(response1, response2); - response2.AddAttribute(new AttributeValues("http://att1")); + response2.Attributes.Add(new AttributeValues("http://att1")); Assert.AreEqual(response1, response2); } } diff --git a/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/StoreRequestTests.cs b/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/StoreRequestTests.cs index e0fe064..23c9177 100644 --- a/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/StoreRequestTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/StoreRequestTests.cs @@ -31,7 +31,7 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions.AttributeExchange { public void AddAttributeByValue() { var req = new StoreRequest(); AttributeValues value = new AttributeValues(); - req.AddAttribute(value); + req.Attributes.Add(value); Assert.AreSame(value, req.Attributes.Single()); } @@ -41,7 +41,7 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions.AttributeExchange { [TestMethod] public void AddAttributeByPrimitives() { var req = new StoreRequest(); - req.AddAttribute("http://att1", "value1", "value2"); + req.Attributes.Add("http://att1", "value1", "value2"); AttributeValues value = req.Attributes.Single(); Assert.AreEqual("http://att1", value.TypeUri); Assert.IsTrue(MessagingUtilities.AreEquivalent(new[] { "value1", "value2" }, value.Values)); @@ -57,13 +57,13 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions.AttributeExchange { Assert.AreEqual(req1, req2); // Add attributes in different orders deliberately. - req1.AddAttribute("http://att1"); + req1.Attributes.Add("http://att1"); Assert.AreNotEqual(req1, req2); - req2.AddAttribute("http://att2"); + req2.Attributes.Add("http://att2"); Assert.AreNotEqual(req1, req2); - req1.AddAttribute("http://att2"); + req1.Attributes.Add("http://att2"); Assert.AreNotEqual(req1, req2); - req2.AddAttribute("http://att1"); + req2.Attributes.Add("http://att1"); Assert.AreEqual(req1, req2); } } diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index 0e580e5..e63297f 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -215,6 +215,7 @@ <Compile Include="Messaging\IMessageWithEvents.cs" /> <Compile Include="Messaging\IProtocolMessageWithExtensions.cs" /> <Compile Include="Messaging\InternalErrorException.cs" /> + <Compile Include="Messaging\KeyedCollectionDelegate.cs" /> <Compile Include="Messaging\NetworkDirectWebResponse.cs" /> <Compile Include="Messaging\OutgoingWebResponseActionResult.cs" /> <Compile Include="Messaging\Reflection\IMessagePartEncoder.cs" /> diff --git a/src/DotNetOpenAuth/Messaging/KeyedCollectionDelegate.cs b/src/DotNetOpenAuth/Messaging/KeyedCollectionDelegate.cs new file mode 100644 index 0000000..928f873 --- /dev/null +++ b/src/DotNetOpenAuth/Messaging/KeyedCollectionDelegate.cs @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------- +// <copyright file="KeyedCollectionDelegate.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Messaging { + using System; + using System.Collections.ObjectModel; + using System.Diagnostics.Contracts; + + /// <summary> + /// A KeyedCollection whose item -> key transform is provided via a delegate + /// to its constructor, and null items are disallowed. + /// </summary> + /// <typeparam name="TKey">The type of the key.</typeparam> + /// <typeparam name="TItem">The type of the item.</typeparam> + internal class KeyedCollectionDelegate<TKey, TItem> : KeyedCollection<TKey, TItem> { + /// <summary> + /// The delegate that returns a key for the given item. + /// </summary> + private Func<TItem, TKey> getKeyForItemDelegate; + + /// <summary> + /// Initializes a new instance of the KeyedCollectionDelegate class. + /// </summary> + /// <param name="getKeyForItemDelegate">The delegate that gets the key for a given item.</param> + internal KeyedCollectionDelegate(Func<TItem, TKey> getKeyForItemDelegate) { + Contract.Requires(getKeyForItemDelegate != null); + ErrorUtilities.VerifyArgumentNotNull(getKeyForItemDelegate, "getKeyForItemDelegate"); + + this.getKeyForItemDelegate = getKeyForItemDelegate; + } + + /// <summary> + /// When implemented in a derived class, extracts the key from the specified element. + /// </summary> + /// <param name="item">The element from which to extract the key.</param> + /// <returns>The key for the specified element.</returns> + protected override TKey GetKeyForItem(TItem item) { + ErrorUtilities.VerifyArgumentNotNull(item, "item"); + return this.getKeyForItemDelegate(item); + } + } +} diff --git a/src/DotNetOpenAuth/OpenId/Associations.cs b/src/DotNetOpenAuth/OpenId/Associations.cs index 1fd6177..fe2be42 100644 --- a/src/DotNetOpenAuth/OpenId/Associations.cs +++ b/src/DotNetOpenAuth/OpenId/Associations.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; + using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using DotNetOpenAuth.Messaging; @@ -25,13 +26,12 @@ namespace DotNetOpenAuth.OpenId { /// The lookup table where keys are the association handles and values are the associations themselves. /// </summary> [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] - private readonly Dictionary<string, Association> associations; + private readonly KeyedCollection<string, Association> associations = new KeyedCollectionDelegate<string, Association>(assoc => assoc.Handle); /// <summary> /// Initializes a new instance of the <see cref="Associations"/> class. /// </summary> public Associations() { - this.associations = new Dictionary<string, Association>(); } /// <summary> @@ -45,7 +45,7 @@ namespace DotNetOpenAuth.OpenId { public IEnumerable<Association> Best { get { lock (this.associations) { - return this.associations.Values.OrderByDescending(assoc => assoc.Issued); + return this.associations.OrderByDescending(assoc => assoc.Issued); } } } @@ -57,7 +57,8 @@ namespace DotNetOpenAuth.OpenId { public void Set(Association association) { ErrorUtilities.VerifyArgumentNotNull(association, "association"); lock (this.associations) { - this.associations[association.Handle] = association; + this.associations.Remove(association.Handle); // just in case one already exists. + this.associations.Add(association); } } @@ -68,9 +69,11 @@ namespace DotNetOpenAuth.OpenId { /// <returns>The desired association, or null if none with the given handle could be found.</returns> public Association Get(string handle) { lock (this.associations) { - Association assoc; - this.associations.TryGetValue(handle, out assoc); - return assoc; + if (this.associations.Contains(handle)) { + return this.associations[handle]; + } else { + return null; + } } } @@ -90,7 +93,7 @@ namespace DotNetOpenAuth.OpenId { /// </summary> public void ClearExpired() { lock (this.associations) { - var expireds = this.associations.Values.Where(assoc => assoc.IsExpired).ToList(); + var expireds = this.associations.Where(assoc => assoc.IsExpired).ToList(); foreach (Association assoc in expireds) { this.associations.Remove(assoc.Handle); } diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AXUtilities.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AXUtilities.cs index 53b916f..3504b7a 100644 --- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AXUtilities.cs +++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AXUtilities.cs @@ -7,13 +7,27 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { using System; using System.Collections.Generic; + using System.Diagnostics.Contracts; using System.Globalization; using DotNetOpenAuth.Messaging; /// <summary> /// Helper methods shared by multiple messages in the Attribute Exchange extension. /// </summary> - internal static class AXUtilities { + public static class AXUtilities { + /// <summary> + /// Adds a given attribute with one or more values to the request for storage. + /// Applicable to Relying Parties only. + /// </summary> + /// <param name="collection">The collection of <see cref="AttributeValues"/> to add to.</param> + /// <param name="typeUri">The type URI of the attribute.</param> + /// <param name="values">The attribute values.</param> + public static void Add(this ICollection<AttributeValues> collection, string typeUri, params string[] values) { + Contract.Requires(collection != null); + ErrorUtilities.VerifyArgumentNotNull(collection, "collection"); + collection.Add(new AttributeValues(typeUri, values)); + } + /// <summary> /// Serializes a set of attribute values to a dictionary of fields to send in the message. /// </summary> diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchRequest.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchRequest.cs index 0f5e4e6..72f98ee 100644 --- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchRequest.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { using System; using System.Collections.Generic; + using System.Collections.ObjectModel; using System.Globalization; using System.Linq; using DotNetOpenAuth.Messaging; @@ -48,9 +49,9 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { private const string Mode = "fetch_request"; /// <summary> - /// The list of requested attributes. This field will never be null. + /// The collection of requested attributes. /// </summary> - private readonly List<AttributeRequest> attributesRequested = new List<AttributeRequest>(); + private readonly KeyedCollection<string, AttributeRequest> attributes = new KeyedCollectionDelegate<string, AttributeRequest>(ar => ar.TypeUri); /// <summary> /// Initializes a new instance of the <see cref="FetchRequest"/> class. @@ -60,10 +61,13 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { } /// <summary> - /// Gets a sequence of the attributes whose values are requested by the Relying Party. + /// Gets a collection of the attributes whose values are + /// requested by the Relying Party. /// </summary> - public IEnumerable<AttributeRequest> Attributes { - get { return this.attributesRequested; } + /// <value>A collection where the keys are the attribute type URIs, and the value + /// is all the attribute request details.</value> + public KeyedCollection<string, AttributeRequest> Attributes { + get { return this.attributes; } } /// <summary> @@ -90,29 +94,6 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { private string RequiredAliases { get; set; } /// <summary> - /// Adds a request for the values of a given attribute. - /// Applicable to Relying Parties. - /// </summary> - /// <param name="attribute">The attribute.</param> - public void AddAttribute(AttributeRequest attribute) { - ErrorUtilities.VerifyArgumentNotNull(attribute, "attribute"); - ErrorUtilities.VerifyArgumentNamed(!this.ContainsAttribute(attribute.TypeUri), "attribute", OpenIdStrings.AttributeAlreadyAdded, attribute.TypeUri); - this.attributesRequested.Add(attribute); - } - - /// <summary> - /// Find out whether the value(s) of a given attribute are being requested by the Relying Party. - /// Applicable to Providers. - /// </summary> - /// <param name="attributeTypeUri">The type URI of the attribute.</param> - /// <returns> - /// The details of a Relying Party's request for the given attribute; or <c>null</c> if the relyign party did not ask for the values of the given attribute. - /// </returns> - public AttributeRequest GetAttribute(string attributeTypeUri) { - return this.attributesRequested.SingleOrDefault(attribute => string.Equals(attribute.TypeUri, attributeTypeUri, StringComparison.Ordinal)); - } - - /// <summary> /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>. /// </summary> /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param> @@ -177,7 +158,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { List<string> requiredAliases = new List<string>(), optionalAliases = new List<string>(); AliasManager aliasManager = new AliasManager(); - foreach (var att in this.attributesRequested) { + foreach (var att in this.attributes) { string alias = aliasManager.GetAlias(att.TypeUri); // define the alias<->typeUri mapping @@ -240,7 +221,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { } else { att.Count = 1; } - this.AddAttribute(att); + this.Attributes.Add(att); } else { Logger.OpenId.Error("Type URI definition of alias " + alias + " is missing."); } @@ -296,16 +277,5 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { return aliasList.Split(','); } - - /// <summary> - /// Determines whether some attribute has values in this fetch request. - /// </summary> - /// <param name="typeUri">The type URI of the attribute in question.</param> - /// <returns> - /// <c>true</c> if the specified attribute appears in the fetch request; otherwise, <c>false</c>. - /// </returns> - private bool ContainsAttribute(string typeUri) { - return this.GetAttribute(typeUri) != null; - } } } diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchResponse.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchResponse.cs index c309532..0f7d40f 100644 --- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/FetchResponse.cs @@ -6,9 +6,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Globalization; + using System.Collections.ObjectModel; using System.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Messages; @@ -39,9 +37,9 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { private const string Mode = "fetch_response"; /// <summary> - /// The list of provided attributes. This field will never be null. + /// The collection of provided attributes. This field will never be null. /// </summary> - private readonly List<AttributeValues> attributesProvided = new List<AttributeValues>(); + private readonly KeyedCollection<string, AttributeValues> attributesProvided = new KeyedCollectionDelegate<string, AttributeValues>(av => av.TypeUri); /// <summary> /// Initializes a new instance of the <see cref="FetchResponse"/> class. @@ -53,7 +51,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { /// <summary> /// Gets a sequence of the attributes whose values are provided by the OpenID Provider. /// </summary> - public IEnumerable<AttributeValues> Attributes { + public KeyedCollection<string, AttributeValues> Attributes { get { return this.attributesProvided; } } @@ -73,28 +71,6 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { public Uri UpdateUrl { get; set; } /// <summary> - /// Adds attributes to the response for the relying party. - /// Applicable to Providers. - /// </summary> - /// <param name="attribute">The attribute and values to add to the response.</param> - public void AddAttribute(AttributeValues attribute) { - ErrorUtilities.VerifyArgumentNotNull(attribute, "attribute"); - ErrorUtilities.VerifyArgumentNamed(!this.ContainsAttribute(attribute.TypeUri), "attribute", OpenIdStrings.AttributeAlreadyAdded, attribute.TypeUri); - this.attributesProvided.Add(attribute); - } - - /// <summary> - /// Gets the value(s) returned by the OpenID Provider - /// for a given attribute, or null if that attribute was not provided. - /// Applicable to Relying Parties. - /// </summary> - /// <param name="attributeTypeUri">The type URI of the attribute.</param> - /// <returns>The values given by the Provider for the given attribute; or <c>null</c> if the attribute was not included in the message.</returns> - public AttributeValues GetAttribute(string attributeTypeUri) { - return this.attributesProvided.SingleOrDefault(attribute => string.Equals(attribute.TypeUri, attributeTypeUri, StringComparison.Ordinal)); - } - - /// <summary> /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>. /// </summary> /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param> @@ -165,7 +141,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { void IMessageWithEvents.OnReceiving() { var extraData = ((IMessage)this).ExtraData; foreach (var att in AXUtilities.DeserializeAttributes(extraData)) { - this.AddAttribute(att); + this.Attributes.Add(att); } } @@ -191,16 +167,5 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { Logger.OpenId.ErrorFormat("The AX fetch response update_url parameter was not absolute ('{0}'). Ignoring value.", this.UpdateUrl); } } - - /// <summary> - /// Determines whether some attribute has values in this fetch response. - /// </summary> - /// <param name="typeUri">The type URI of the attribute in question.</param> - /// <returns> - /// <c>true</c> if the specified attribute appears in the fetch response; otherwise, <c>false</c>. - /// </returns> - private bool ContainsAttribute(string typeUri) { - return this.GetAttribute(typeUri) != null; - } } } diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/StoreRequest.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/StoreRequest.cs index b4df366..e3743e4 100644 --- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/StoreRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/StoreRequest.cs @@ -6,7 +6,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { using System; - using System.Collections.Generic; + using System.Collections.ObjectModel; using System.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Messages; @@ -37,9 +37,9 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { private const string Mode = "store_request"; /// <summary> - /// The list of provided attribute values. This field will never be null. + /// The collection of provided attribute values. This field will never be null. /// </summary> - private readonly List<AttributeValues> attributesProvided = new List<AttributeValues>(); + private readonly KeyedCollection<string, AttributeValues> attributesProvided = new KeyedCollectionDelegate<string, AttributeValues>(av => av.TypeUri); /// <summary> /// Initializes a new instance of the <see cref="StoreRequest"/> class. @@ -49,43 +49,12 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { } /// <summary> - /// Gets a list of all the attributes that are included in the store request. + /// Gets the collection of all the attributes that are included in the store request. /// </summary> - public IEnumerable<AttributeValues> Attributes { + public KeyedCollection<string, AttributeValues> Attributes { get { return this.attributesProvided; } } - /// <summary> - /// Adds a given attribute with one or more values to the request for storage. - /// Applicable to Relying Parties only. - /// </summary> - /// <param name="attribute">The attribute values.</param> - public void AddAttribute(AttributeValues attribute) { - ErrorUtilities.VerifyArgumentNotNull(attribute, "attribute"); - ErrorUtilities.VerifyArgumentNamed(!this.ContainsAttribute(attribute.TypeUri), "attribute", OpenIdStrings.AttributeAlreadyAdded, attribute.TypeUri); - this.attributesProvided.Add(attribute); - } - - /// <summary> - /// Adds a given attribute with one or more values to the request for storage. - /// Applicable to Relying Parties only. - /// </summary> - /// <param name="typeUri">The type URI of the attribute.</param> - /// <param name="values">The attribute values.</param> - public void AddAttribute(string typeUri, params string[] values) { - this.AddAttribute(new AttributeValues(typeUri, values)); - } - - /// <summary> - /// Gets the value(s) associated with a given attribute that should be stored. - /// Applicable to Providers only. - /// </summary> - /// <param name="attributeTypeUri">The type URI of the attribute whose values are being sought.</param> - /// <returns>The attribute values.</returns> - public AttributeValues GetAttribute(string attributeTypeUri) { - return this.attributesProvided.SingleOrDefault(attribute => string.Equals(attribute.TypeUri, attributeTypeUri, StringComparison.Ordinal)); - } - #region IMessageWithEvents Members /// <summary> @@ -106,7 +75,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { void IMessageWithEvents.OnReceiving() { var fields = ((IMessage)this).ExtraData; foreach (var att in AXUtilities.DeserializeAttributes(fields)) { - this.AddAttribute(att); + this.Attributes.Add(att); } } @@ -154,16 +123,5 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { return hashCode; } } - - /// <summary> - /// Determines whether some attribute has values in this store request. - /// </summary> - /// <param name="typeUri">The type URI of the attribute in question.</param> - /// <returns> - /// <c>true</c> if the specified attribute appears in the store request; otherwise, <c>false</c>. - /// </returns> - private bool ContainsAttribute(string typeUri) { - return this.GetAttribute(typeUri) != null; - } } } |