Changing shell settings loader to prep for multi-tenancy work

Adding data prefix property
Moving to a different yaml library
Renaming IShellSettingsLoader and ShellSettingsLoader to ITenantManager and DefaultTenantManager
Avoiding use of MapPath in the appdatafolder abstraction

--HG--
branch : dev
This commit is contained in:
Louis DeJardin
2010-04-07 15:34:38 -07:00
parent 80007a5101
commit 476abfc409
14 changed files with 4041 additions and 97 deletions

47
lib/yaml/ChangeLog.txt Normal file
View File

@@ -0,0 +1,47 @@
--- 2009-10-04 Osamu TAKEUCHI <osamu@big.jp>
Alpha release of YamlSerializer as 0.9.0.2
* All "_"s in integer and floating point values are neglected
to accommodate the !!int and !!float encoding.
* YamlConfig.DontUseVerbatimTag is added but the default value is set false.
Note that !<!System.Int32[,]> is much human friendly than !System.Int32%5B%2C%5D.
* Equality of YamlNode with an unknown tag is evaluated by identity,
while that of !!map and !!seq node is still evaluated by YAML's standard.
Note that equality of !!map and !!seq are different from that of object[]
and Dictionary<object, object>.
* YamlConfig.OmitTagForRootNode was added. Fixed issue #2850.
* Serialize Dictionary<object,object> to !!map. Fixed #2891.
* Modified [126-130] ns-plain-???, [147] c-ns-flow-map-separate-value(n,c)
to accommodate revision 2009-10-01
* Omit !< > if Tag contains only ns-tag-char, Fixed issue #2813
--- 2009-09-23 Osamu TAKEUCHI <osamu@big.jp>
Alpha release of YamlSerializer as 0.9.0.1
* Removed TODO's for reporting bugs in YAML spec that are done.
* Fixed assembly copyright.
* !!merge is supported. Fixed issue#2605.
* Read-only class-type member with no child members are omitted when
serializing. Fixed issue#2599.
* Culture for TypeConverter is set to be CultureInfo.InvariantCulture.
Fixed issue #2629.
* To fix Issue#2631
* Field names and property names are always presented as simple texts.
* When deserializing, we can not avoid the parser parses some spacial
names to !!bool and !!null. Such non-text nodes are converted to
texts at construction stage.
* To fix issue#2663
* Hash code stored in a mapping node is now updated when the a key node's
content is changed.
* Hash code and equality became independent on the order of keys in a
mapping node.
* A mapping node checks for duplicated keys every time the node content
is changed.
* Test results are changed because some of them are dependent on the hash
key order.
* The current equality evaluation is too strict, probably needs some adjustment.
* NativeObject property was added to YamlScalar.
* YamlScalar's equality is evaluated by comparing NativeObject.
--- 2009-09-11 Osamu TAKEUCHI <osamu@big.jp>
First release of YamlSerializer as 0.9.0.0

39
lib/yaml/Readme.txt Normal file
View File

@@ -0,0 +1,39 @@
YamlSerializer 0.9.0.2 (2009-10-04) Osamu TAKEUCHI <osamu@big.jp>
Description:
A library that serialize / deserialize C# native objects into YAML1.2 text.
Development environment:
Visual C# 2008 Express Edition
Sandcastle (2008-05-29)
SandcastleBuilder 1.8.0.2
HTML Help workshop 4.74.8702
NUnit 2.5.0.9122
TestDriven.NET 2.0
Support web page:
http://yamlserializer.codeplex.com/
License:
YamlSerializer is distributed under the MIT license as following:
---
The MIT License (MIT)
Copyright (c) 2009 Osamu TAKEUCHI <osamu@big.jp>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Binary file not shown.

3770
lib/yaml/YamlSerializer.XML Normal file

File diff suppressed because it is too large Load Diff

BIN
lib/yaml/YamlSerializer.dll Normal file

Binary file not shown.

View File

@@ -77,5 +77,19 @@ namespace Orchard.Tests.Environment.Configuration {
_appDataFolder.CreateFile("alpha\\omega\\foo\\bar.txt", "quux");
Assert.That(Directory.Exists(Path.Combine(_tempFolder, "alpha\\omega\\foo")), Is.True);
}
[Test]
public void FilesCanBeReadBack() {
_appDataFolder.CreateFile("alpha\\gamma\\foo\\bar.txt", @"
this is
a
test");
var text = _appDataFolder.ReadFile("alpha\\gamma\\foo\\bar.txt");
Assert.That(text, Is.EqualTo(@"
this is
a
test"));
}
}
}

View File

@@ -0,0 +1,76 @@
using System.IO;
using System.Linq;
using NUnit.Framework;
using Orchard.Environment.Configuration;
namespace Orchard.Tests.Environment.Configuration {
[TestFixture]
public class ShellSettingsLoaderTests {
private string _tempFolder;
private AppDataFolder _appData;
[SetUp]
public void Init() {
_appData = new AppDataFolder();
_tempFolder = Path.GetTempFileName();
File.Delete(_tempFolder);
_appData.SetBasePath(_tempFolder);
}
[TearDown]
public void Term() {
Directory.Delete(_tempFolder, true);
}
[Test]
public void SingleSettingsFileShouldComeBackAsExpected() {
_appData.CreateFile("Sites\\Default\\Settings.txt", "Name: Default\r\nDataProvider: SQLite\r\nDataConnectionString: something else");
IShellSettingsLoader loader = new ShellSettingsLoader(_appData);
var settings = loader.LoadSettings().Single();
Assert.That(settings, Is.Not.Null);
Assert.That(settings.Name, Is.EqualTo("Default"));
Assert.That(settings.DataProvider, Is.EqualTo("SQLite"));
Assert.That(settings.DataConnectionString, Is.EqualTo("something else"));
}
[Test]
public void MultipleFilesCanBeDetected() {
_appData.CreateFile("Sites\\Default\\Settings.txt", "Name: Default\r\nDataProvider: SQLite\r\nDataConnectionString: something else");
_appData.CreateFile("Sites\\Another\\Settings.txt", "Name: Another\r\nDataProvider: SQLite2\r\nDataConnectionString: something else2");
IShellSettingsLoader loader = new ShellSettingsLoader(_appData);
var settings = loader.LoadSettings();
Assert.That(settings.Count(), Is.EqualTo(2));
var def = settings.Single(x => x.Name == "Default");
Assert.That(def.Name, Is.EqualTo("Default"));
Assert.That(def.DataProvider, Is.EqualTo("SQLite"));
Assert.That(def.DataConnectionString, Is.EqualTo("something else"));
var alt = settings.Single(x => x.Name == "Another");
Assert.That(alt.Name, Is.EqualTo("Another"));
Assert.That(alt.DataProvider, Is.EqualTo("SQLite2"));
Assert.That(alt.DataConnectionString, Is.EqualTo("something else2"));
}
[Test]
public void NewSettingsCanBeStored() {
_appData.CreateFile("Sites\\Default\\Settings.txt", "Name: Default\r\nDataProvider: SQLite\r\nDataConnectionString: something else");
IShellSettingsLoader loader = new ShellSettingsLoader(_appData);
var foo = new ShellSettings {Name = "Foo", DataProvider = "Bar", DataConnectionString = "Quux"};
Assert.That(loader.LoadSettings().Count(), Is.EqualTo(1));
loader.SaveSettings(foo);
Assert.That(loader.LoadSettings().Count(), Is.EqualTo(2));
var text = File.ReadAllText(_appData.MapPath("Sites\\Foo\\Settings.txt"));
Assert.That(text, Is.StringContaining("Foo"));
Assert.That(text, Is.StringContaining("Bar"));
Assert.That(text, Is.StringContaining("Quux"));
}
}
}

View File

@@ -153,6 +153,7 @@
<Compile Include="Data\StubLocator.cs" />
<Compile Include="Environment\AutofacUtil\DynamicProxy2\DynamicProxyTests.cs" />
<Compile Include="Environment\Configuration\AppDataFolderTests.cs" />
<Compile Include="Environment\Configuration\ShellSettingsLoaderTests.cs" />
<Compile Include="Environment\DefaultCompositionStrategyTests.cs" />
<Compile Include="Environment\DefaultOrchardHostTests.cs" />
<Compile Include="Environment\DefaultOrchardShellTests.cs" />

View File

@@ -15,6 +15,7 @@ namespace Orchard.Environment.Configuration {
IEnumerable<string> ListDirectories(string path);
void CreateFile(string path, string content);
string ReadFile(string path);
void DeleteFile(string path);
string CreateDirectory(string path);
@@ -26,7 +27,6 @@ namespace Orchard.Environment.Configuration {
/// </summary>
void SetBasePath(string basePath);
string MapPath(string path);
}
public class AppDataFolder : IAppDataFolder {
@@ -44,6 +44,10 @@ namespace Orchard.Environment.Configuration {
File.WriteAllText(filePath, content);
}
public string ReadFile(string path) {
return File.ReadAllText(Path.Combine(_basePath, path));
}
public void DeleteFile(string path) {
File.Delete(Path.Combine(_basePath, path));
}

View File

@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Yaml.Serialization;
using Orchard.Localization;
namespace Orchard.Environment.Configuration {
public class DefaultTenantManager : ITenantManager {
private readonly IAppDataFolder _appDataFolder;
Localizer T { get; set; }
public DefaultTenantManager(IAppDataFolder appDataFolder) {
_appDataFolder = appDataFolder;
T = NullLocalizer.Instance;
}
IEnumerable<IShellSettings> ITenantManager.LoadSettings() {
return LoadSettings().ToArray();
}
void ITenantManager.SaveSettings(IShellSettings settings) {
if (settings == null)
throw new ArgumentException(T("There are no settings to save.").ToString());
if (string.IsNullOrEmpty(settings.Name))
throw new ArgumentException(T("Settings \"Name\" is not set.").ToString());
var filePath = Path.Combine(Path.Combine("Sites", settings.Name), "Settings.txt");
_appDataFolder.CreateFile(filePath, ComposeSettings(settings));
}
IEnumerable<IShellSettings> LoadSettings() {
var filePaths = _appDataFolder
.ListDirectories("Sites")
.SelectMany(path => _appDataFolder.ListFiles(path))
.Where(path => string.Equals(Path.GetFileName(path), "Settings.txt", StringComparison.OrdinalIgnoreCase));
foreach (var filePath in filePaths) {
yield return ParseSettings(_appDataFolder.ReadFile(filePath));
}
}
class Content {
public string Name { get; set; }
public string DataProvider { get; set; }
public string DataConnectionString { get; set; }
}
static IShellSettings ParseSettings(string text) {
var ser = new YamlSerializer();
var content = ser.Deserialize(text, typeof(Content)).Cast<Content>().Single();
return new ShellSettings {
Name = content.Name,
DataProvider = content.DataProvider,
DataConnectionString = content.DataConnectionString,
DataPrefix = content.DataPrefix,
};
}
static string ComposeSettings(IShellSettings shellSettings) {
if (shellSettings == null)
return "";
var ser = new YamlSerializer();
return ser.Serialize(new Content {
Name = shellSettings.Name,
DataProvider = shellSettings.DataProvider,
DataConnectionString = shellSettings.DataConnectionString
});
}
}
}

View File

@@ -0,0 +1,8 @@
using System.Collections.Generic;
namespace Orchard.Environment.Configuration {
public interface ITenantManager {
IEnumerable<IShellSettings> LoadSettings();
void SaveSettings(IShellSettings settings);
}
}

View File

@@ -1,13 +1,15 @@
namespace Orchard.Environment.Configuration {
public interface IShellSettings {
string Name { get; set; }
string DataProvider { get; set; }
string DataConnectionString { get; set; }
string Name { get; }
string DataProvider { get; }
string DataConnectionString { get; }
string DataPrefix { get; }
}
public class ShellSettings : IShellSettings {
public string Name { get; set; }
public string DataProvider { get; set; }
public string DataConnectionString { get; set; }
public string DataPrefix { get; set; }
}
}

View File

@@ -1,93 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Hosting;
using Orchard.Localization;
using Yaml.Grammar;
namespace Orchard.Environment.Configuration {
public interface IShellSettingsLoader {
IEnumerable<IShellSettings> LoadSettings();
void SaveSettings(IShellSettings settings);
}
public class ShellSettingsLoader : IShellSettingsLoader {
private readonly IAppDataFolder _appDataFolder;
Localizer T { get; set; }
public ShellSettingsLoader(IAppDataFolder appDataFolder) {
_appDataFolder = appDataFolder;
T = NullLocalizer.Instance;
}
IEnumerable<IShellSettings> IShellSettingsLoader.LoadSettings() {
return LoadSettings().ToArray();
}
public void SaveSettings(IShellSettings settings) {
if (settings == null)
throw new ArgumentException(T("There are no settings to save.").ToString());
if (string.IsNullOrEmpty(settings.Name))
throw new ArgumentException(T("Settings \"Name\" is not set.").ToString());
var settingsFile = Path.Combine(Path.Combine("Sites", settings.Name), "Settings.txt");
_appDataFolder.CreateFile(settingsFile, ComposeSettings(settings));
}
IEnumerable<IShellSettings> LoadSettings() {
foreach (var yamlDocument in LoadFiles()) {
yield return ParseSettings(yamlDocument);
}
}
IEnumerable<YamlDocument> LoadFiles() {
var sitePaths = _appDataFolder
.ListDirectories("Sites")
.SelectMany(path => _appDataFolder.ListFiles(path))
.Where(path => string.Equals(Path.GetFileName(path), "Settings.txt", StringComparison.OrdinalIgnoreCase));
foreach (var sitePath in sitePaths) {
var yamlStream = YamlParser.Load(_appDataFolder.MapPath(sitePath));
yield return yamlStream.Documents.Single();
}
}
static IShellSettings ParseSettings(YamlDocument document) {
var mapping = (Mapping)document.Root;
var fields = mapping.Entities
.Where(x => x.Key is Scalar)
.ToDictionary(x => ((Scalar)x.Key).Text, x => x.Value);
return new ShellSettings {
Name = GetValue(fields, "Name"),
DataProvider = GetValue(fields, "DataProvider"),
DataConnectionString = GetValue(fields, "DataConnectionString")
};
}
static string GetValue(
IDictionary<string, DataItem> fields,
string key) {
DataItem value;
return fields.TryGetValue(key, out value) ? value.ToString() : null;
}
static string ComposeSettings(IShellSettings shellSettings) {
if (shellSettings == null)
return "";
var settingsBuilder = new StringBuilder();
settingsBuilder.AppendLine(string.Format("Name: {0}", shellSettings.Name));
settingsBuilder.AppendLine(string.Format("DataProvider: {0}", shellSettings.DataProvider));
if (!string.IsNullOrEmpty(shellSettings.DataConnectionString))
settingsBuilder.AppendLine(string.Format("DataConnectionString: {0}", shellSettings.DataConnectionString));
return settingsBuilder.ToString();
}
}
}

View File

@@ -101,6 +101,10 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\yaml\Yaml.dll</HintPath>
</Reference>
<Reference Include="YamlSerializer, Version=0.9.0.2, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\yaml\YamlSerializer.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Data\SessionLocator.cs" />