summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OpenId/Xrds/ServiceElement.cs
blob: 0886e78bde7bc87e1f67873cc096bf6915de0514 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//-----------------------------------------------------------------------
// <copyright file="ServiceElement.cs" company="Outercurve Foundation, Scott Hanselman">
//     Copyright (c) Outercurve Foundation, Scott Hanselman. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOpenAuth.Xrds {
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Xml.XPath;
	using DotNetOpenAuth.OpenId;

	/// <summary>
	/// The Service element in an XRDS document.
	/// </summary>
	internal class ServiceElement : XrdsNode, IComparable<ServiceElement> {
		/// <summary>
		/// Initializes a new instance of the <see cref="ServiceElement"/> class.
		/// </summary>
		/// <param name="serviceElement">The service element.</param>
		/// <param name="parent">The parent.</param>
		public ServiceElement(XPathNavigator serviceElement, XrdElement parent) :
			base(serviceElement, parent) {
		}

		/// <summary>
		/// Gets the XRD parent element.
		/// </summary>
		public XrdElement Xrd {
			get { return (XrdElement)ParentNode; }
		}

		/// <summary>
		/// Gets the priority.
		/// </summary>
		public int? Priority {
			get {
				XPathNavigator n = Node.SelectSingleNode("@priority", XmlNamespaceResolver);
				return n != null ? n.ValueAsInt : (int?)null;
			}
		}

		/// <summary>
		/// Gets the URI child elements.
		/// </summary>
		public IEnumerable<UriElement> UriElements {
			get {
				List<UriElement> uris = new List<UriElement>();
				foreach (XPathNavigator node in Node.Select("xrd:URI", XmlNamespaceResolver)) {
					uris.Add(new UriElement(node, this));
				}
				uris.Sort();
				return uris;
			}
		}

		/// <summary>
		/// Gets the type child elements.
		/// </summary>
		/// <value>The type elements.</value>
		public IEnumerable<TypeElement> TypeElements {
			get {
				foreach (XPathNavigator node in Node.Select("xrd:Type", XmlNamespaceResolver)) {
					yield return new TypeElement(node, this);
				}
			}
		}

		/// <summary>
		/// Gets the type child element's URIs.
		/// </summary>
		public string[] TypeElementUris {
			get {
				return this.TypeElements.Select(type => type.Uri).ToArray();
			}
		}

		/// <summary>
		/// Gets the OP Local Identifier.
		/// </summary>
		public Identifier ProviderLocalIdentifier {
			get {
				var n = Node.SelectSingleNode("xrd:LocalID", XmlNamespaceResolver)
					?? Node.SelectSingleNode("openid10:Delegate", XmlNamespaceResolver);
				if (n != null && n.Value != null) {
					string value = n.Value.Trim();
					if (value.Length > 0) {
						return n.Value;
					}
				}

				return null;
			}
		}

		#region IComparable<ServiceElement> Members

		/// <summary>
		/// Compares the current object with another object of the same type.
		/// </summary>
		/// <param name="other">An object to compare with this object.</param>
		/// <returns>
		/// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has the following meanings:
		/// Value
		/// Meaning
		/// Less than zero
		/// This object is less than the <paramref name="other"/> parameter.
		/// Zero
		/// This object is equal to <paramref name="other"/>.
		/// Greater than zero
		/// This object is greater than <paramref name="other"/>.
		/// </returns>
		public int CompareTo(ServiceElement other) {
			if (other == null) {
				return -1;
			}
			if (this.Priority.HasValue && other.Priority.HasValue) {
				return this.Priority.Value.CompareTo(other.Priority.Value);
			} else {
				if (this.Priority.HasValue) {
					return -1;
				} else if (other.Priority.HasValue) {
					return 1;
				} else {
					return 0;
				}
			}
		}

		#endregion
	}
}