From f06449a0fdbea147f44c556ee2814f89598860be Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Thu, 22 Dec 2011 16:54:23 +0000 Subject: [PATCH] Generate WCF proxy file from Add Service Reference dialog. --- .../Project/ICSharpCode.SharpDevelop.csproj | 16 +++ .../AddServiceReferenceViewModel.cs | 28 ++-- .../ServiceReference/ICodeDomProvider.cs | 15 ++ .../ServiceReference/IFileSystem.cs | 12 ++ .../IProjectWithServiceReferences.cs | 17 +++ .../IServiceReferenceCodeDomBuilder.cs | 15 ++ .../IServiceReferenceProxyGenerator.cs | 15 ++ .../ProjectWithServiceReferences.cs | 80 +++++++++++ .../ServiceReferenceCodeDomBuilder.cs | 25 ++++ .../ServiceReferenceCodeDomProvider.cs | 42 ++++++ .../ServiceReferenceFileSystem.cs | 18 +++ .../ServiceReferenceGenerator.cs | 66 +++++++++ .../ServiceReferenceProxyGenerator.cs | 42 ++++++ .../ServiceReference/WebServiceMetadataSet.cs | 50 +++++++ .../Commands/ReferenceFolderNodeCommands.cs | 16 +-- .../ICSharpCode.SharpDevelop.Tests.csproj | 7 + .../ProjectWithServiceReferencesTests.cs | 131 ++++++++++++++++++ .../ServiceReferenceGeneratorTests.cs | 88 ++++++++++++ .../ServiceReferenceProxyGeneratorTests.cs | 52 +++++++ .../WebServiceMetadataSetTests.cs | 97 +++++++++++++ 20 files changed, 811 insertions(+), 21 deletions(-) create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ICodeDomProvider.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IFileSystem.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IProjectWithServiceReferences.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IServiceReferenceCodeDomBuilder.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IServiceReferenceProxyGenerator.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ProjectWithServiceReferences.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceCodeDomBuilder.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceCodeDomProvider.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceFileSystem.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceGenerator.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceProxyGenerator.cs create mode 100644 src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/WebServiceMetadataSet.cs create mode 100644 src/Main/Base/Test/ServiceReferences/ProjectWithServiceReferencesTests.cs create mode 100644 src/Main/Base/Test/ServiceReferences/ServiceReferenceGeneratorTests.cs create mode 100644 src/Main/Base/Test/ServiceReferences/ServiceReferenceProxyGeneratorTests.cs create mode 100644 src/Main/Base/Test/ServiceReferences/WebServiceMetadataSetTests.cs diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index b01e8bbd10..9f6f5e3623 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -28,6 +28,7 @@ v4.0 + ICSharpCode.SharpDevelop Full @@ -60,6 +61,9 @@ + + 3.0 + @@ -265,6 +269,18 @@ Code + + + + + + + + + + + + ToolNotFoundDialog.cs diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs index 3abcca6c60..c8730795da 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs @@ -1,11 +1,6 @@ -/* - * Created by SharpDevelop. - * User: Peter Forstmeier - * Date: 12.10.2011 - * Time: 20:05 - * - * To change this template use Tools | Options | Coding | Edit Standard Headers. - */ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + using System; using System.Collections; using System.Collections.Generic; @@ -23,21 +18,18 @@ using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; using System.Windows.Media.Imaging; - using ICSharpCode.Core; using ICSharpCode.Core.Presentation; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.SharpDevelop.Project.Commands; using ICSharpCode.SharpDevelop.Widgets; using ICSharpCode.SharpDevelop.Widgets.Resources; using Microsoft.Win32; namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference { - /// - /// Description of AddServiceReferenceViewModel. - /// - public class AddServiceReferenceViewModel:ViewModelBase + public class AddServiceReferenceViewModel : ViewModelBase { string header1 = "To see a list of available services on a specific server, "; string header2 = "enter a service URL and click Go. To browse for available services click Discover."; @@ -61,6 +53,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference ServiceDescriptionCollection serviceDescriptionCollection = new ServiceDescriptionCollection(); CredentialCache credentialCache = new CredentialCache(); WebServiceDiscoveryClientProtocol discoveryClientProtocol; + WebServiceMetadataSet serviceMetadata; delegate DiscoveryDocument DiscoverAnyAsync(string url); delegate void DiscoveredWebServicesHandler(DiscoveryClientProtocol protocol); @@ -248,6 +241,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference { if (protocol != null) { serviceDescriptionCollection = ServiceReferenceHelper.GetServiceDescriptions(protocol); + serviceMetadata = new WebServiceMetadataSet(protocol); ServiceDescriptionMessage = String.Format("{0} service(s) found at address {1}", serviceDescriptionCollection.Count, @@ -402,6 +396,14 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference } ServiceItems = items; } + + public void AddServiceReference() + { + var serviceGenerator = new ServiceReferenceGenerator(project); + serviceGenerator.Namespace = defaultNameSpace; + serviceGenerator.AddServiceReference(serviceMetadata); + new RefreshProjectBrowser().Run(); + } } diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ICodeDomProvider.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ICodeDomProvider.cs new file mode 100644 index 0000000000..4400ed3f46 --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ICodeDomProvider.cs @@ -0,0 +1,15 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public interface ICodeDomProvider + { + string FileExtension { get; } + + void GenerateCodeFromCompileUnit(CodeCompileUnit compileUnit, string fileName); + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IFileSystem.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IFileSystem.cs new file mode 100644 index 0000000000..1614e97327 --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IFileSystem.cs @@ -0,0 +1,12 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public interface IFileSystem + { + void CreateDirectoryIfMissing(string path); + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IProjectWithServiceReferences.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IProjectWithServiceReferences.cs new file mode 100644 index 0000000000..4b3831a6a5 --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IProjectWithServiceReferences.cs @@ -0,0 +1,17 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public interface IProjectWithServiceReferences + { + string ServiceReferencesFolder { get; } + ICodeDomProvider CodeDomProvider { get; } + + string GetServiceReferenceFileName(string serviceReferenceName); + void AddServiceReferenceProxyFile(string fileName); + void Save(); + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IServiceReferenceCodeDomBuilder.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IServiceReferenceCodeDomBuilder.cs new file mode 100644 index 0000000000..e62d7e24de --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IServiceReferenceCodeDomBuilder.cs @@ -0,0 +1,15 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom; +using System.ServiceModel.Description; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public interface IServiceReferenceCodeDomBuilder + { + CodeCompileUnit GenerateCompileUnit(MetadataSet metadata); + + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IServiceReferenceProxyGenerator.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IServiceReferenceProxyGenerator.cs new file mode 100644 index 0000000000..9c3d2c31d0 --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IServiceReferenceProxyGenerator.cs @@ -0,0 +1,15 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.ServiceModel.Description; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public interface IServiceReferenceProxyGenerator + { + string ServiceReferenceNamespace { get; set; } + + void GenerateProxy(MetadataSet metadata, string proxyFileName); + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ProjectWithServiceReferences.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ProjectWithServiceReferences.cs new file mode 100644 index 0000000000..8e62a6aaa3 --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ProjectWithServiceReferences.cs @@ -0,0 +1,80 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom.Compiler; +using System.IO; +using ICSharpCode.SharpDevelop.Project; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public class ProjectWithServiceReferences : IProjectWithServiceReferences + { + IProject project; + string serviceReferencesFolder; + + public static readonly string DefaultServiceReferencesFolderName = "Service References"; + + public ProjectWithServiceReferences(IProject project) + : this(project, new ServiceReferenceCodeDomProvider(project)) + { + } + + public ProjectWithServiceReferences(IProject project, ICodeDomProvider codeDomProvider) + { + this.project = project; + this.CodeDomProvider = codeDomProvider; + } + + public string ServiceReferencesFolder { + get { + if (serviceReferencesFolder == null) { + GetServiceReferencesFolder(); + } + return serviceReferencesFolder; + } + } + + void GetServiceReferencesFolder() + { + serviceReferencesFolder = Path.Combine(project.Directory, DefaultServiceReferencesFolderName); + } + + public ICodeDomProvider CodeDomProvider { get; private set; } + + public string GetServiceReferenceFileName(string serviceReferenceName) + { + return Path.Combine(ServiceReferencesFolder, serviceReferenceName, "Reference.cs"); + } + + public void AddServiceReferenceProxyFile(string fileName) + { + AddServiceReferenceFileToProject(fileName); + AddServiceReferencesItemToProject(); + } + + void AddServiceReferenceFileToProject(string fileName) + { + var projectItem = new FileProjectItem(project, ItemType.Compile); + projectItem.FileName = fileName; + AddProjectItemToProject(projectItem); + } + + void AddProjectItemToProject(ProjectItem item) + { + ProjectService.AddProjectItem(project, item); + } + + void AddServiceReferencesItemToProject() + { + var projectItem = new ServiceReferencesProjectItem(project); + projectItem.Include = "Service References"; + AddProjectItemToProject(projectItem); + } + + public void Save() + { + project.Save(); + } + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceCodeDomBuilder.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceCodeDomBuilder.cs new file mode 100644 index 0000000000..db3b3f727d --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceCodeDomBuilder.cs @@ -0,0 +1,25 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom; +using System.ServiceModel.Description; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public class ServiceReferenceCodeDomBuilder : IServiceReferenceCodeDomBuilder + { + public CodeCompileUnit GenerateCompileUnit(MetadataSet metadata) + { + var importer = new WsdlImporter(metadata); + var contractGenerator = new ServiceContractGenerator(); + contractGenerator.Options = ServiceContractGenerationOptions.ClientClass; + + foreach (ContractDescription contract in importer.ImportAllContracts()) { + contractGenerator.GenerateServiceContractType(contract); + } + + return contractGenerator.TargetCompileUnit; + } + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceCodeDomProvider.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceCodeDomProvider.cs new file mode 100644 index 0000000000..953cff83b6 --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceCodeDomProvider.cs @@ -0,0 +1,42 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.IO; +using ICSharpCode.SharpDevelop.Project; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public class ServiceReferenceCodeDomProvider : ICodeDomProvider + { + IProject project; + CodeDomProvider codeDomProvider; + + public ServiceReferenceCodeDomProvider(IProject project) + { + this.project = project; + } + + public string FileExtension { + get { return CodeDomProvider.FileExtension; } + } + + CodeDomProvider CodeDomProvider { + get { + if (codeDomProvider == null) { + codeDomProvider = project.LanguageProperties.CodeDomProvider; + } + return codeDomProvider; + } + } + + public void GenerateCodeFromCompileUnit(CodeCompileUnit compileUnit, string fileName) + { + using (var writer = new StreamWriter(fileName)) { + CodeDomProvider.GenerateCodeFromCompileUnit(compileUnit, writer, null); + } + } + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceFileSystem.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceFileSystem.cs new file mode 100644 index 0000000000..1455e129c1 --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceFileSystem.cs @@ -0,0 +1,18 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public class ServiceReferenceFileSystem : IFileSystem + { + public void CreateDirectoryIfMissing(string path) + { + if (!Directory.Exists(path)) { + Directory.CreateDirectory(path); + } + } + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceGenerator.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceGenerator.cs new file mode 100644 index 0000000000..0f0fb6aac8 --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceGenerator.cs @@ -0,0 +1,66 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; +using System.ServiceModel.Description; + +using ICSharpCode.SharpDevelop.Project; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public class ServiceReferenceGenerator + { + IProjectWithServiceReferences project; + IServiceReferenceProxyGenerator proxyGenerator; + IFileSystem fileSystem; + + public ServiceReferenceGenerator(IProject project) + : this(new ProjectWithServiceReferences(project)) + { + } + + public ServiceReferenceGenerator(IProjectWithServiceReferences project) + : this( + project, + new ServiceReferenceProxyGenerator(project.CodeDomProvider), + new ServiceReferenceFileSystem()) + { + } + + public ServiceReferenceGenerator( + IProjectWithServiceReferences project, + IServiceReferenceProxyGenerator proxyGenerator, + IFileSystem fileSystem) + { + this.project = project; + this.proxyGenerator = proxyGenerator; + this.fileSystem = fileSystem; + } + + public string Namespace { get; set; } + + public void AddServiceReference(MetadataSet metadata) + { + GenerateServiceReferenceProxy(metadata); + } + + void GenerateServiceReferenceProxy(MetadataSet metadata) + { + string fileName = project.GetServiceReferenceFileName(Namespace); + CreateFolderForFileIfFolderMissing(fileName); + + proxyGenerator.GenerateProxy(metadata, fileName); + + project.AddServiceReferenceProxyFile(fileName); + + project.Save(); + } + + void CreateFolderForFileIfFolderMissing(string fileName) + { + string folder = Path.GetDirectoryName(fileName); + fileSystem.CreateDirectoryIfMissing(folder); + } + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceProxyGenerator.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceProxyGenerator.cs new file mode 100644 index 0000000000..9b07bdf0bd --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceProxyGenerator.cs @@ -0,0 +1,42 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom; +using System.IO; +using System.ServiceModel.Description; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public class ServiceReferenceProxyGenerator : IServiceReferenceProxyGenerator + { + IServiceReferenceCodeDomBuilder codeDomBuilder; + ICodeDomProvider codeDomProvider; + + public ServiceReferenceProxyGenerator(ICodeDomProvider codeDomProvider) + : this(codeDomProvider, new ServiceReferenceCodeDomBuilder()) + { + } + + public ServiceReferenceProxyGenerator( + ICodeDomProvider codeDomProvider, + IServiceReferenceCodeDomBuilder codeDomBuilder) + { + this.codeDomProvider = codeDomProvider; + this.codeDomBuilder = codeDomBuilder; + } + + public string ServiceReferenceNamespace { get; set; } + + public void GenerateProxy(MetadataSet metadata, string proxyFileName) + { + CodeCompileUnit compileUnit = codeDomBuilder.GenerateCompileUnit(metadata); + GenerateProxy(compileUnit, proxyFileName); + } + + void GenerateProxy(CodeCompileUnit compileUnit, string fileName) + { + codeDomProvider.GenerateCodeFromCompileUnit(compileUnit, fileName); + } + } +} diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/WebServiceMetadataSet.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/WebServiceMetadataSet.cs new file mode 100644 index 0000000000..8ecedfc9a1 --- /dev/null +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/WebServiceMetadataSet.cs @@ -0,0 +1,50 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.ServiceModel.Description; +using System.Xml.Schema; + +using WSDescription = System.Web.Services.Description; +using WSDiscovery = System.Web.Services.Discovery; + +namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference +{ + public class WebServiceMetadataSet : MetadataSet + { + public static readonly string EmptyMetadataIdentifier = String.Empty; + + public WebServiceMetadataSet(WSDiscovery.DiscoveryClientProtocol discoveryClient) + { + AddToMetadata(discoveryClient.Documents); + } + + void AddToMetadata(WSDiscovery.DiscoveryClientDocumentCollection documents) + { + foreach (object document in documents.Values) { + AddToMetadataIfNotNull(document as WSDescription.ServiceDescription); + AddToMetadataIfNotNull(document as XmlSchema); + } + } + + void AddToMetadataIfNotNull(WSDescription.ServiceDescription serviceDescription) + { + if (serviceDescription != null) { + AddMetadataSection(MetadataSection.ServiceDescriptionDialect, serviceDescription); + } + } + + void AddMetadataSection(string dialect, object metadata) + { + var metadataSection = new MetadataSection(dialect, EmptyMetadataIdentifier, metadata); + MetadataSections.Add(metadataSection); + } + + void AddToMetadataIfNotNull(XmlSchema schema) + { + if (schema != null) { + AddMetadataSection(MetadataSection.XmlSchemaDialect, schema); + } + } + } +} \ No newline at end of file diff --git a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs index a8ccf83426..ea770cddbe 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs @@ -227,23 +227,23 @@ namespace ICSharpCode.SharpDevelop.Project.Commands } - public class AddServiceReferenceToProject: AbstractMenuCommand + public class AddServiceReferenceToProject : AbstractMenuCommand { -// private static string NodePath = "//system.serviceModel//client//endpoint"; - public override void Run() { - AbstractProjectBrowserTreeNode node = Owner as AbstractProjectBrowserTreeNode; + var node = Owner as AbstractProjectBrowserTreeNode; IProject project = (node != null) ? node.Project : ProjectService.CurrentProject; if (project == null) { return; } var vm = new AddServiceReferenceViewModel(project); - AddServiceReferenceDialog o = new AddServiceReferenceDialog(); - o.DataContext = vm; - o.Owner = WorkbenchSingleton.MainWindow; - var b = o.ShowDialog(); + var dialog = new AddServiceReferenceDialog(); + dialog.DataContext = vm; + dialog.Owner = WorkbenchSingleton.MainWindow; + if (dialog.ShowDialog() ?? true) { + vm.AddServiceReference(); + } } } diff --git a/src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj b/src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj index 5fa06efc2b..1f7bb1f89d 100644 --- a/src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj +++ b/src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj @@ -47,6 +47,9 @@ + + 3.0 + @@ -95,9 +98,13 @@ + + + + diff --git a/src/Main/Base/Test/ServiceReferences/ProjectWithServiceReferencesTests.cs b/src/Main/Base/Test/ServiceReferences/ProjectWithServiceReferencesTests.cs new file mode 100644 index 0000000000..ad7a2496d7 --- /dev/null +++ b/src/Main/Base/Test/ServiceReferences/ProjectWithServiceReferencesTests.cs @@ -0,0 +1,131 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.Linq; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference; +using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.SharpDevelop.Tests.WebReferences; +using Microsoft.CSharp; +using NUnit.Framework; +using Rhino.Mocks; + +namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences +{ + [TestFixture] + public class ProjectWithServiceReferencesTests + { + IProject fakeProject; + ProjectWithServiceReferences project; + List projectItemsAddedToProject; + MSBuildBasedProject msbuildProject; + + void CreateProject() + { + projectItemsAddedToProject = new List(); + fakeProject = MockRepository.GenerateStub(); + project = new ProjectWithServiceReferences(fakeProject); + } + + void CreateProjectWithMSBuildProject() + { + msbuildProject = WebReferenceTestHelper.CreateTestProject("C#"); + project = new ProjectWithServiceReferences(msbuildProject); + } + + void SetProjectDirectory(string directory) + { + fakeProject.Stub(p => p.Directory).Return(directory); + } + + void SetProjectCodeDomProvider(LanguageProperties languageProperties) + { + fakeProject.Stub(p => p.LanguageProperties).Return(languageProperties); + } + + ProjectItem GetFirstServiceReferenceFileInMSBuildProject(string fileName) + { + return msbuildProject.Items.SingleOrDefault(item => item.FileName == fileName); + } + + ServiceReferencesProjectItem GetFirstWCFMetadataItemInMSBuildProject() + { + return msbuildProject.GetItemsOfType(ItemType.ServiceReferences).SingleOrDefault() as ServiceReferencesProjectItem; + } + + [Test] + public void ServiceReferencesFolder_ProjectHasNoServiceReferences_ReturnsServiceReferencesFolderAsProjectSubFolder() + { + CreateProject(); + SetProjectDirectory(@"d:\projects\MyProject"); + + string folder = project.ServiceReferencesFolder; + string expectedFolder = @"d:\projects\MyProject\Service References"; + + Assert.AreEqual(expectedFolder, folder); + } + + [Test] + public void CodeDomProvider_UnderlyingProjectUsesCSharpCodeDomProvider_ProjectUsesCSharpCodeDomProvider() + { + CreateProject(); + SetProjectCodeDomProvider(LanguageProperties.CSharp); + + ICodeDomProvider codeDomProvider = project.CodeDomProvider; + string fileExtension = codeDomProvider.FileExtension; + + Assert.AreEqual("cs", fileExtension); + } + + [Test] + public void GetServiceReferenceProxyFileName_ProjectHasNoServiceReferences_ReturnsFileNameInServiceReferencesFolderWithSubFolderNamedAfterServiceReference() + { + CreateProject(); + SetProjectDirectory(@"d:\projects\MyProject"); + + string fileName = project.GetServiceReferenceFileName("Service1"); + string expectedFileName = @"d:\projects\MyProject\Service References\Service1\Reference.cs"; + + Assert.AreEqual(expectedFileName, fileName); + } + + [Test] + public void AddServiceReferenceProxyFile_ProjectHasNoServiceReferences_ProxyFileAddedToProjectAsFileToCompile() + { + CreateProjectWithMSBuildProject(); + + string proxyFileName = @"d:\projects\MyProject\Service References\Service1\Reference.cs"; + project.AddServiceReferenceProxyFile(proxyFileName); + + ProjectItem item = GetFirstServiceReferenceFileInMSBuildProject(proxyFileName); + + Assert.AreEqual(ItemType.Compile, item.ItemType); + } + + [Test] + public void Save_SaveProjectChanges_UnderlyingProjectIsSaved() + { + CreateProject(); + + project.Save(); + + fakeProject.AssertWasCalled(p => p.Save()); + } + + [Test] + public void AddServiceReferenceProxyFile_ProjectHasNoServiceReferences_WCFMetadataItemAddedToProjectForServiceReferencesFolder() + { + CreateProjectWithMSBuildProject(); + + string proxyFileName = @"d:\projects\MyProject\Service References\Service1\Reference.cs"; + project.AddServiceReferenceProxyFile(proxyFileName); + + ServiceReferencesProjectItem item = GetFirstWCFMetadataItemInMSBuildProject(); + + Assert.AreEqual("Service References", item.Include); + } + } +} diff --git a/src/Main/Base/Test/ServiceReferences/ServiceReferenceGeneratorTests.cs b/src/Main/Base/Test/ServiceReferences/ServiceReferenceGeneratorTests.cs new file mode 100644 index 0000000000..b4b44cc173 --- /dev/null +++ b/src/Main/Base/Test/ServiceReferences/ServiceReferenceGeneratorTests.cs @@ -0,0 +1,88 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.ServiceModel.Description; +using ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference; +using ICSharpCode.SharpDevelop.Project; +using NUnit.Framework; +using Rhino.Mocks; + +namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences +{ + [TestFixture] + public class ServiceReferenceGeneratorTests + { + IProjectWithServiceReferences fakeProject; + IServiceReferenceProxyGenerator fakeProxyGenerator; + ServiceReferenceGenerator generator; + IFileSystem fakeFileSystem; + MetadataSet metadata; + + void CreateGenerator() + { + metadata = new MetadataSet(); + + fakeProject = MockRepository.GenerateStub(); + fakeProxyGenerator = MockRepository.GenerateStub(); + fakeFileSystem = MockRepository.GenerateStub(); + generator = new ServiceReferenceGenerator(fakeProject, fakeProxyGenerator, fakeFileSystem); + } + + void SetServiceReferenceFileName(string serviceReferenceName, string fileName) + { + fakeProject.Stub(p => p.GetServiceReferenceFileName(serviceReferenceName)).Return(fileName); + } + + [Test] + public void AddServiceReference_GeneratesServiceReference_MetadataPassedToProxyGenerator() + { + CreateGenerator(); + string expectedProxyFileName = @"d:\projects\MyProject\Service References\MyServiceRef\Reference.cs"; + SetServiceReferenceFileName("MyServiceRef", expectedProxyFileName); + generator.Namespace = "MyServiceRef"; + + generator.AddServiceReference(metadata); + + fakeProxyGenerator.AssertWasCalled(p => p.GenerateProxy(metadata, expectedProxyFileName)); + } + + [Test] + public void AddServiceReference_ServiceReferenceDoesNotExist_ServiceReferenceFolderCreated() + { + CreateGenerator(); + string proxyFileName = @"d:\projects\MyProject\Service References\MyService1\Reference.cs"; + SetServiceReferenceFileName("MyService1", proxyFileName); + generator.Namespace = "MyService1"; + + generator.AddServiceReference(metadata); + + string expectedDirectory = @"d:\projects\MyProject\Service References\MyService1"; + + fakeFileSystem.AssertWasCalled(f => f.CreateDirectoryIfMissing(expectedDirectory)); + } + + [Test] + public void AddServiceReference_GeneratesServiceReference_ServiceReferenceProxyFileAddedToProject() + { + CreateGenerator(); + string expectedProxyFileName = @"d:\projects\MyProject\Service References\MyServiceRef\Reference.cs"; + SetServiceReferenceFileName("MyServiceRef", expectedProxyFileName); + generator.Namespace = "MyServiceRef"; + + generator.AddServiceReference(metadata); + + fakeProject.AssertWasCalled(p => p.AddServiceReferenceProxyFile(expectedProxyFileName)); + } + + [Test] + public void AddServiceReference_GeneratesServiceReference_ProjectIsSaved() + { + CreateGenerator(); + + generator.AddServiceReference(metadata); + + fakeProject.AssertWasCalled(p => p.Save()); + } + } +} diff --git a/src/Main/Base/Test/ServiceReferences/ServiceReferenceProxyGeneratorTests.cs b/src/Main/Base/Test/ServiceReferences/ServiceReferenceProxyGeneratorTests.cs new file mode 100644 index 0000000000..de26d1ae1d --- /dev/null +++ b/src/Main/Base/Test/ServiceReferences/ServiceReferenceProxyGeneratorTests.cs @@ -0,0 +1,52 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom; +using System.ServiceModel.Description; +using ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference; +using NUnit.Framework; +using Rhino.Mocks; + +namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences +{ + [TestFixture] + public class ServiceReferenceProxyGeneratorTests + { + ServiceReferenceProxyGenerator proxyGenerator; + IProjectWithServiceReferences fakeProject; + IServiceReferenceCodeDomBuilder fakeCodeDomBuilder; + ICodeDomProvider fakeCodeDomProvider; + MetadataSet metadata; + + void CreateProxyGenerator() + { + metadata = new MetadataSet(); + + fakeCodeDomBuilder = MockRepository.GenerateStub(); + fakeProject = MockRepository.GenerateStub(); + fakeCodeDomProvider = MockRepository.GenerateStub(); + proxyGenerator = new ServiceReferenceProxyGenerator(fakeCodeDomProvider, fakeCodeDomBuilder); + } + + CodeCompileUnit CreateCompileUnitToReturnFromCodeDomBuilder(MetadataSet metadata) + { + var compileUnit = new CodeCompileUnit(); + fakeCodeDomBuilder.Stub(c => c.GenerateCompileUnit(metadata)).Return(compileUnit); + return compileUnit; + } + + [Test] + public void GenerateProxy_ProxyToBeGeneratedForMetadata_CodeGeneratedFromCodeDomForProxyFileInProjectSubFolder() + { + CreateProxyGenerator(); + CodeCompileUnit compileUnit = CreateCompileUnitToReturnFromCodeDomBuilder(metadata); + proxyGenerator.ServiceReferenceNamespace = "Test"; + string expectedProxyFileName = @"d:\projects\MyProject\Service References\Test\Service1\Reference.cs"; + + proxyGenerator.GenerateProxy(metadata, expectedProxyFileName); + + fakeCodeDomProvider.AssertWasCalled(p => p.GenerateCodeFromCompileUnit(compileUnit, expectedProxyFileName)); + } + } +} diff --git a/src/Main/Base/Test/ServiceReferences/WebServiceMetadataSetTests.cs b/src/Main/Base/Test/ServiceReferences/WebServiceMetadataSetTests.cs new file mode 100644 index 0000000000..ab8695de2e --- /dev/null +++ b/src/Main/Base/Test/ServiceReferences/WebServiceMetadataSetTests.cs @@ -0,0 +1,97 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Linq; +using System.ServiceModel.Description; +using System.Web.Services.Discovery; +using System.Xml.Schema; +using ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference; +using NUnit.Framework; +using WSDescription = System.Web.Services.Description; +using WSDiscovery = System.Web.Services.Discovery; + +namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences +{ + [TestFixture] + public class WebServiceMetadataSetTests + { + DiscoveryClientProtocol discoveryProtocol; + WebServiceMetadataSet metadata; + + void CreateDiscoveryProtocol() + { + discoveryProtocol = new DiscoveryClientProtocol(); + } + + WSDescription.ServiceDescription AddServiceDescriptionToDiscoveryProtocol() + { + var serviceDescription = new WSDescription.ServiceDescription(); + discoveryProtocol.Documents.Add("http://ServiceDescription", serviceDescription); + return serviceDescription; + } + + void CreateMetadata() + { + metadata = new WebServiceMetadataSet(discoveryProtocol); + } + + XmlSchema AddXmlSchemaToDiscoveryProtocol() + { + var schema = new XmlSchema(); + discoveryProtocol.Documents.Add("http://XmlSchema", schema); + return schema; + } + + [Test] + public void Constructor_DiscoveryProtocolHasOneServiceDescription_ServiceDescriptionAddedToMetadata() + { + CreateDiscoveryProtocol(); + WSDescription.ServiceDescription serviceDescription = + AddServiceDescriptionToDiscoveryProtocol(); + CreateMetadata(); + + MetadataSection section = metadata.MetadataSections.First(); + + Assert.AreEqual(serviceDescription, section.Metadata); + } + + [Test] + public void Constructor_DiscoveryProtocolHasOneServiceDescription_ServiceDescriptionMetadataHasServiceDescriptionDialect() + { + CreateDiscoveryProtocol(); + WSDescription.ServiceDescription serviceDescription = + AddServiceDescriptionToDiscoveryProtocol(); + CreateMetadata(); + + MetadataSection section = metadata.MetadataSections.First(); + + Assert.AreEqual(MetadataSection.ServiceDescriptionDialect, section.Dialect); + } + + [Test] + public void Constructor_DiscoveryProtocolHasOneXmlSchema_XmlSchemaAddedToMetadata() + { + CreateDiscoveryProtocol(); + XmlSchema schema = AddXmlSchemaToDiscoveryProtocol(); + CreateMetadata(); + + MetadataSection section = metadata.MetadataSections.First(); + + Assert.AreEqual(schema, section.Metadata); + } + + [Test] + public void Constructor_DiscoveryProtocolHasOneXmlSchema_XmlSchemaAddedToMetadataHasXmlSchemaDialect() + { + CreateDiscoveryProtocol(); + XmlSchema schema = AddXmlSchemaToDiscoveryProtocol(); + CreateMetadata(); + + MetadataSection section = metadata.MetadataSections.First(); + + Assert.AreEqual(MetadataSection.XmlSchemaDialect, section.Dialect); + } + + } +}