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 var path = Path.GetDirectoryName (uri.AbsolutePath);
142 path = Path.Combine (path, "Test");
143 path = Path.Combine (path, "MetadataTests");
144 path = Path.Combine (path, "Resources");
145 var filename = Path.Combine (path, name);
146 using (var stream = new StreamReader (filename)) {
147 var reader = new XmlTextReader (stream);
148 return MetadataSet.ReadFrom (reader);
152 public static MetadataSet LoadMetadataFromResource (string name)
154 var asm = Assembly.GetExecutingAssembly ();
155 if (!name.EndsWith (".xml"))
156 name = name + ".xml";
158 var resname = "MetadataTests.Resources." + name;
159 using (var stream = asm.GetManifestResourceStream (resname)) {
161 throw new InvalidOperationException (
162 "No such resource: " + name);
163 var reader = new XmlTextReader (stream);
164 return MetadataSet.ReadFrom (reader);
168 public static XmlDocument LoadConfigurationFromFile (string name)
170 var asm = Assembly.GetExecutingAssembly ();
171 if (!name.EndsWith (".config"))
172 name = name + ".config";
173 var uri = new Uri (asm.CodeBase);
174 var path = Path.GetDirectoryName (uri.AbsolutePath);
175 path = Path.Combine (path, "Test");
176 path = Path.Combine (path, "MetadataTests");
177 path = Path.Combine (path, "Resources");
178 var filename = Path.Combine (path, name);
179 using (var stream = new StreamReader (filename)) {
180 var xml = new XmlDocument ();
186 public static XmlDocument LoadConfigurationFromResource (string name)
188 var asm = Assembly.GetExecutingAssembly ();
189 if (!name.EndsWith (".config"))
190 name = name + ".config";
192 var resname = "MetadataTests.Resources." + name;
193 using (var stream = asm.GetManifestResourceStream (resname)) {
195 throw new InvalidOperationException (
196 "No such resource: " + name);
197 var xml = new XmlDocument ();
203 public static void SaveMetadataToFile (string filename, MetadataSet metadata)
205 if (File.Exists (filename))
208 using (var file = new StreamWriter (filename, false)) {
209 var writer = new XmlTextWriter (file);
210 writer.Formatting = Formatting.Indented;
211 metadata.WriteTo (writer);
214 Console.WriteLine ("Exported {0}.", filename);
217 internal static string SaveMetadataToString (MetadataSet metadata)
219 using (var ms = new MemoryStream ()) {
220 var writer = new XmlTextWriter (new StreamWriter (ms));
221 writer.Formatting = Formatting.Indented;
222 metadata.WriteTo (writer);
225 return Encoding.UTF8.GetString (ms.GetBuffer (), 0, (int)ms.Position);
229 internal static MetadataSet LoadMetadataFromString (string doc)
231 var buffer = Encoding.UTF8.GetBytes (doc);
232 using (var ms = new MemoryStream (buffer)) {
233 var reader = new XmlTextReader (ms);
234 return MetadataSet.ReadFrom (reader);
238 public static MetadataSet RoundTrip (string name)
240 var metadata = MetadataSamples.GetMetadataByName (name);
242 var doc = SaveMetadataToString (metadata);
243 return LoadMetadataFromString (doc);
246 public static void GenerateConfig (MetadataSet metadata, SysConfig config)
248 WsdlImporter importer = new WsdlImporter (metadata);
250 var endpoints = importer.ImportAllEndpoints ();
252 var generator = new ServiceContractGenerator (config);
253 generator.Options = ServiceContractGenerationOptions.None;
255 foreach (var endpoint in endpoints) {
256 ChannelEndpointElement channelElement;
257 generator.GenerateServiceEndpoint (endpoint, out channelElement);
261 public static void GenerateConfig (string filename, MetadataSet metadata)
263 var fileMap = new ExeConfigurationFileMap ();
264 fileMap.ExeConfigFilename = filename;
265 var config = ConfigurationManager.OpenMappedExeConfiguration (
266 fileMap, ConfigurationUserLevel.None);
268 GenerateConfig (metadata, config);
269 config.Save (ConfigurationSaveMode.Minimal);
270 NormalizeConfig (filename);
273 internal static string SaveConfigToString (MetadataSet metadata)
275 var filename = Path.GetTempFileName ();
276 File.Delete (filename);
279 GenerateConfig (filename, metadata);
281 using (var reader = new StreamReader (filename))
282 return reader.ReadToEnd ();
284 File.Delete (filename);
288 public static void NormalizeConfig (string filename)
290 // Mono-specific hack.
291 if (Environment.OSVersion.Platform == PlatformID.Win32NT)
294 var doc = new XmlDocument ();
296 var nav = doc.CreateNavigator ();
298 var empty = new List<XPathNavigator> ();
299 var iter = nav.Select ("/configuration/system.serviceModel//*");
300 foreach (XPathNavigator node in iter) {
301 if (!node.HasChildren && !node.HasAttributes && string.IsNullOrEmpty (node.Value))
304 foreach (var node in empty)
307 var settings = new XmlWriterSettings ();
308 settings.Indent = true;
309 settings.NewLineHandling = NewLineHandling.Replace;
311 using (var writer = XmlWriter.Create (filename, settings)) {
312 doc.WriteTo (writer);
314 Console.WriteLine ();