1 //
2 // Author: Atsushi Enomoto <atsushi@ximian.com>
3 //
4 // Copyright (C) 2009,2010 Novell, Inc (http://www.novell.com)
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the
8 // "Software"), to deal in the Software without restriction, including
9 // without limitation the rights to use, copy, modify, merge, publish,
10 // distribute, sublicense, and/or sell copies of the Software, and to
11 // permit persons to whom the Software is furnished to do so, subject to
12 // the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 //
25 using System;
26 using System.Collections.Generic;
27 using System.Collections.ObjectModel;
28 using System.ServiceModel;
29 using System.ServiceModel.Channels;
30 using System.ServiceModel.Description;
31 using System.ServiceModel.Dispatcher;
32 using System.Xml;
33 using System.Xml.Schema;
34 using System.Xml.Linq;
35 
36 namespace System.ServiceModel.Discovery
37 {
38 	public class ResolveCriteria
39 	{
40 		const string SerializationNS = "http://schemas.microsoft.com/ws/2008/06/discovery";
41 		static readonly EndpointAddress anonymous_address = new EndpointAddress (EndpointAddress.AnonymousUri);
42 
ResolveCriteria()43 		public ResolveCriteria ()
44 		{
45 			Extensions = new Collection<XElement> ();
46 			Duration = TimeSpan.FromSeconds (20);
47 			Address = anonymous_address;
48 		}
49 
ResolveCriteria(EndpointAddress address)50 		public ResolveCriteria (EndpointAddress address)
51 			: this ()
52 		{
53 			Address = address;
54 		}
55 
56 		public EndpointAddress Address { get; set; }
57 		public TimeSpan Duration { get; set; }
58 		public Collection<XElement> Extensions { get; private set; }
59 
ReadXml(XmlReader reader, DiscoveryVersion version)60 		internal static ResolveCriteria ReadXml (XmlReader reader, DiscoveryVersion version)
61 		{
62 			if (reader == null)
63 				throw new ArgumentNullException ("reader");
64 
65 			var ret = new ResolveCriteria ();
66 
67 			reader.MoveToContent ();
68 			if (!reader.IsStartElement ("ResolveType", version.Namespace) || reader.IsEmptyElement)
69 				throw new XmlException ("Non-empty ResolveType element is expected");
70 			reader.ReadStartElement ("ResolveType", version.Namespace);
71 
72 			// standard members
73 			reader.MoveToContent ();
74 			ret.Address = EndpointAddress.ReadFrom (version.MessageVersion.Addressing, reader);
75 
76 			// non-standard members
77 			for (reader.MoveToContent (); !reader.EOF && reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) {
78 				if (reader.NamespaceURI == SerializationNS) {
79 					switch (reader.LocalName) {
80 					case "Duration":
81 						ret.Duration = (TimeSpan) reader.ReadElementContentAs (typeof (TimeSpan), null);
82 						break;
83 					}
84 				}
85 				else
86 					ret.Extensions.Add (XElement.Load (reader));
87 			}
88 
89 			reader.ReadEndElement ();
90 
91 			return ret;
92 		}
93 
WriteXml(XmlWriter writer, DiscoveryVersion version)94 		internal void WriteXml (XmlWriter writer, DiscoveryVersion version)
95 		{
96 			if (writer == null)
97 				throw new ArgumentNullException ("writer");
98 
99 			// standard members
100 			Address.WriteTo (version.MessageVersion.Addressing, writer);
101 
102 			// non-standard members
103 			writer.WriteStartElement ("Duration", SerializationNS);
104 			writer.WriteValue (Duration);
105 			writer.WriteEndElement ();
106 
107 			foreach (var ext in Extensions)
108 				ext.WriteTo (writer);
109 		}
110 
BuildSchema(DiscoveryVersion version)111 		internal static XmlSchema BuildSchema (DiscoveryVersion version)
112 		{
113 			var schema = new XmlSchema () { TargetNamespace = version.Namespace };
114 			string addrNS = "http://www.w3.org/2005/08/addressing";
115 
116 			var anyAttr = new XmlSchemaAnyAttribute () { Namespace = "##other", ProcessContents = XmlSchemaContentProcessing.Lax };
117 
118 			var resolvePart = new XmlSchemaSequence ();
119 			resolvePart.Items.Add (new XmlSchemaElement () { RefName = new XmlQualifiedName ("EndpointReference", addrNS), MinOccurs = 0 });
120 			resolvePart.Items.Add (new XmlSchemaAny () { MinOccurs = 0, MaxOccursString = "unbounded", Namespace = "##other", ProcessContents = XmlSchemaContentProcessing.Lax });
121 			var ct = new XmlSchemaComplexType () { Name = "ResolveType", Particle = resolvePart, AnyAttribute = anyAttr };
122 
123 			schema.Includes.Add (new XmlSchemaImport () { Namespace = addrNS });
124 			schema.Items.Add (ct);
125 
126 			return schema;
127 		}
128 	}
129 }
130