Browse Source

When creating a service reference use and update the app.config file that is open in the text editor.

pull/6/merge
Matt Ward 14 years ago
parent
commit
e20bee14dd
  1. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  2. 45
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ActiveTextEditors.cs
  3. 14
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IActiveTextEditors.cs
  4. 4
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IFileSystem.cs
  5. 2
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IServiceReferenceProxyGenerator.cs
  6. 5
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceFileGenerator.cs
  7. 23
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceFileSystem.cs
  8. 54
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceGenerator.cs
  9. 10
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceProxyGenerator.cs
  10. 15
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/SvcUtilRunner.cs
  11. 175
      src/Main/Base/Test/ServiceReferences/ServiceReferenceGeneratorTests.cs

2
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -261,6 +261,7 @@ @@ -261,6 +261,7 @@
<Compile Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\StorageLocationConverter.cs" />
<Compile Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\StorageLocationPicker.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReferenceHelper.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\ActiveTextEditors.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\AddServiceReferenceDialog.xaml.cs">
<DependentUpon>AddServiceReferenceDialog.xaml</DependentUpon>
<SubType>Code</SubType>
@ -272,6 +273,7 @@ @@ -272,6 +273,7 @@
</Compile>
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\AdvancedServiceViewModel.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\ClientOptions.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\IActiveTextEditors.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\IFileSystem.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\IProjectWithServiceReferences.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\IServiceReferenceFileGenerator.cs" />

45
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ActiveTextEditors.cs

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
// 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 ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
{
public class ActiveTextEditors : IActiveTextEditors
{
public string GetTextForOpenFile(string fileName)
{
ITextEditor textEditor = GetTextEditor(fileName);
if (textEditor != null) {
return textEditor.Document.Text;
}
return null;
}
ITextEditor GetTextEditor(string fileName)
{
IViewContent viewContent = FileService.GetOpenFile(fileName);
var textEditorProvider = viewContent as ITextEditorProvider;
if (textEditorProvider != null) {
return textEditorProvider.TextEditor;
}
return null;
}
public void UpdateTextForOpenFile(string fileName, string text)
{
ITextEditor textEditor = GetTextEditor(fileName);
if (textEditor != null) {
using (IDisposable undoGroup = textEditor.Document.OpenUndoGroup()) {
textEditor.Document.Text = text;
}
}
}
public bool IsFileOpen(string fileName)
{
return FileService.IsOpen(fileName);
}
}
}

14
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IActiveTextEditors.cs

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
// 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 IActiveTextEditors
{
string GetTextForOpenFile(string fileName);
void UpdateTextForOpenFile(string fileName, string text);
bool IsFileOpen(string fileName);
}
}

4
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IFileSystem.cs

@ -8,5 +8,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -8,5 +8,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
public interface IFileSystem
{
void CreateDirectoryIfMissing(string path);
string CreateTempFile(string text);
string ReadAllFileText(string fileName);
void DeleteFile(string fileName);
void WriteAllText(string fileName, string text);
}
}

2
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/IServiceReferenceProxyGenerator.cs

@ -10,5 +10,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -10,5 +10,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
{
ServiceReferenceGeneratorOptions Options { get; set; }
void GenerateProxyFile();
event EventHandler Complete;
}
}

5
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceFileGenerator.cs

@ -40,5 +40,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -40,5 +40,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
{
mapGenerator.GenerateServiceReferenceMapFile(mapFile);
}
public event EventHandler Complete {
add { proxyGenerator.Complete += value; }
remove { proxyGenerator.Complete += value; }
}
}
}

23
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceFileSystem.cs

@ -14,5 +14,28 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -14,5 +14,28 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
Directory.CreateDirectory(path);
}
}
public string CreateTempFile(string text)
{
string folder = Path.GetTempPath();
string fileName = Path.Combine(folder, "app.config");
File.WriteAllText(fileName, text);
return fileName;
}
public string ReadAllFileText(string fileName)
{
return File.ReadAllText(fileName);
}
public void DeleteFile(string fileName)
{
File.Delete(fileName);
}
public void WriteAllText(string fileName, string text)
{
File.WriteAllText(fileName, text);
}
}
}

54
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceGenerator.cs

@ -16,6 +16,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -16,6 +16,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
IProjectWithServiceReferences project;
IServiceReferenceFileGenerator fileGenerator;
IFileSystem fileSystem;
IActiveTextEditors activeTextEditors;
string tempAppConfigFileName;
public ServiceReferenceGenerator(IProject project)
: this(new ProjectWithServiceReferences(project))
@ -26,18 +28,21 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -26,18 +28,21 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
: this(
project,
new ServiceReferenceFileGenerator(),
new ServiceReferenceFileSystem())
new ServiceReferenceFileSystem(),
new ActiveTextEditors())
{
}
public ServiceReferenceGenerator(
IProjectWithServiceReferences project,
IServiceReferenceFileGenerator fileGenerator,
IFileSystem fileSystem)
IFileSystem fileSystem,
IActiveTextEditors activeTextEditors)
{
this.project = project;
this.fileGenerator = fileGenerator;
this.fileSystem = fileSystem;
this.activeTextEditors = activeTextEditors;
}
public ServiceReferenceGeneratorOptions Options {
@ -68,18 +73,38 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -68,18 +73,38 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
ServiceReferenceFileName referenceFileName = project.GetServiceReferenceFileName(fileGenerator.Options.ServiceName);
CreateFolderForFileIfFolderMissing(referenceFileName.Path);
CreateTempAppConfigFileIfOpenInTextEditor();
Options.OutputFileName = referenceFileName.Path;
Options.AppConfigFileName = project.GetAppConfigFileName();
Options.AppConfigFileName = GetAppConfigFileName();
Options.NoAppConfig = false;
Options.MergeAppConfig = project.HasAppConfigFile();
Options.MapProjectLanguage(project.Language);
Options.GenerateNamespace(project.RootNamespace);
Options.AddProjectReferencesIfUsingTypesFromProjectReferences(project.GetReferences());
fileGenerator.Complete += ProxyFileGenerationComplete;
fileGenerator.GenerateProxyFile();
return referenceFileName;
}
string GetAppConfigFileName()
{
if (tempAppConfigFileName != null) {
return tempAppConfigFileName;
}
return project.GetAppConfigFileName();
}
void CreateTempAppConfigFileIfOpenInTextEditor()
{
string appConfigText = activeTextEditors.GetTextForOpenFile(project.GetAppConfigFileName());
if (appConfigText != null) {
tempAppConfigFileName = fileSystem.CreateTempFile(appConfigText);
}
}
ServiceReferenceMapFileName CreateServiceReferenceMapFile()
{
ServiceReferenceMapFileName mapFileName = project.GetServiceReferenceMapFileName(fileGenerator.Options.ServiceName);
@ -94,6 +119,29 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -94,6 +119,29 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
fileSystem.CreateDirectoryIfMissing(folder);
}
void ProxyFileGenerationComplete(object sender, EventArgs e)
{
if (tempAppConfigFileName != null) {
UpdateAppConfigInTextEditor();
DeleteTempAppConfigFile();
}
}
void DeleteTempAppConfigFile()
{
fileSystem.DeleteFile(tempAppConfigFileName);
}
void UpdateAppConfigInTextEditor()
{
string text = fileSystem.ReadAllFileText(tempAppConfigFileName);
if (activeTextEditors.IsFileOpen(project.GetAppConfigFileName())) {
activeTextEditors.UpdateTextForOpenFile(project.GetAppConfigFileName(), text);
} else {
fileSystem.WriteAllText(project.GetAppConfigFileName(), text);
}
}
public IEnumerable<CheckableAssemblyReference> GetCheckableAssemblyReferences()
{
return GetUnsortedCheckableAssemblyReferences()

10
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceProxyGenerator.cs

@ -20,7 +20,17 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -20,7 +20,17 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
public void GenerateProxyFile()
{
var runner = new SvcUtilRunner(options);
runner.ProcessExited += OnComplete;
runner.Run();
}
public event EventHandler Complete;
void OnComplete(object sender, EventArgs e)
{
if (Complete != null) {
Complete(this, e);
}
}
}
}

15
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/SvcUtilRunner.cs

@ -13,6 +13,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -13,6 +13,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
this.Options = options;
}
public event EventHandler ProcessExited;
public ServiceReferenceGeneratorOptions Options { get; private set; }
public void Run()
@ -48,7 +50,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -48,7 +50,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
runner.LogStandardOutputAndError = false;
runner.OutputLineReceived += LineReceived;
runner.ErrorLineReceived += LineReceived;
runner.ProcessExited += ProcessExited;
runner.ProcessExited += SvcUtilProcessExited;
return runner;
}
@ -57,9 +59,18 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -57,9 +59,18 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
SvcUtilMessageView.AppendLine(e.Line);
}
void ProcessExited(object sender, EventArgs e)
void SvcUtilProcessExited(object sender, EventArgs e)
{
SvcUtilMessageView.AppendLine("SvcUtil finished.");
WorkbenchSingleton.SafeThreadAsyncCall(() => OnProcessExited());
}
void OnProcessExited()
{
if (ProcessExited != null) {
ProcessExited(this, new EventArgs());
}
}
}
}

175
src/Main/Base/Test/ServiceReferences/ServiceReferenceGeneratorTests.cs

@ -23,6 +23,7 @@ namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences @@ -23,6 +23,7 @@ namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences
IFileSystem fakeFileSystem;
ServiceReferenceGeneratorOptions options;
List<ReferenceProjectItem> projectReferences;
IActiveTextEditors fakeActiveTextEditors;
void CreateGenerator()
{
@ -35,8 +36,9 @@ namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences @@ -35,8 +36,9 @@ namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences
fakeReferenceMapGenerator = MockRepository.GenerateStub<IServiceReferenceMapGenerator>();
fileGenerator = new ServiceReferenceFileGenerator(fakeProxyGenerator, fakeReferenceMapGenerator);
fakeFileSystem = MockRepository.GenerateStub<IFileSystem>();
fakeActiveTextEditors = MockRepository.GenerateStub<IActiveTextEditors>();
generator = new ServiceReferenceGenerator(fakeProject, fileGenerator, fakeFileSystem);
generator = new ServiceReferenceGenerator(fakeProject, fileGenerator, fakeFileSystem, fakeActiveTextEditors);
}
void SetProjectRootNamespace(string rootNamespace)
@ -133,6 +135,45 @@ namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences @@ -133,6 +135,45 @@ namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences
return projectItem;
}
void AppConfigIsOpenInTextEditor(string fileName, string appConfigText)
{
fakeActiveTextEditors
.Stub(editors => editors.GetTextForOpenFile(fileName))
.Return(appConfigText);
fakeActiveTextEditors
.Stub(editors => editors.IsFileOpen(fileName))
.Return(true);
}
void AppConfigIsClosedInTextEditor(string fileName)
{
fakeActiveTextEditors.BackToRecord(BackToRecordOptions.All);
fakeActiveTextEditors.Replay();
fakeActiveTextEditors
.Stub(editors => editors.IsFileOpen(fileName))
.Return(false);
}
void SetTempFileNameCreated(string tempFileName)
{
fakeFileSystem.Stub(fs => fs.CreateTempFile(Arg<string>.Is.Anything))
.Return(tempFileName);
}
void SvcUtilRunCompleted()
{
fakeProxyGenerator.Raise(g => g.Complete += null, fakeProxyGenerator, new EventArgs());
}
void SetTempFileText(string fileName, string text)
{
SetTempFileNameCreated(fileName);
fakeFileSystem
.Stub(fs => fs.ReadAllFileText(fileName))
.Return(text);
}
[Test]
public void AddServiceReference_GeneratesServiceReference_ProxyFileIsGenerated()
{
@ -450,5 +491,137 @@ namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences @@ -450,5 +491,137 @@ namespace ICSharpCode.SharpDevelop.Tests.ServiceReferences
CollectionAssert.AreEqual(expectedAssemblies, generator.Options.Assemblies);
}
[Test]
public void AddServiceReference_AppConfigIsOpenInTextEditor_TempFileCreatedWithAppConfigText()
{
CreateGenerator();
AddProxyFileNameForServiceName("MyService");
AddMapFileNameForServiceName("MyService");
generator.Options.ServiceName = "MyService";
string appConfigFileName = @"d:\projects\MyProject\app.config";
SetProjectAppConfigFileName(appConfigFileName);
ProjectHasAppConfigFile();
AppConfigIsOpenInTextEditor(appConfigFileName, "appconfig text");
generator.AddServiceReference();
fakeFileSystem.AssertWasCalled(fs => fs.CreateTempFile("appconfig text"));
}
[Test]
public void AddServiceReference_AppConfigIsNotOpenInTextEditor_TempFileNotCreated()
{
CreateGenerator();
AddProxyFileNameForServiceName("MyService");
AddMapFileNameForServiceName("MyService");
generator.Options.ServiceName = "MyService";
string appConfigFileName = @"d:\projects\MyProject\app.config";
SetProjectAppConfigFileName(appConfigFileName);
ProjectHasAppConfigFile();
generator.AddServiceReference();
fakeFileSystem.AssertWasNotCalled(fs => fs.CreateTempFile(Arg<string>.Is.Anything));
}
[Test]
public void AddServiceReference_AppConfigIsOpenInTextEditor_TempFileAppConfigPassedUsedWhenGeneratingProxy()
{
CreateGenerator();
AddProxyFileNameForServiceName("MyService");
AddMapFileNameForServiceName("MyService");
generator.Options.ServiceName = "MyService";
string appConfigFileName = @"d:\projects\MyProject\app.config";
SetProjectAppConfigFileName(appConfigFileName);
ProjectHasAppConfigFile();
AppConfigIsOpenInTextEditor(appConfigFileName, "appconfig text");
SetTempFileNameCreated(@"d:\temp\test.tmp");
generator.AddServiceReference();
Assert.AreEqual(@"d:\temp\test.tmp", fakeProxyGenerator.Options.AppConfigFileName);
}
[Test]
public void AddServiceReference_AppConfigIsOpenInTextEditorAndSvcUtilHasFinished_TempFileAppConfigContentReplacesTextInTextEditor()
{
CreateGenerator();
AddProxyFileNameForServiceName("MyService");
AddMapFileNameForServiceName("MyService");
generator.Options.ServiceName = "MyService";
string appConfigFileName = @"d:\projects\MyProject\app.config";
SetProjectAppConfigFileName(appConfigFileName);
ProjectHasAppConfigFile();
AppConfigIsOpenInTextEditor(appConfigFileName, "appconfig text");
SetTempFileText(@"d:\temp\test.tmp", "New appconfig text");
generator.AddServiceReference();
SvcUtilRunCompleted();
fakeActiveTextEditors.AssertWasCalled(editors => editors.UpdateTextForOpenFile(appConfigFileName, "New appconfig text"));
}
[Test]
public void AddServiceReference_AppConfigIsNotOpenInTextEditor_TextInTextEditorNotUpdated()
{
CreateGenerator();
AddProxyFileNameForServiceName("MyService");
AddMapFileNameForServiceName("MyService");
generator.Options.ServiceName = "MyService";
string appConfigFileName = @"d:\projects\MyProject\app.config";
SetProjectAppConfigFileName(appConfigFileName);
ProjectHasAppConfigFile();
generator.AddServiceReference();
SvcUtilRunCompleted();
fakeActiveTextEditors.AssertWasNotCalled(editors => editors.UpdateTextForOpenFile(Arg<string>.Is.Anything, Arg<string>.Is.Anything));
}
[Test]
public void AddServiceReference_AppConfigIsOpenInTextEditorAndSvcUtilHasFinished_TempFileIsDeleted()
{
CreateGenerator();
AddProxyFileNameForServiceName("MyService");
AddMapFileNameForServiceName("MyService");
generator.Options.ServiceName = "MyService";
string appConfigFileName = @"d:\projects\MyProject\app.config";
SetProjectAppConfigFileName(appConfigFileName);
ProjectHasAppConfigFile();
AppConfigIsOpenInTextEditor(appConfigFileName, "appconfig text");
SetTempFileNameCreated(@"d:\temp\test.tmp");
generator.AddServiceReference();
SvcUtilRunCompleted();
fakeFileSystem.AssertWasCalled(fs => fs.DeleteFile(@"d:\temp\test.tmp"));
}
[Test]
public void AddServiceReference_AppConfigIsOriginallyOpenInTextEditorButIsClosedWhenSvcUtilHasFinished_TempFileAppConfigContentReplacesAppConfigOnFileSystem()
{
CreateGenerator();
AddProxyFileNameForServiceName("MyService");
AddMapFileNameForServiceName("MyService");
generator.Options.ServiceName = "MyService";
string appConfigFileName = @"d:\projects\MyProject\app.config";
SetProjectAppConfigFileName(appConfigFileName);
ProjectHasAppConfigFile();
AppConfigIsOpenInTextEditor(appConfigFileName, "appconfig text");
SetTempFileText(@"d:\temp\test.tmp", "New appconfig text");
generator.AddServiceReference();
AppConfigIsClosedInTextEditor(appConfigFileName);
SvcUtilRunCompleted();
fakeFileSystem.AssertWasCalled(fs => fs.WriteAllText(appConfigFileName, "New appconfig text"));
fakeActiveTextEditors.AssertWasNotCalled(editors => editors.UpdateTextForOpenFile(Arg<string>.Is.Anything, Arg<string>.Is.Anything));
}
}
}

Loading…
Cancel
Save