5 // Martin Baulig <martin.baulig@xamarin.com>
7 // Copyright (c) 2012 Xamarin Inc. (http://www.xamarin.com)
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 using System.Configuration;
31 using System.Collections.Generic;
33 using System.Xml.XPath;
34 using System.Reflection;
35 using System.ServiceModel;
36 using System.ServiceModel.Channels;
37 using System.ServiceModel.Configuration;
38 using System.ServiceModel.Description;
40 using SysConfig = System.Configuration.Configuration;
42 namespace MonoTests.System.ServiceModel.MetadataTests {
44 public abstract class TestContext {
48 public abstract MetadataSet GetMetadata (string name);
50 public abstract XmlDocument GetConfiguration (string name);
54 #region Default Context
56 public static TestContext LoadMetadataContext = new _LoadMetadataContext ();
58 public static TestContext CreateMetadataContext = new _CreateMetadataContext ();
60 public static TestContext RoundTripContext = new _RoundTripContext ();
64 #region Implementations
66 class _LoadMetadataContext : TestContext {
67 public override MetadataSet GetMetadata (string name)
69 return LoadMetadata (name);
72 public override XmlDocument GetConfiguration (string name)
74 return LoadConfiguration (name);
78 class _CreateMetadataContext : TestContext {
79 public override MetadataSet GetMetadata (string name)
81 return MetadataSamples.GetMetadataByName (name);
84 public override XmlDocument GetConfiguration (string name)
86 var metadata = GetMetadata (name);
87 var doc = new XmlDocument ();
88 doc.LoadXml (SaveConfigToString (metadata));
93 class _RoundTripContext : TestContext {
94 public override MetadataSet GetMetadata (string name)
96 return RoundTrip (name);
99 public override XmlDocument GetConfiguration (string name)
101 var metadata = GetMetadata (name);
102 var doc = new XmlDocument ();
103 doc.LoadXml (SaveConfigToString (metadata));
110 #region Public Static API
112 public static MetadataSet LoadMetadata (string name)
114 #if USE_EMBEDDED_METADATA
115 return LoadMetadataFromResource (name);
117 return LoadMetadataFromFile (name);
121 public static XmlDocument LoadConfiguration (string name)
123 #if USE_EMBEDDED_METADATA
124 return LoadConfigurationFromResource (name);
126 return LoadConfigurationFromFile (name);
130 public static void SaveMetadata (string name, MetadataSet metadata)
132 SaveMetadataToFile (name, metadata);
135 public static MetadataSet LoadMetadataFromFile (string name)
137 var asm = Assembly.GetExecutingAssembly ();
138 if (!name.EndsWith (".xml"))
139 name = name + ".xml";
140 var uri = new Uri (asm.CodeBase);
141 // Run from mcs/class/lib/<profile>
142 var path = Path.GetDirectoryName (uri.AbsolutePath);
143 path = Directory.GetParent (path).Parent.FullName;
144 path = Path.Combine (path, "System.ServiceModel");
145 path = Path.Combine (path, "Test");
146 path = Path.Combine (path, "MetadataTests");
147 path = Path.Combine (path, "Resources");
148 var filename = Path.Combine (path, name);
149 using (var stream = new StreamReader (filename)) {
150 var reader = new XmlTextReader (stream);
151 return MetadataSet.ReadFrom (reader);
155 public static MetadataSet LoadMetadataFromResource (string name)
157 var asm = Assembly.GetExecutingAssembly ();
158 if (!name.EndsWith (".xml"))
159 name = name + ".xml";
161 var resname = "MetadataTests.Resources." + name;
162 using (var stream = asm.GetManifestResourceStream (resname)) {
164 throw new InvalidOperationException (
165 "No such resource: " + name);
166 var reader = new XmlTextReader (stream);
167 return MetadataSet.ReadFrom (reader);
171 public static XmlDocument LoadConfigurationFromFile (string name)
173 var asm = Assembly.GetExecutingAssembly ();
174 if (!name.EndsWith (".config"))
175 name = name + ".config";
176 var uri = new Uri (asm.CodeBase);
177 var path = Path.GetDirectoryName (uri.AbsolutePath);
178 path = Directory.GetParent (path).Parent.FullName;
179 path = Path.Combine (path, "System.ServiceModel");
180 path = Path.Combine (path, "Test");
181 path = Path.Combine (path, "MetadataTests");
182 path = Path.Combine (path, "Resources");
183 var filename = Path.Combine (path, name);
184 using (var stream = new StreamReader (filename)) {
185 var xml = new XmlDocument ();
191 public static XmlDocument LoadConfigurationFromResource (string name)
193 var asm = Assembly.GetExecutingAssembly ();
194 if (!name.EndsWith (".config"))
195 name = name + ".config";
197 var resname = "MetadataTests.Resources." + name;
198 using (var stream = asm.GetManifestResourceStream (resname)) {
200 throw new InvalidOperationException (
201 "No such resource: " + name);
202 var xml = new XmlDocument ();
208 public static void SaveMetadataToFile (string filename, MetadataSet metadata)
210 if (File.Exists (filename))
213 using (var file = new StreamWriter (filename, false)) {
214 var writer = new XmlTextWriter (file);
215 writer.Formatting = Formatting.Indented;
216 metadata.WriteTo (writer);
219 Console.WriteLine ("Exported {0}.", filename);
222 internal static string SaveMetadataToString (MetadataSet metadata)
224 using (var ms = new MemoryStream ()) {
225 var writer = new XmlTextWriter (new StreamWriter (ms));
226 writer.Formatting = Formatting.Indented;
227 metadata.WriteTo (writer);
230 return Encoding.UTF8.GetString (ms.GetBuffer (), 0, (int)ms.Position);
234 internal static MetadataSet LoadMetadataFromString (string doc)
236 var buffer = Encoding.UTF8.GetBytes (doc);
237 using (var ms = new MemoryStream (buffer)) {
238 var reader = new XmlTextReader (ms);
239 return MetadataSet.ReadFrom (reader);
243 public static MetadataSet RoundTrip (string name)
245 var metadata = MetadataSamples.GetMetadataByName (name);
247 var doc = SaveMetadataToString (metadata);
248 return LoadMetadataFromString (doc);
251 public static void GenerateConfig (MetadataSet metadata, SysConfig config)
253 WsdlImporter importer = new WsdlImporter (metadata);
255 var endpoints = importer.ImportAllEndpoints ();
257 var generator = new ServiceContractGenerator (config);
258 generator.Options = ServiceContractGenerationOptions.None;
260 foreach (var endpoint in endpoints) {
261 ChannelEndpointElement channelElement;
262 generator.GenerateServiceEndpoint (endpoint, out channelElement);
266 public static void GenerateConfig (string filename, MetadataSet metadata)
268 var fileMap = new ExeConfigurationFileMap ();
269 fileMap.ExeConfigFilename = filename;
270 var config = ConfigurationManager.OpenMappedExeConfiguration (
271 fileMap, ConfigurationUserLevel.None);
273 GenerateConfig (metadata, config);
274 config.Save (ConfigurationSaveMode.Minimal);
275 NormalizeConfig (filename);
278 internal static string SaveConfigToString (MetadataSet metadata)
280 var filename = Path.GetTempFileName ();
281 File.Delete (filename);
284 GenerateConfig (filename, metadata);
286 using (var reader = new StreamReader (filename))
287 return reader.ReadToEnd ();
289 File.Delete (filename);
293 public static void NormalizeConfig (string filename)
295 // Mono-specific hack.
296 if (Environment.OSVersion.Platform == PlatformID.Win32NT)
299 var doc = new XmlDocument ();
301 var nav = doc.CreateNavigator ();
303 var empty = new List<XPathNavigator> ();
304 var iter = nav.Select ("/configuration/system.serviceModel//*");
305 foreach (XPathNavigator node in iter) {
306 if (!node.HasChildren && !node.HasAttributes && string.IsNullOrEmpty (node.Value))
309 foreach (var node in empty)
312 var settings = new XmlWriterSettings ();
313 settings.Indent = true;
314 settings.NewLineHandling = NewLineHandling.Replace;
316 using (var writer = XmlWriter.Create (filename, settings)) {
317 doc.WriteTo (writer);
319 Console.WriteLine ();