diff --git a/.vs/config/applicationhost.config b/.vs/config/applicationhost.config
new file mode 100644
index 00000000000..20dc0fd6fb1
--- /dev/null
+++ b/.vs/config/applicationhost.config
@@ -0,0 +1,1036 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NuGet.Config b/NuGet.Config
new file mode 100644
index 00000000000..c33f0ccb5bf
--- /dev/null
+++ b/NuGet.Config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OrchardVNext.sln b/OrchardVNext.sln
index 70c7ba9f926..aa8ee454e62 100644
--- a/OrchardVNext.sln
+++ b/OrchardVNext.sln
@@ -1,9 +1,8 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
+Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.22512.0
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Web", "src\OrchardVNext.Web\OrchardVNext.Web.kproj", "{07D91819-4C81-434F-8DE4-51D2B5A4EDA8}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Web", "src\OrchardVNext.Web\OrchardVNext.Web.xproj", "{07D91819-4C81-434F-8DE4-51D2B5A4EDA8}"
ProjectSection(ProjectDependencies) = postProject
{60B5B61F-09C1-4F5C-8A5A-953574D0DCA2} = {60B5B61F-09C1-4F5C-8A5A-953574D0DCA2}
EndProjectSection
@@ -12,25 +11,30 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
global.json = global.json
EndProjectSection
+ ProjectSection(FolderGlobals) = preProject
+ global_1json__JSONSchema = http://json.schemastore.org/global
+ EndProjectSection
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Framework", "src\OrchardVNext\OrchardVNext.Framework.kproj", "{60B5B61F-09C1-4F5C-8A5A-953574D0DCA2}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Framework", "src\OrchardVNext\OrchardVNext.Framework.xproj", "{60B5B61F-09C1-4F5C-8A5A-953574D0DCA2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{90030E85-0C4F-456F-B879-443E8A3F220D}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Test1", "src\OrchardVNext.Web\Modules\OrchardVNext.Test1\OrchardVNext.Test1.kproj", "{44CF51FB-7C14-4471-B113-9286BD41A783}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Test1", "src\OrchardVNext.Web\Modules\OrchardVNext.Test1\OrchardVNext.Test1.xproj", "{44CF51FB-7C14-4471-B113-9286BD41A783}"
ProjectSection(ProjectDependencies) = postProject
{60B5B61F-09C1-4F5C-8A5A-953574D0DCA2} = {60B5B61F-09C1-4F5C-8A5A-953574D0DCA2}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{275E087F-A4E2-4A7B-A924-ED68E3A52086}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Test2", "src\OrchardVNext.Web\Modules\OrchardVNext.Test2\OrchardVNext.Test2.kproj", "{C0BA112A-FD23-451B-8876-912E1AEAD87B}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Test2", "src\OrchardVNext.Web\Modules\OrchardVNext.Test2\OrchardVNext.Test2.xproj", "{C0BA112A-FD23-451B-8876-912E1AEAD87B}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Demo", "src\OrchardVNext.Web\Modules\OrchardVNext.Demo\OrchardVNext.Demo.kproj", "{19089E81-CEFD-4008-A31C-541D82F58C54}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Demo", "src\OrchardVNext.Web\Modules\OrchardVNext.Demo\OrchardVNext.Demo.xproj", "{19089E81-CEFD-4008-A31C-541D82F58C54}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C362E36F-3F0F-40B3-8BBF-2B0252E77A34}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Tests", "src\OrchardVNext.Tests\OrchardVNext.Tests.kproj", "{B8431B91-F908-416A-A82C-B29528FCA4E9}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Tests", "src\OrchardVNext.Tests\OrchardVNext.Tests.xproj", "{B8431B91-F908-416A-A82C-B29528FCA4E9}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "OrchardVNext.Core", "src\OrchardVNext.Web\Core\OrchardVNext.Core\OrchardVNext.Core.xproj", "{D2B2A745-17BA-4B5F-8992-93EA803BD068}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -62,6 +66,10 @@ Global
{B8431B91-F908-416A-A82C-B29528FCA4E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8431B91-F908-416A-A82C-B29528FCA4E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8431B91-F908-416A-A82C-B29528FCA4E9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D2B2A745-17BA-4B5F-8992-93EA803BD068}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D2B2A745-17BA-4B5F-8992-93EA803BD068}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D2B2A745-17BA-4B5F-8992-93EA803BD068}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D2B2A745-17BA-4B5F-8992-93EA803BD068}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -75,5 +83,6 @@ Global
{19089E81-CEFD-4008-A31C-541D82F58C54} = {90030E85-0C4F-456F-B879-443E8A3F220D}
{C362E36F-3F0F-40B3-8BBF-2B0252E77A34} = {275E087F-A4E2-4A7B-A924-ED68E3A52086}
{B8431B91-F908-416A-A82C-B29528FCA4E9} = {C362E36F-3F0F-40B3-8BBF-2B0252E77A34}
+ {D2B2A745-17BA-4B5F-8992-93EA803BD068} = {275E087F-A4E2-4A7B-A924-ED68E3A52086}
EndGlobalSection
EndGlobal
diff --git a/OrchardVNext.sublime-project b/OrchardVNext.sublime-project
new file mode 100644
index 00000000000..472baf8a620
--- /dev/null
+++ b/OrchardVNext.sublime-project
@@ -0,0 +1,10 @@
+{
+ "folders":
+ [
+ {
+ "follow_symlinks": true,
+ "path": "."
+ }
+ ],
+ "solution_file": "./OrchardVNext.sln"
+}
\ No newline at end of file
diff --git a/OrchardVNext.sublime-workspace b/OrchardVNext.sublime-workspace
new file mode 100644
index 00000000000..c08d9490367
--- /dev/null
+++ b/OrchardVNext.sublime-workspace
@@ -0,0 +1,867 @@
+{
+ "auto_complete":
+ {
+ "selected_items":
+ [
+ ]
+ },
+ "buffers":
+ [
+ {
+ "file": "src/OrchardVNext.Web/Modules/OrchardVNext.Test1/Class.cs",
+ "settings":
+ {
+ "buffer_size": 541,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext.Web/Modules/OrchardVNext.Test1/TestMiddleware.cs",
+ "settings":
+ {
+ "buffer_size": 626,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/project.json",
+ "settings":
+ {
+ "buffer_size": 1139,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/InvokeExtensions.cs",
+ "settings":
+ {
+ "buffer_size": 1987,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext.Web/Startup.cs",
+ "settings":
+ {
+ "buffer_size": 281,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/Environment/OrchardStarter.cs",
+ "settings":
+ {
+ "buffer_size": 4096,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "contents": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing Microsoft.Framework.ConfigurationModel;\nusing OrchardVNext.Environment.Configuration.Sources;\nusing OrchardVNext.FileSystems.AppData;\n\nnamespace OrchardVNext.Environment.Configuration {\n public interface IShellSettingsManager {\n IEnumerable LoadSettings();\n }\n\n public class ShellSettingsManager : IShellSettingsManager {\n private readonly IAppDataFolder _appDataFolder;\n private const string _settingsFileNameFormat = \"Settings.{0}\";\n private readonly string[] _settingFileNameExtensions = new string[] { \"txt\", \"json\" };\n\n public ShellSettingsManager(IAppDataFolder appDataFolder) {\n _appDataFolder = appDataFolder;\n }\n\n IEnumerable IShellSettingsManager.LoadSettings() {\n var filePaths = _appDataFolder\n .ListDirectories(\"Sites\")\n .SelectMany(path => _appDataFolder.ListFiles(path))\n .Where(path => {\n var filePathName = Path.GetFileName(path);\n\n return _settingFileNameExtensions.Any(p =>\n string.Equals(filePathName, string.Format(_settingsFileNameFormat, p), StringComparison.OrdinalIgnoreCase)\n );\n });\n\n List shellSettings = new List();\n\n foreach (var filePath in filePaths) {\n IConfigurationSourceContainer configurationContainer = null;\n\n var extension = Path.GetExtension(filePath);\n\n switch (extension) {\n case \".json\":\n configurationContainer = new Microsoft.Framework.ConfigurationModel.Configuration()\n .AddJsonFile(filePath);\n break;\n case \".xml\":\n configurationContainer = new Microsoft.Framework.ConfigurationModel.Configuration()\n .AddXmlFile(filePath);\n break;\n case \".ini\":\n configurationContainer = new Microsoft.Framework.ConfigurationModel.Configuration()\n .AddIniFile(filePath);\n break;\n case \".txt\":\n configurationContainer = new Microsoft.Framework.ConfigurationModel.Configuration()\n .Add(new DefaultFileConfigurationSource(_appDataFolder, filePath));\n break;\n }\n\n if (configurationContainer != null) {\n var shellSetting = new ShellSettings {\n Name = configurationContainer.Get(\"Name\"),\n DataConnectionString = configurationContainer.Get(\"DataConnectionString\"),\n DataProvider = configurationContainer.Get(\"DataProvider\"),\n DataTablePrefix = configurationContainer.Get(\"DataTablePrefix\"),\n RequestUrlHost = configurationContainer.Get(\"RequestUrlHost\"),\n RequestUrlPrefix = configurationContainer.Get(\"RequestUrlPrefix\")\n };\n\n TenantState state;\n shellSetting.State = Enum.TryParse(configurationContainer.Get(\"State\"), true, out state) ? state : TenantState.Uninitialized;\n\n shellSettings.Add(shellSetting);\n }\n }\n\n return shellSettings;\n }\n }\n}",
+ "file": "src/OrchardVNext/Environment/Configuration/ShellSettingsManager.cs",
+ "file_size": 3723,
+ "file_write_time": 130711908279920244,
+ "settings":
+ {
+ "buffer_size": 3643,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "/C/Users/Nicholas/AppData/Roaming/Sublime Text 3/Packages/User/C#.sublime-settings",
+ "settings":
+ {
+ "buffer_size": 163,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/FileSystems/AppData/AppDataFolder.cs",
+ "settings":
+ {
+ "buffer_size": 6615,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/FileSystems/AppData/IAppDataFolderRoot.cs",
+ "settings":
+ {
+ "buffer_size": 948,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/FileSystems/WebSite/WebSiteFolder.cs",
+ "settings":
+ {
+ "buffer_size": 3951,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/Environment/ShellBuilders/CompositionStrategy.cs",
+ "settings":
+ {
+ "buffer_size": 5420,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/Environment/ShellBuilders/Models/ShellBlueprint.cs",
+ "settings":
+ {
+ "buffer_size": 1228,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/ContentManagement/ContentExtensions.cs",
+ "settings":
+ {
+ "buffer_size": 1641,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/ContentManagement/IContent.cs",
+ "settings":
+ {
+ "buffer_size": 235,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "/C/Users/Nicholas/AppData/Roaming/Sublime Text 3/Packages/User/csharp.sublime-build",
+ "settings":
+ {
+ "buffer_size": 79,
+ "line_ending": "Windows",
+ "name": "untitled.sublime-build"
+ }
+ },
+ {
+ "file": "src/OrchardVNext/Environment/DefaultOrchardHost.cs",
+ "settings":
+ {
+ "buffer_size": 704,
+ "line_ending": "Windows"
+ }
+ },
+ {
+ "file": "OrchardVNext.sublime-project",
+ "settings":
+ {
+ "buffer_size": 152,
+ "line_ending": "Windows"
+ }
+ }
+ ],
+ "build_system": "",
+ "command_palette":
+ {
+ "height": 119.0,
+ "selected_items":
+ [
+ [
+ "Omnisharp Reli",
+ "OmniSharpSublime: Reload Solution"
+ ],
+ [
+ "OmniSharpSublime: Re",
+ "OmniSharpSublime: Reload Solution"
+ ]
+ ],
+ "width": 588.0
+ },
+ "console":
+ {
+ "height": 651.0,
+ "history":
+ [
+ "install",
+ "import urllib.request,os,hashlib; h = 'eb2297e1a458f27d836c04bb0cbaf282' + 'd0e7a3098092775ccb37ca9d6b2e4b7d'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by) ",
+ "install",
+ "import urllib.request,os,hashlib; h = 'eb2297e1a458f27d836c04bb0cbaf282' + 'd0e7a3098092775ccb37ca9d6b2e4b7d'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by) "
+ ]
+ },
+ "distraction_free":
+ {
+ "menu_visible": true,
+ "show_minimap": false,
+ "show_open_files": false,
+ "show_tabs": false,
+ "side_bar_visible": false,
+ "status_bar_visible": false
+ },
+ "expanded_folders":
+ [
+ "/D/Brochard",
+ "/D/Brochard/src",
+ "/D/Brochard/src/OrchardVNext",
+ "/D/Brochard/src/OrchardVNext/ContentManagement",
+ "/D/Brochard/src/OrchardVNext.Web"
+ ],
+ "file_history":
+ [
+ "/C/Users/Nicholas/AppData/Roaming/Sublime Text 3/Packages/Default/Default (Windows).sublime-keymap",
+ "/C/Users/Nicholas/AppData/Roaming/Sublime Text 3/Packages/User/Default (Windows).sublime-keymap",
+ "/C/Users/Nicholas/AppData/Roaming/Sublime Text 3/Packages/User/C#.sublime-settings"
+ ],
+ "find":
+ {
+ "height": 31.0
+ },
+ "find_in_files":
+ {
+ "height": 138.0,
+ "where_history":
+ [
+ ]
+ },
+ "find_state":
+ {
+ "case_sensitive": false,
+ "find_history":
+ [
+ "ctrl+s\"",
+ "ctrl+s"
+ ],
+ "highlight": true,
+ "in_selection": false,
+ "preserve_case": false,
+ "regex": false,
+ "replace_history":
+ [
+ ],
+ "reverse": false,
+ "show_context": true,
+ "use_buffer2": true,
+ "whole_word": false,
+ "wrap": true
+ },
+ "groups":
+ [
+ {
+ "selected": 6,
+ "sheets":
+ [
+ {
+ "buffer": 0,
+ "file": "src/OrchardVNext.Web/Modules/OrchardVNext.Test1/Class.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 541,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 490,
+ 490
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 17,
+ "type": "text"
+ },
+ {
+ "buffer": 1,
+ "file": "src/OrchardVNext.Web/Modules/OrchardVNext.Test1/TestMiddleware.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 626,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 507,
+ 507
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 15,
+ "type": "text"
+ },
+ {
+ "buffer": 2,
+ "file": "src/OrchardVNext/project.json",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 1139,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 933,
+ 933
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/JavaScript/JSON.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 13,
+ "type": "text"
+ },
+ {
+ "buffer": 3,
+ "file": "src/OrchardVNext/InvokeExtensions.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 1987,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 559,
+ 559
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 132.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 3,
+ "type": "text"
+ },
+ {
+ "buffer": 4,
+ "file": "src/OrchardVNext.Web/Startup.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 281,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 219,
+ 219
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage"
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 12,
+ "type": "text"
+ },
+ {
+ "buffer": 5,
+ "file": "src/OrchardVNext/Environment/OrchardStarter.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 4096,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 1628,
+ 1628
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 178.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 2,
+ "type": "text"
+ },
+ {
+ "buffer": 6,
+ "file": "src/OrchardVNext/Environment/Configuration/ShellSettingsManager.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 3643,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 1878,
+ 1878
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 321.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 0,
+ "type": "text"
+ },
+ {
+ "buffer": 7,
+ "file": "/C/Users/Nicholas/AppData/Roaming/Sublime Text 3/Packages/User/C#.sublime-settings",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 163,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 2,
+ 2
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/JavaScript/JSON.tmLanguage"
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 1,
+ "type": "text"
+ },
+ {
+ "buffer": 8,
+ "file": "src/OrchardVNext/FileSystems/AppData/AppDataFolder.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 6615,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 378,
+ 378
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 5,
+ "type": "text"
+ },
+ {
+ "buffer": 9,
+ "file": "src/OrchardVNext/FileSystems/AppData/IAppDataFolderRoot.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 948,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 252,
+ 252
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 4,
+ "type": "text"
+ },
+ {
+ "buffer": 10,
+ "file": "src/OrchardVNext/FileSystems/WebSite/WebSiteFolder.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 3951,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 2026,
+ 2026
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 6,
+ "type": "text"
+ },
+ {
+ "buffer": 11,
+ "file": "src/OrchardVNext/Environment/ShellBuilders/CompositionStrategy.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 5420,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 1978,
+ 1978
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 11,
+ "type": "text"
+ },
+ {
+ "buffer": 12,
+ "file": "src/OrchardVNext/Environment/ShellBuilders/Models/ShellBlueprint.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 1228,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 580,
+ 580
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 10,
+ "type": "text"
+ },
+ {
+ "buffer": 13,
+ "file": "src/OrchardVNext/ContentManagement/ContentExtensions.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 1641,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 722,
+ 722
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 9,
+ "type": "text"
+ },
+ {
+ "buffer": 14,
+ "file": "src/OrchardVNext/ContentManagement/IContent.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 235,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 225,
+ 225
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage"
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 8,
+ "type": "text"
+ },
+ {
+ "buffer": 15,
+ "file": "/C/Users/Nicholas/AppData/Roaming/Sublime Text 3/Packages/User/csharp.sublime-build",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 79,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 63,
+ 63
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/JavaScript/JSON.tmLanguage"
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 7,
+ "type": "text"
+ },
+ {
+ "buffer": 16,
+ "file": "src/OrchardVNext/Environment/DefaultOrchardHost.cs",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 704,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 628,
+ 628
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/C#/C#.tmLanguage",
+ "tab_size": 4,
+ "translate_tabs_to_spaces": true
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 14,
+ "type": "text"
+ },
+ {
+ "buffer": 17,
+ "file": "OrchardVNext.sublime-project",
+ "semi_transient": false,
+ "settings":
+ {
+ "buffer_size": 152,
+ "regions":
+ {
+ },
+ "selection":
+ [
+ [
+ 0,
+ 0
+ ]
+ ],
+ "settings":
+ {
+ "syntax": "Packages/JavaScript/JSON.tmLanguage"
+ },
+ "translation.x": 0.0,
+ "translation.y": 0.0,
+ "zoom_level": 1.0
+ },
+ "stack_index": 16,
+ "type": "text"
+ }
+ ]
+ }
+ ],
+ "incremental_find":
+ {
+ "height": 30.0
+ },
+ "input":
+ {
+ "height": 42.0
+ },
+ "layout":
+ {
+ "cells":
+ [
+ [
+ 0,
+ 0,
+ 1,
+ 1
+ ]
+ ],
+ "cols":
+ [
+ 0.0,
+ 1.0
+ ],
+ "rows":
+ [
+ 0.0,
+ 1.0
+ ]
+ },
+ "menu_visible": true,
+ "output.exec":
+ {
+ "height": 596.0
+ },
+ "output.find_results":
+ {
+ "height": 0.0
+ },
+ "output.variable_get":
+ {
+ "height": 498.0
+ },
+ "project": "OrchardVNext.sublime-project",
+ "replace":
+ {
+ "height": 58.0
+ },
+ "save_all_on_build": true,
+ "select_file":
+ {
+ "height": 0.0,
+ "selected_items":
+ [
+ ],
+ "width": 0.0
+ },
+ "select_project":
+ {
+ "height": 0.0,
+ "selected_items":
+ [
+ ],
+ "width": 0.0
+ },
+ "select_symbol":
+ {
+ "height": 0.0,
+ "selected_items":
+ [
+ ],
+ "width": 0.0
+ },
+ "selected_group": 0,
+ "settings":
+ {
+ },
+ "show_minimap": true,
+ "show_open_files": false,
+ "show_tabs": true,
+ "side_bar_visible": true,
+ "side_bar_width": 326.0,
+ "status_bar_visible": true,
+ "template_settings":
+ {
+ }
+}
diff --git a/global.json b/global.json
index cad39504d41..d94610fe3bd 100644
--- a/global.json
+++ b/global.json
@@ -1,3 +1,3 @@
{
- "sources": [ "src" ]
+ "projects": [ "src" ]
}
diff --git a/src/OrchardVNext.Tests/OrchardVNext.Tests.kproj b/src/OrchardVNext.Tests/OrchardVNext.Tests.xproj
similarity index 85%
rename from src/OrchardVNext.Tests/OrchardVNext.Tests.kproj
rename to src/OrchardVNext.Tests/OrchardVNext.Tests.xproj
index 1cbad2fde37..2cbc5225c0f 100644
--- a/src/OrchardVNext.Tests/OrchardVNext.Tests.kproj
+++ b/src/OrchardVNext.Tests/OrchardVNext.Tests.xproj
@@ -4,7 +4,7 @@
14.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
+
b8431b91-f908-416a-a82c-b29528fca4e9
OrchardVNext.Tests
@@ -17,7 +17,7 @@
2.0
-
+
diff --git a/src/OrchardVNext.Tests/project.json b/src/OrchardVNext.Tests/project.json
index fabea333402..22f2aa11e3c 100644
--- a/src/OrchardVNext.Tests/project.json
+++ b/src/OrchardVNext.Tests/project.json
@@ -3,19 +3,18 @@
"warningsAsErrors": true
},
"dependencies": {
- "xunit.runner.kre": "1.0.0-beta4-*",
- "Microsoft.AspNet.Testing": "1.0.0-*",
+ "xunit.runner.aspnet": "2.0.0-aspnet-*",
"OrchardVNext": ""
},
"commands": {
- "test": "xunit.runner.kre"
+ "test": "xunit.runner.aspnet"
},
"frameworks": {
- "aspnet50": {
+ "dnx451": {
"dependencies": {
"Moq": "4.2.1312.1622"
}
},
- "aspnetcore50": { }
+ "dnxcore50": { }
}
}
diff --git a/src/OrchardVNext/OrchardVNext.Framework.kproj b/src/OrchardVNext.Web/Core/OrchardVNext.Core/OrchardVNext.Core.xproj
similarity index 70%
rename from src/OrchardVNext/OrchardVNext.Framework.kproj
rename to src/OrchardVNext.Web/Core/OrchardVNext.Core/OrchardVNext.Core.xproj
index b9d4b9b3cee..c49d3263219 100644
--- a/src/OrchardVNext/OrchardVNext.Framework.kproj
+++ b/src/OrchardVNext.Web/Core/OrchardVNext.Core/OrchardVNext.Core.xproj
@@ -4,19 +4,19 @@
14.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
+
- 60b5b61f-09c1-4f5c-8a5a-953574d0dca2
+ d2b2a745-17ba-4b5f-8992-93ea803bd068
Library
- OrchardVNext
+ OrchardVNext.Core
- OrchardVNext.Framework
+ OrchardVNext.Core
2.0
-
+
diff --git a/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/ContentDefinitionManager.cs b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/ContentDefinitionManager.cs
new file mode 100644
index 00000000000..05548268936
--- /dev/null
+++ b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/ContentDefinitionManager.cs
@@ -0,0 +1,265 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Xml.Linq;
+using OrchardVNext.ContentManagement.MetaData;
+using OrchardVNext.ContentManagement.MetaData.Models;
+using OrchardVNext.ContentManagement.MetaData.Services;
+using OrchardVNext.Core.Settings.Metadata.Records;
+using OrchardVNext.Data;
+
+namespace OrchardVNext.Core.Settings.Metadata {
+ public class ContentDefinitionManager : Component, IContentDefinitionManager {
+ private readonly IContentStorageProvider _contentStorageProvider;
+ private readonly ISettingsFormatter _settingsFormatter;
+
+ public ContentDefinitionManager(
+ IContentStorageProvider contentStorageProvider,
+ ISettingsFormatter settingsFormatter) {
+ _contentStorageProvider = contentStorageProvider;
+ _settingsFormatter = settingsFormatter;
+ }
+
+ public IEnumerable ListTypeDefinitions() {
+ return AcquireContentTypeDefinitions().Values;
+ }
+
+ public IEnumerable ListPartDefinitions() {
+ return AcquireContentPartDefinitions().Values;
+ }
+
+ public IEnumerable ListFieldDefinitions() {
+ return AcquireContentFieldDefinitions().Values;
+ }
+
+ public ContentTypeDefinition GetTypeDefinition(string name) {
+ if (string.IsNullOrWhiteSpace(name)) {
+ return null;
+ }
+
+ var contentTypeDefinitions = AcquireContentTypeDefinitions();
+ if (contentTypeDefinitions.ContainsKey(name)) {
+ return contentTypeDefinitions[name];
+ }
+
+ return null;
+ }
+
+ public ContentPartDefinition GetPartDefinition(string name) {
+ if (string.IsNullOrWhiteSpace(name)) {
+ return null;
+ }
+
+ var contentPartDefinitions = AcquireContentPartDefinitions();
+ if (contentPartDefinitions.ContainsKey(name)) {
+ return contentPartDefinitions[name];
+ }
+
+ return null;
+ }
+
+ public void DeleteTypeDefinition(string name) {
+ var record = _contentStorageProvider
+ .Query(x => x.Name == name)
+ .SingleOrDefault();
+
+ // deletes the content type record associated
+ if (record != null) {
+ _contentStorageProvider.Remove(record);
+ }
+ }
+
+ public void DeletePartDefinition(string name) {
+ // remove parts from current types
+ var typesWithPart = ListTypeDefinitions().Where(typeDefinition => typeDefinition.Parts.Any(part => part.PartDefinition.Name == name));
+
+ foreach (var typeDefinition in typesWithPart) {
+ this.AlterTypeDefinition(typeDefinition.Name, builder => builder.RemovePart(name));
+ }
+
+ // delete part
+ var record = _contentStorageProvider
+ .Query(x => x.Name == name)
+ .SingleOrDefault();
+
+ if (record != null) {
+ _contentStorageProvider.Remove(record);
+ }
+ }
+
+ public void StoreTypeDefinition(ContentTypeDefinition contentTypeDefinition) {
+ Apply(contentTypeDefinition, Acquire(contentTypeDefinition));
+ }
+
+ public void StorePartDefinition(ContentPartDefinition contentPartDefinition) {
+ Apply(contentPartDefinition, Acquire(contentPartDefinition));
+ }
+
+
+ private IDictionary AcquireContentTypeDefinitions() {
+ AcquireContentPartDefinitions();
+
+ var contentTypeDefinitionRecords = _contentStorageProvider
+ .Query()
+ .Select(Build);
+
+ return contentTypeDefinitionRecords.ToDictionary(x => x.Name, y => y, StringComparer.OrdinalIgnoreCase);
+ }
+
+ private IDictionary AcquireContentPartDefinitions() {
+ var contentPartDefinitionRecords = _contentStorageProvider
+ .Query()
+ .Select(Build);
+
+ return contentPartDefinitionRecords.ToDictionary(x => x.Name, y => y, StringComparer.OrdinalIgnoreCase);
+ }
+
+ private IDictionary AcquireContentFieldDefinitions() {
+ return _contentStorageProvider
+ .Query()
+ .Select(Build)
+ .ToDictionary(x => x.Name, y => y);
+ }
+
+ private ContentTypeDefinitionRecord Acquire(ContentTypeDefinition contentTypeDefinition) {
+ var result = _contentStorageProvider
+ .Query(x => x.Name == contentTypeDefinition.Name)
+ .SingleOrDefault();
+
+ if (result == null) {
+ result = new ContentTypeDefinitionRecord { Name = contentTypeDefinition.Name, DisplayName = contentTypeDefinition.DisplayName };
+ _contentStorageProvider.Store(result);
+ }
+ return result;
+ }
+
+ private ContentPartDefinitionRecord Acquire(ContentPartDefinition contentPartDefinition) {
+ var result = _contentStorageProvider
+ .Query(x => x.Name == contentPartDefinition.Name)
+ .SingleOrDefault();
+
+ if (result == null) {
+ result = new ContentPartDefinitionRecord { Name = contentPartDefinition.Name };
+ _contentStorageProvider.Store(result);
+ }
+ return result;
+ }
+
+ private ContentFieldDefinitionRecord Acquire(ContentFieldDefinition contentFieldDefinition) {
+ var result = _contentStorageProvider
+ .Query(x => x.Name == contentFieldDefinition.Name)
+ .SingleOrDefault();
+
+ if (result == null) {
+ result = new ContentFieldDefinitionRecord { Name = contentFieldDefinition.Name };
+ _contentStorageProvider.Store(result);
+ }
+ return result;
+ }
+
+ private void Apply(ContentTypeDefinition model, ContentTypeDefinitionRecord record) {
+ record.DisplayName = model.DisplayName;
+ record.Settings = _settingsFormatter.Map(model.Settings).ToString();
+
+ var toRemove = record.ContentTypePartDefinitionRecords
+ .Where(partDefinitionRecord => model.Parts.All(part => partDefinitionRecord.ContentPartDefinitionRecord.Name != part.PartDefinition.Name))
+ .ToList();
+
+ foreach (var remove in toRemove) {
+ record.ContentTypePartDefinitionRecords.Remove(remove);
+ }
+
+ foreach (var part in model.Parts) {
+ var partName = part.PartDefinition.Name;
+ var typePartRecord = record.ContentTypePartDefinitionRecords.SingleOrDefault(r => r.ContentPartDefinitionRecord.Name == partName);
+ if (typePartRecord == null) {
+ typePartRecord = new ContentTypePartDefinitionRecord { ContentPartDefinitionRecord = Acquire(part.PartDefinition) };
+ record.ContentTypePartDefinitionRecords.Add(typePartRecord);
+ }
+ Apply(part, typePartRecord);
+ }
+ }
+
+ private void Apply(ContentTypePartDefinition model, ContentTypePartDefinitionRecord record) {
+ record.Settings = Compose(_settingsFormatter.Map(model.Settings));
+ }
+
+ private void Apply(ContentPartDefinition model, ContentPartDefinitionRecord record) {
+ record.Settings = _settingsFormatter.Map(model.Settings).ToString();
+
+ var toRemove = record.ContentPartFieldDefinitionRecords
+ .Where(partFieldDefinitionRecord => model.Fields.All(partField => partFieldDefinitionRecord.Name != partField.Name))
+ .ToList();
+
+ foreach (var remove in toRemove) {
+ record.ContentPartFieldDefinitionRecords.Remove(remove);
+ }
+
+ foreach (var field in model.Fields) {
+ var fieldName = field.Name;
+ var partFieldRecord = record.ContentPartFieldDefinitionRecords.SingleOrDefault(r => r.Name == fieldName);
+ if (partFieldRecord == null) {
+ partFieldRecord = new ContentPartFieldDefinitionRecord {
+ ContentFieldDefinitionRecord = Acquire(field.FieldDefinition),
+ Name = field.Name
+ };
+ record.ContentPartFieldDefinitionRecords.Add(partFieldRecord);
+ }
+ Apply(field, partFieldRecord);
+ }
+ }
+
+ private void Apply(ContentPartFieldDefinition model, ContentPartFieldDefinitionRecord record) {
+ record.Settings = Compose(_settingsFormatter.Map(model.Settings));
+ }
+
+ ContentTypeDefinition Build(ContentTypeDefinitionRecord source) {
+ return new ContentTypeDefinition(
+ source.Name,
+ source.DisplayName,
+ source.ContentTypePartDefinitionRecords.Select(Build),
+ _settingsFormatter.Map(Parse(source.Settings)));
+ }
+
+ ContentTypePartDefinition Build(ContentTypePartDefinitionRecord source) {
+ return new ContentTypePartDefinition(
+ Build(source.ContentPartDefinitionRecord),
+ _settingsFormatter.Map(Parse(source.Settings)));
+ }
+
+ ContentPartDefinition Build(ContentPartDefinitionRecord source) {
+ return new ContentPartDefinition(
+ source.Name,
+ source.ContentPartFieldDefinitionRecords.Select(Build),
+ _settingsFormatter.Map(Parse(source.Settings)));
+ }
+
+ ContentPartFieldDefinition Build(ContentPartFieldDefinitionRecord source) {
+ return new ContentPartFieldDefinition(
+ Build(source.ContentFieldDefinitionRecord),
+ source.Name,
+ _settingsFormatter.Map(Parse(source.Settings)));
+ }
+
+ ContentFieldDefinition Build(ContentFieldDefinitionRecord source) {
+ return new ContentFieldDefinition(source.Name);
+ }
+
+ XElement Parse(string settings) {
+ if (string.IsNullOrEmpty(settings))
+ return null;
+
+ try {
+ return XElement.Parse(settings);
+ }
+ catch (Exception ex) {
+ Logger.Error(ex, "Unable to parse settings xml");
+ return null;
+ }
+ }
+
+ static string Compose(XElement map) {
+ return map?.ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentFieldDefinitionRecord.cs b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentFieldDefinitionRecord.cs
new file mode 100644
index 00000000000..81e43bc3cd5
--- /dev/null
+++ b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentFieldDefinitionRecord.cs
@@ -0,0 +1,13 @@
+using OrchardVNext.ContentManagement;
+using OrchardVNext.ContentManagement.Records;
+using OrchardVNext.Data;
+
+namespace OrchardVNext.Core.Settings.Metadata.Records {
+ [Persistent]
+ public class ContentFieldDefinitionRecord : DocumentRecord {
+ public string Name {
+ get { return this.RetrieveValue(x => x.Name); }
+ set { this.StoreValue(x => x.Name, value); }
+ }
+ }
+}
diff --git a/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentPartDefinitionRecord.cs b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentPartDefinitionRecord.cs
new file mode 100644
index 00000000000..49f4bc05258
--- /dev/null
+++ b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentPartDefinitionRecord.cs
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+using OrchardVNext.ContentManagement;
+using OrchardVNext.ContentManagement.Records;
+using OrchardVNext.Data;
+using OrchardVNext.Data.Conventions;
+
+namespace OrchardVNext.Core.Settings.Metadata.Records {
+ [Persistent]
+ public class ContentPartDefinitionRecord : DocumentRecord {
+ public ContentPartDefinitionRecord() {
+ ContentPartFieldDefinitionRecords = new List();
+ }
+
+ public string Name {
+ get { return this.RetrieveValue(x => x.Name); }
+ set { this.StoreValue(x => x.Name, value); }
+ }
+ public bool Hidden {
+ get { return this.RetrieveValue(x => x.Hidden); }
+ set { this.StoreValue(x => x.Hidden, value); }
+ }
+ [StringLengthMax]
+ public string Settings {
+ get { return this.RetrieveValue(x => x.Settings); }
+ set { this.StoreValue(x => x.Settings, value); }
+ }
+
+ //[CascadeAllDeleteOrphan]
+ public virtual IList ContentPartFieldDefinitionRecords { get; set; }
+
+ }
+}
diff --git a/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentPartFieldDefinitionRecord.cs b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentPartFieldDefinitionRecord.cs
new file mode 100644
index 00000000000..ac0b25a9c61
--- /dev/null
+++ b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentPartFieldDefinitionRecord.cs
@@ -0,0 +1,13 @@
+using OrchardVNext.Data;
+using OrchardVNext.Data.Conventions;
+
+namespace OrchardVNext.Core.Settings.Metadata.Records {
+ [Persistent]
+ public class ContentPartFieldDefinitionRecord {
+ public virtual int Id { get; set; }
+ public virtual ContentFieldDefinitionRecord ContentFieldDefinitionRecord { get; set; }
+ public virtual string Name { get; set; }
+ [StringLengthMax]
+ public virtual string Settings { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentTypeDefinitionRecord.cs b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentTypeDefinitionRecord.cs
new file mode 100644
index 00000000000..ab1c566a231
--- /dev/null
+++ b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentTypeDefinitionRecord.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+using OrchardVNext.ContentManagement;
+using OrchardVNext.ContentManagement.Records;
+using OrchardVNext.Data;
+using OrchardVNext.Data.Conventions;
+
+namespace OrchardVNext.Core.Settings.Metadata.Records {
+ [Persistent]
+ public class ContentTypeDefinitionRecord : DocumentRecord {
+ public ContentTypeDefinitionRecord() {
+ ContentTypePartDefinitionRecords = new List();
+ }
+
+ public string Name {
+ get { return this.RetrieveValue(x => x.Name); }
+ set { this.StoreValue(x => x.Name, value); }
+ }
+ public string DisplayName {
+ get { return this.RetrieveValue(x => x.DisplayName); }
+ set { this.StoreValue(x => x.DisplayName, value); }
+ }
+ public bool Hidden {
+ get { return this.RetrieveValue(x => x.Hidden); }
+ set { this.StoreValue(x => x.Hidden, value); }
+ }
+ [StringLengthMax]
+ public string Settings {
+ get { return this.RetrieveValue(x => x.Settings); }
+ set { this.StoreValue(x => x.Settings, value); }
+ }
+
+ //[CascadeAllDeleteOrphan]
+ public virtual IList ContentTypePartDefinitionRecords { get; set; }
+ }
+
+}
diff --git a/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentTypePartDefinitionRecord.cs b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentTypePartDefinitionRecord.cs
new file mode 100644
index 00000000000..a8d31e161d0
--- /dev/null
+++ b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Metadata/Records/ContentTypePartDefinitionRecord.cs
@@ -0,0 +1,12 @@
+using OrchardVNext.Data;
+using OrchardVNext.Data.Conventions;
+
+namespace OrchardVNext.Core.Settings.Metadata.Records {
+ [Persistent]
+ public class ContentTypePartDefinitionRecord {
+ public virtual int Id { get; set; }
+ public virtual ContentPartDefinitionRecord ContentPartDefinitionRecord { get; set; }
+ [StringLengthMax]
+ public virtual string Settings { get; set; }
+ }
+}
diff --git a/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Module.txt b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Module.txt
new file mode 100644
index 00000000000..23235dc07ea
--- /dev/null
+++ b/src/OrchardVNext.Web/Core/OrchardVNext.Core/Settings/Module.txt
@@ -0,0 +1,9 @@
+Name: Settings
+AntiForgery: enabled
+Author: The Orchard Team
+Website: http://orchardproject.net
+Version: 2.0.x
+OrchardVersion: 2.0.x
+Description: The settings module creates site settings that other modules can contribute to.
+FeatureDescription: Site settings.
+Category: Core
diff --git a/src/OrchardVNext.Web/Core/OrchardVNext.Core/project.json b/src/OrchardVNext.Web/Core/OrchardVNext.Core/project.json
new file mode 100644
index 00000000000..a4e2a7030fb
--- /dev/null
+++ b/src/OrchardVNext.Web/Core/OrchardVNext.Core/project.json
@@ -0,0 +1,12 @@
+{
+ "version": "2.0.0-*",
+ "dependencies": {
+ "Microsoft.AspNet.Mvc": "6.0.0-beta4-*",
+ "OrchardVNext": ""
+ },
+ "compilationOptions": { "define": [ "TRACE" ], "warningsAsErrors": true },
+ "frameworks": {
+ "dnx451": { },
+ "dnxcore50": { }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Controllers/HomeController.cs b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Controllers/HomeController.cs
index 5389e38c4ae..7f726953e2d 100644
--- a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Controllers/HomeController.cs
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Controllers/HomeController.cs
@@ -1,16 +1,62 @@
using Microsoft.AspNet.Mvc;
+using OrchardVNext.ContentManagement;
+using OrchardVNext.ContentManagement.Handlers;
+using OrchardVNext.Data;
+using OrchardVNext.Demo.Models;
using OrchardVNext.Test1;
namespace OrchardVNext.Demo.Controllers {
public class HomeController : Controller {
private readonly ITestDependency _testDependency;
+ private readonly IContentStorageProvider _contentStorageProvider;
+ private readonly IContentManager _contentManager;
- public HomeController(ITestDependency testDependency) {
+ public HomeController(ITestDependency testDependency,
+ IContentStorageProvider contentStorageProvider,
+ IContentManager contentManager) {
_testDependency = testDependency;
+ _contentStorageProvider = contentStorageProvider;
+ _contentManager = contentManager;
+ }
+
+ public ActionResult Index()
+ {
+ //var contentItem = new ContentItem
+ //{
+ // VersionRecord = new ContentItemVersionRecord
+ // {
+ // ContentItemRecord = new ContentItemRecord(),
+ // Number = 1,
+ // Latest = true,
+ // Published = true
+ // }
+ //};
+
+ //contentItem.VersionRecord.ContentItemRecord.Versions.Add(contentItem.VersionRecord);
+
+ //_contentStorageProvider.Store(contentItem);
+
+ //var indexedRecordIds = _contentIndexProvider.GetByFilter(x => x.Id == 1);
+
+ //var retrievedRecord = _contentStorageProvider.Get(contentItem.Id);
+
+ //var indexedRetrievedRecords = _contentStorageProvider.GetMany(x => x.Id == 1);
+
+
+ var contentItem = _contentManager.New("Foo");
+ contentItem.As().Line = "Orchard VNext Rocks";
+ _contentManager.Create(contentItem);
+
+ var retrieveContentItem = _contentManager.Get(contentItem.Id);
+ var lineToSay = retrieveContentItem.As().Line;
+
+ return View("Index", _testDependency.SayHi(lineToSay));
}
+ }
- public ActionResult Index() {
- return View("Index", _testDependency.SayHi());
+ public class TestContentPartAHandler : ContentHandlerBase {
+ public override void Activating(ActivatingContentContext context) {
+ context.Builder.Weld();
}
}
}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Models/TestContentPartA.cs b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Models/TestContentPartA.cs
new file mode 100644
index 00000000000..130fd7b7511
--- /dev/null
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Models/TestContentPartA.cs
@@ -0,0 +1,11 @@
+using System;
+using OrchardVNext.ContentManagement;
+
+namespace OrchardVNext.Demo.Models {
+ public class TestContentPartA : ContentPart {
+ public string Line {
+ get { return this.Retrieve(x => x.Line); }
+ set { this.Store(x => x.Line, value); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Models/TestContentPartB.cs b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Models/TestContentPartB.cs
new file mode 100644
index 00000000000..0770aff1e7c
--- /dev/null
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Models/TestContentPartB.cs
@@ -0,0 +1,10 @@
+using OrchardVNext.ContentManagement;
+
+namespace OrchardVNext.Demo.Models {
+ public class TestContentPartB : ContentPart {
+ public int Line {
+ get { return this.Retrieve(x => x.Line); }
+ set { this.Store(x => x.Line, value); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/OrchardVNext.Demo.kproj b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/OrchardVNext.Demo.xproj
similarity index 74%
rename from src/OrchardVNext.Web/Modules/OrchardVNext.Demo/OrchardVNext.Demo.kproj
rename to src/OrchardVNext.Web/Modules/OrchardVNext.Demo/OrchardVNext.Demo.xproj
index 0ce34893434..3c4038a2967 100644
--- a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/OrchardVNext.Demo.kproj
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/OrchardVNext.Demo.xproj
@@ -4,7 +4,7 @@
14.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
+
19089e81-cefd-4008-a31c-541d82f58c54
OrchardVNext.Demo
@@ -18,10 +18,5 @@
2.0
3157
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Properties/debugSettings.json b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Properties/debugSettings.json
new file mode 100644
index 00000000000..a44fad34a3d
--- /dev/null
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Properties/debugSettings.json
@@ -0,0 +1,3 @@
+{
+ "Profiles": []
+}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Routes.cs b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Routes.cs
index cddd544cf1f..6a0683d6189 100644
--- a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Routes.cs
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/Routes.cs
@@ -1,13 +1,8 @@
-using OrchardVNext.Environment.Configuration;
+using System.Collections.Generic;
using OrchardVNext.Mvc.Routes;
-using System.Collections.Generic;
namespace OrchardVNext.Demo {
public class Routes : IRouteProvider {
- public readonly ShellSettings _shellSettings;
- public Routes(ShellSettings shellSettings) {
- _shellSettings = shellSettings;
- }
public IEnumerable GetRoutes() {
return new[] {
new RouteDescriptor {
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/project.json b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/project.json
index 54b651730cd..1f2372261dd 100644
--- a/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/project.json
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Demo/project.json
@@ -1,11 +1,11 @@
{
"dependencies": {
- "Microsoft.AspNet.Mvc": "6.0.0-beta4-*",
+ "Microsoft.AspNet.Mvc": "6.0.0-beta5-*",
"OrchardVNext": "",
"OrchardVNext.Test1": ""
},
"frameworks": {
- "aspnet50": { },
- "aspnetcore50": { }
+ "dnx451": { },
+ "dnxcore50": { }
}
}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/Class.cs b/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/Class.cs
index 03d9f2a3bba..2294b824585 100644
--- a/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/Class.cs
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/Class.cs
@@ -1,9 +1,9 @@
-using System;
+using System;
using OrchardVNext.Environment.Configuration;
namespace OrchardVNext.Test1 {
public interface ITestDependency : IDependency {
- string SayHi();
+ string SayHi(string line);
}
public class Class : ITestDependency {
@@ -12,8 +12,8 @@ public Class(ShellSettings shellSettings) {
_shellSettings = shellSettings;
}
- public string SayHi() {
- return string.Format("Hi from tenant {0}", _shellSettings.Name);
+ public string SayHi(string line) {
+ return string.Format("Hi from tenant {0} - {1}", _shellSettings.Name, line);
}
}
}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/OrchardVNext.Test1.kproj b/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/OrchardVNext.Test1.xproj
similarity index 74%
rename from src/OrchardVNext.Web/Modules/OrchardVNext.Test1/OrchardVNext.Test1.kproj
rename to src/OrchardVNext.Web/Modules/OrchardVNext.Test1/OrchardVNext.Test1.xproj
index 747d33c4379..e2384970781 100644
--- a/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/OrchardVNext.Test1.kproj
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/OrchardVNext.Test1.xproj
@@ -4,7 +4,7 @@
14.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
+
44cf51fb-7c14-4471-b113-9286bd41a783
OrchardVNext.Test1
@@ -18,10 +18,5 @@
2.0
49881
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/TestMiddleware.cs b/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/TestMiddleware.cs
index 38ef64d29e4..38a014b703d 100644
--- a/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/TestMiddleware.cs
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/TestMiddleware.cs
@@ -1,4 +1,4 @@
-using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using OrchardVNext.Middleware;
using System;
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/project.json b/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/project.json
index 7c276bf9c82..d6f1b6fec34 100644
--- a/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/project.json
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Test1/project.json
@@ -1,10 +1,9 @@
{
"dependencies": {
- "Microsoft.AspNet.Server.IIS": "1.0.0-beta4-*",
"OrchardVNext": ""
},
"frameworks": {
- "aspnet50": { },
- "aspnetcore50": { }
+ "dnx451": { },
+ "dnxcore50": { }
}
}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Test2/OrchardVNext.Test2.kproj b/src/OrchardVNext.Web/Modules/OrchardVNext.Test2/OrchardVNext.Test2.xproj
similarity index 74%
rename from src/OrchardVNext.Web/Modules/OrchardVNext.Test2/OrchardVNext.Test2.kproj
rename to src/OrchardVNext.Web/Modules/OrchardVNext.Test2/OrchardVNext.Test2.xproj
index 73132fce431..511c1497d07 100644
--- a/src/OrchardVNext.Web/Modules/OrchardVNext.Test2/OrchardVNext.Test2.kproj
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Test2/OrchardVNext.Test2.xproj
@@ -4,7 +4,7 @@
14.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
+
c0ba112a-fd23-451b-8876-912e1aead87b
OrchardVNext.Test2
@@ -18,10 +18,5 @@
2.0
13411
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Modules/OrchardVNext.Test2/project.json b/src/OrchardVNext.Web/Modules/OrchardVNext.Test2/project.json
index 7c276bf9c82..60664ae7ef4 100644
--- a/src/OrchardVNext.Web/Modules/OrchardVNext.Test2/project.json
+++ b/src/OrchardVNext.Web/Modules/OrchardVNext.Test2/project.json
@@ -1,10 +1,10 @@
{
"dependencies": {
- "Microsoft.AspNet.Server.IIS": "1.0.0-beta4-*",
+ "Microsoft.AspNet.Server.IIS": "1.0.0-beta5-*",
"OrchardVNext": ""
},
"frameworks": {
- "aspnet50": { },
- "aspnetcore50": { }
+ "dnx451": { },
+ "dnxcore50": { }
}
}
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/OrchardVNext.Web.kproj b/src/OrchardVNext.Web/OrchardVNext.Web.xproj
similarity index 73%
rename from src/OrchardVNext.Web/OrchardVNext.Web.kproj
rename to src/OrchardVNext.Web/OrchardVNext.Web.xproj
index 223239b2823..fe15c31522c 100644
--- a/src/OrchardVNext.Web/OrchardVNext.Web.kproj
+++ b/src/OrchardVNext.Web/OrchardVNext.Web.xproj
@@ -4,7 +4,7 @@
14.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
+
07d91819-4c81-434f-8de4-51d2b5a4eda8
Web
@@ -20,10 +20,5 @@
False
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/OrchardVNext.Web/Startup.cs b/src/OrchardVNext.Web/Startup.cs
index f1d217ac0df..b3071413d6b 100644
--- a/src/OrchardVNext.Web/Startup.cs
+++ b/src/OrchardVNext.Web/Startup.cs
@@ -1,10 +1,16 @@
-using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Builder;
+using Microsoft.Framework.DependencyInjection;
+using Microsoft.Framework.Logging;
using OrchardVNext.Environment;
namespace OrchardVNext.Web {
public class Startup {
- public void Configure(IApplicationBuilder app) {
- var host = OrchardStarter.CreateHost(app);
+ public void ConfigureServices(IServiceCollection services) {
+ OrchardStarter.ConfigureHost(services);
+ }
+
+ public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) {
+ var host = OrchardStarter.CreateHost(app, loggerFactory);
host.Initialize();
}
}
diff --git a/src/OrchardVNext.Web/project.json b/src/OrchardVNext.Web/project.json
index 63bd4f51896..db74950861b 100644
--- a/src/OrchardVNext.Web/project.json
+++ b/src/OrchardVNext.Web/project.json
@@ -3,28 +3,31 @@
"version": "2.0.0-*",
"exclude": [
"wwwroot",
+ "App_Data",
"Core",
"Modules",
"Themes"
],
"packExclude": [
+ "node_modules",
+ "bower_components",
"**.kproj",
"**.user",
"**.vspscc"
],
"dependencies": {
- "Microsoft.AspNet.Server.IIS": "1.0.0-beta4-*",
- "Microsoft.AspNet.Mvc": "6.0.0-beta4-*",
- "Microsoft.AspNet.Hosting": "1.0.0-beta4-*",
- "Microsoft.AspNet.Server.WebListener": "1.0.0-beta4-*",
- "OrchardVNext": ""
+ "Microsoft.AspNet.Server.IIS": "1.0.0-beta5-*",
+ "Microsoft.AspNet.Mvc": "6.0.0-beta5-*",
+ "Microsoft.AspNet.Hosting": "1.0.0-beta5-*",
+ "Microsoft.AspNet.Server.WebListener": "1.0.0-beta5-*",
+ "OrchardVNext": ""
},
"commands": {
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://local.orchardvnext.test1.com;http://local.orchardvnext.test2.com"
},
"compilationOptions": { "define": [ "TRACE" ], "warningsAsErrors": true },
"frameworks": {
- "aspnet50": { },
- "aspnetcore50": { }
+ "dnx451": { },
+ "dnxcore50": { }
}
}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/ContentExtensions.cs b/src/OrchardVNext/ContentManagement/ContentExtensions.cs
new file mode 100644
index 00000000000..d90a3856fa3
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/ContentExtensions.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace OrchardVNext.ContentManagement {
+ public static class ContentExtensions {
+ /* Aggregate item/part type casting extension methods */
+
+ public static bool Is(this IContent content) {
+ return content == null ? false : content.ContentItem.Has(typeof(T));
+ }
+ public static T As(this IContent content) where T : IContent {
+ return content == null ? default(T) : (T)content.ContentItem.Get(typeof(T));
+ }
+
+ public static bool Has(this IContent content) {
+ return content == null ? false : content.ContentItem.Has(typeof(T));
+ }
+ public static T Get(this IContent content) where T : IContent {
+ return content == null ? default(T) : (T)content.ContentItem.Get(typeof(T));
+ }
+
+ public static IEnumerable AsPart(this IEnumerable items) where T : IContent {
+ return items == null ? null : items.Where(item => item.Is()).Select(item => item.As());
+ }
+
+ public static bool IsPublished(this IContent content) {
+ return content.ContentItem.VersionRecord != null && content.ContentItem.VersionRecord.Published;
+ }
+ public static bool HasDraft(this IContent content) {
+ return (
+ (content.ContentItem.VersionRecord != null)
+ && ((content.ContentItem.VersionRecord.Published == false)
+ || (content.ContentItem.VersionRecord.Published && content.ContentItem.VersionRecord.Latest == false)));
+ }
+ }
+}
diff --git a/src/OrchardVNext/ContentManagement/ContentField.cs b/src/OrchardVNext/ContentManagement/ContentField.cs
new file mode 100644
index 00000000000..1079b658030
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/ContentField.cs
@@ -0,0 +1,14 @@
+using OrchardVNext.ContentManagement.FieldStorage;
+using OrchardVNext.ContentManagement.MetaData.Models;
+
+namespace OrchardVNext.ContentManagement {
+ public class ContentField {
+ public string Name { get { return PartFieldDefinition.Name; } }
+ public string DisplayName { get { return PartFieldDefinition.DisplayName; } }
+
+ public ContentPartFieldDefinition PartFieldDefinition { get; set; }
+ public ContentFieldDefinition FieldDefinition { get { return PartFieldDefinition.FieldDefinition; } }
+
+ public IFieldStorage Storage { get; set; }
+ }
+}
diff --git a/src/OrchardVNext/ContentManagement/ContentItem.cs b/src/OrchardVNext/ContentManagement/ContentItem.cs
new file mode 100644
index 00000000000..219cbe0c43c
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/ContentItem.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using OrchardVNext.ContentManagement.MetaData.Models;
+using OrchardVNext.ContentManagement.Records;
+
+namespace OrchardVNext.ContentManagement {
+ public class ContentItem : IContent {
+ public ContentItem() {
+ _parts = new List();
+ }
+
+ private readonly IList _parts;
+
+ ContentItem IContent.ContentItem => this;
+
+ public int Id { get { return Record?.Id ?? 0; } }
+ public int Version { get { return VersionRecord?.Number ?? 0; } }
+
+ public string ContentType { get; set; }
+ public ContentTypeDefinition TypeDefinition { get; set; }
+ public ContentItemRecord Record { get { return VersionRecord?.ContentItemRecord; } }
+ public ContentItemVersionRecord VersionRecord { get; set; }
+
+ public IEnumerable Parts => _parts;
+
+ public IContentManager ContentManager { get; set; }
+
+ public bool Has(Type partType) {
+ return partType == typeof(ContentItem) || _parts.Any(partType.IsInstanceOfType);
+ }
+
+ public IContent Get(Type partType) {
+ if (partType == typeof(ContentItem))
+ return this;
+ return _parts.FirstOrDefault(partType.IsInstanceOfType);
+ }
+
+ public void Weld(ContentPart part) {
+ part.ContentItem = this;
+ _parts.Add(part);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/ContentPart.cs b/src/OrchardVNext/ContentManagement/ContentPart.cs
new file mode 100644
index 00000000000..7832f877313
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/ContentPart.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Microsoft.AspNet.Mvc;
+using OrchardVNext.ContentManagement.MetaData.Models;
+
+namespace OrchardVNext.ContentManagement {
+ public class ContentPart : IContent {
+ private readonly IList _fields;
+
+ public ContentPart() {
+ _fields = new List();
+ }
+
+ public virtual ContentItem ContentItem { get; set; }
+
+ ///
+ /// The ContentItem's identifier.
+ ///
+ [HiddenInput(DisplayValue = false)]
+ public int Id => ContentItem.Id;
+
+ public ContentTypeDefinition TypeDefinition => ContentItem.TypeDefinition;
+ public ContentTypePartDefinition TypePartDefinition { get; set; }
+ public ContentPartDefinition PartDefinition => TypePartDefinition.PartDefinition;
+ public SettingsDictionary Settings => TypePartDefinition.Settings;
+
+ public IEnumerable Fields => _fields;
+
+
+ public bool Has(Type fieldType, string fieldName) {
+ return _fields.Any(field => field.Name == fieldName && fieldType.IsInstanceOfType(field));
+ }
+
+ public ContentField Get(Type fieldType, string fieldName) {
+ return _fields.FirstOrDefault(field => field.Name == fieldName && fieldType.IsInstanceOfType(field));
+ }
+
+ public void Weld(ContentField field) {
+ _fields.Add(field);
+ }
+
+ public T Retrieve(string fieldName) {
+ return InfosetHelper.Retrieve(this, fieldName);
+ }
+
+ public T RetrieveVersioned(string fieldName) {
+ return this.Retrieve(fieldName, true);
+ }
+
+ public virtual void Store(string fieldName, T value) {
+ InfosetHelper.Store(this, fieldName, value);
+ }
+
+ public virtual void StoreVersioned(string fieldName, T value) {
+ this.Store(fieldName, value, true);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/DefaultContentManager.cs b/src/OrchardVNext/ContentManagement/DefaultContentManager.cs
new file mode 100644
index 00000000000..9e14271fcde
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/DefaultContentManager.cs
@@ -0,0 +1,756 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using OrchardVNext.ContentManagement.Handlers;
+using OrchardVNext.ContentManagement.MetaData;
+using OrchardVNext.ContentManagement.MetaData.Builders;
+using OrchardVNext.ContentManagement.MetaData.Models;
+using OrchardVNext.ContentManagement.Records;
+using OrchardVNext.Data;
+using OrchardVNext.Environment.Configuration;
+
+namespace OrchardVNext.ContentManagement {
+ public class DefaultContentManager : IContentManager {
+ private readonly IContentDefinitionManager _contentDefinitionManager;
+ private readonly IContentManagerSession _contentManagerSession;
+ private readonly IEnumerable _handlers;
+ private readonly IContentItemStore _contentItemStore;
+ private readonly IContentStorageProvider _contentStorageProvider;
+ private readonly ShellSettings _shellSettings;
+
+ private const string Published = "Published";
+ private const string Draft = "Draft";
+
+ public DefaultContentManager(
+ IContentDefinitionManager contentDefinitionManager,
+ IContentManagerSession contentManagerSession,
+ IEnumerable handlers,
+ IContentItemStore contentItemStore,
+ IContentStorageProvider contentStorageProvider,
+ ShellSettings shellSettings) {
+ _contentDefinitionManager = contentDefinitionManager;
+ _contentManagerSession = contentManagerSession;
+ _shellSettings = shellSettings;
+ _handlers = handlers;
+ _contentItemStore = contentItemStore;
+ _contentStorageProvider = contentStorageProvider;
+ }
+
+ public IEnumerable Handlers => _handlers;
+
+ public IEnumerable GetContentTypeDefinitions() {
+ return _contentDefinitionManager.ListTypeDefinitions();
+ }
+
+ public virtual ContentItem New(string contentType) {
+ var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentType);
+ if (contentTypeDefinition == null) {
+ contentTypeDefinition = new ContentTypeDefinitionBuilder().Named(contentType).Build();
+ }
+
+ // create a new kernel for the model instance
+ var context = new ActivatingContentContext {
+ ContentType = contentTypeDefinition.Name,
+ Definition = contentTypeDefinition,
+ Builder = new ContentItemBuilder(contentTypeDefinition)
+ };
+
+ // invoke handlers to weld aspects onto kernel
+ Handlers.Invoke(handler => handler.Activating(context));
+
+ var context2 = new ActivatedContentContext {
+ ContentType = contentType,
+ ContentItem = context.Builder.Build()
+ };
+
+ // back-reference for convenience (e.g. getting metadata when in a view)
+ context2.ContentItem.ContentManager = this;
+
+ Handlers.Invoke(handler => handler.Activated(context2));
+
+ var context3 = new InitializingContentContext {
+ ContentType = context2.ContentType,
+ ContentItem = context2.ContentItem,
+ };
+
+ Handlers.Invoke(handler => handler.Initializing(context3));
+ Handlers.Invoke(handler => handler.Initialized(context3));
+
+ // composite result is returned
+ return context3.ContentItem;
+ }
+
+ public virtual ContentItem Get(int id) {
+ return Get(id, VersionOptions.Published);
+ }
+
+ public virtual ContentItem Get(int id, VersionOptions options) {
+ ContentItem contentItem;
+
+ ContentItemVersionRecord versionRecord = null;
+
+ // obtain the root records based on version options
+ if (options.VersionRecordId != 0) {
+ // short-circuit if item held in session
+ if (_contentManagerSession.RecallVersionRecordId(options.VersionRecordId, out contentItem)) {
+ return contentItem;
+ }
+
+ versionRecord = _contentItemStore.Get(id, options).VersionRecord;
+ }
+ else if (options.VersionNumber != 0) {
+ // short-circuit if item held in session
+ if (_contentManagerSession.RecallVersionNumber(id, options.VersionNumber, out contentItem)) {
+ return contentItem;
+ }
+
+ versionRecord = _contentItemStore.Get(id, options).VersionRecord;
+ }
+ else if (_contentManagerSession.RecallContentRecordId(id, out contentItem)) {
+ // try to reload a previously loaded published content item
+
+ if (options.IsPublished) {
+ return contentItem;
+ }
+
+ versionRecord = contentItem.VersionRecord;
+ }
+
+ // no record means content item is not in db
+ if (versionRecord == null) {
+ // check in memory
+ var record = _contentItemStore.Get(id, options).VersionRecord;
+ if (record == null) {
+ return null;
+ }
+
+ versionRecord = record;
+ }
+
+ // return item if obtained earlier in session
+ if (_contentManagerSession.RecallVersionRecordId(versionRecord.Id, out contentItem)) {
+ if (options.IsDraftRequired && versionRecord.Published) {
+ return BuildNewVersion(contentItem);
+ }
+ return contentItem;
+ }
+
+ // allocate instance and set record property
+ contentItem = New(versionRecord.ContentItemRecord.ContentType.Name);
+ contentItem.VersionRecord = versionRecord;
+
+ // store in session prior to loading to avoid some problems with simple circular dependencies
+ _contentManagerSession.Store(contentItem);
+
+ // create a context with a new instance to load
+ var context = new LoadContentContext(contentItem);
+
+ // invoke handlers to acquire state, or at least establish lazy loading callbacks
+ Handlers.Invoke(handler => handler.Loading(context));
+ Handlers.Invoke(handler => handler.Loaded(context));
+
+ // when draft is required and latest is published a new version is appended
+ if (options.IsDraftRequired && versionRecord.Published) {
+ contentItem = BuildNewVersion(context.ContentItem);
+ }
+
+ return contentItem;
+ }
+
+ // public virtual IEnumerable GetAllVersions(int id) {
+ // return _contentItemVersionRepository
+ // .Fetch(x => x.ContentItemRecord.Id == id)
+ // .OrderBy(x => x.Number)
+ // .Select(x => Get(x.Id, VersionOptions.VersionRecord(x.Id)));
+ // }
+
+ // public IEnumerable GetMany(IEnumerable ids, VersionOptions options) where T : class, IContent {
+ // var contentItemVersionRecords = GetManyImplementation(hints, (contentItemCriteria, contentItemVersionCriteria) => {
+ // contentItemCriteria.Add(Restrictions.In("Id", ids.ToArray()));
+ // if (options.IsPublished) {
+ // contentItemVersionCriteria.Add(Restrictions.Eq("Published", true));
+ // }
+ // else if (options.IsLatest) {
+ // contentItemVersionCriteria.Add(Restrictions.Eq("Latest", true));
+ // }
+ // else if (options.IsDraft && !options.IsDraftRequired) {
+ // contentItemVersionCriteria.Add(
+ // Restrictions.And(Restrictions.Eq("Published", false),
+ // Restrictions.Eq("Latest", true)));
+ // }
+ // else if (options.IsDraft || options.IsDraftRequired) {
+ // contentItemVersionCriteria.Add(Restrictions.Eq("Latest", true));
+ // }
+ // });
+
+ // var itemsById = contentItemVersionRecords
+ // .Select(r => Get(r.ContentItemRecord.Id, options.IsDraftRequired ? options : VersionOptions.VersionRecord(r.Id)))
+ // .GroupBy(ci => ci.Id)
+ // .ToDictionary(g => g.Key);
+
+ // return ids.SelectMany(id => {
+ // IGrouping values;
+ // return itemsById.TryGetValue(id, out values) ? values : Enumerable.Empty();
+ // }).AsPart().ToArray();
+ // }
+
+
+ // public IEnumerable GetManyByVersionId(IEnumerable versionRecordIds) {
+ // var contentItemVersionRecords = GetManyImplementation((contentItemCriteria, contentItemVersionCriteria) =>
+ // contentItemVersionCriteria.Add(Restrictions.In("Id", versionRecordIds.ToArray())));
+
+ // var itemsById = contentItemVersionRecords
+ // .Select(r => Get(r.ContentItemRecord.Id, VersionOptions.VersionRecord(r.Id)))
+ // .GroupBy(ci => ci.VersionRecord.Id)
+ // .ToDictionary(g => g.Key);
+
+ // return versionRecordIds.SelectMany(id => {
+ // IGrouping values;
+ // return itemsById.TryGetValue(id, out values) ? values : Enumerable.Empty();
+ // }).ToArray();
+ // }
+
+ // public IEnumerable GetManyByVersionId(IEnumerable versionRecordIds) where T : class, IContent {
+ // return GetManyByVersionId(versionRecordIds).AsPart();
+ // }
+
+ // private IEnumerable GetManyImplementation(Action predicate) {
+ // var session = _sessionLocator.Value.For(typeof (ContentItemRecord));
+ // var contentItemVersionCriteria = session.CreateCriteria(typeof (ContentItemVersionRecord));
+ // var contentItemCriteria = contentItemVersionCriteria.CreateCriteria("ContentItemRecord");
+ // predicate(contentItemCriteria, contentItemVersionCriteria);
+
+ // var contentItemMetadata = session.SessionFactory.GetClassMetadata(typeof (ContentItemRecord));
+ // var contentItemVersionMetadata = session.SessionFactory.GetClassMetadata(typeof (ContentItemVersionRecord));
+
+ // if (hints != QueryHints.Empty) {
+ // // break apart and group hints by their first segment
+ // var hintDictionary = hints.Records
+ // .Select(hint => new { Hint = hint, Segments = hint.Split('.') })
+ // .GroupBy(item => item.Segments.FirstOrDefault())
+ // .ToDictionary(grouping => grouping.Key, StringComparer.InvariantCultureIgnoreCase);
+
+ // // locate hints that match properties in the ContentItemVersionRecord
+ // foreach (var hit in contentItemVersionMetadata.PropertyNames.Where(hintDictionary.ContainsKey).SelectMany(key => hintDictionary[key])) {
+ // contentItemVersionCriteria.SetFetchMode(hit.Hint, FetchMode.Eager);
+ // hit.Segments.Take(hit.Segments.Count() - 1).Aggregate(contentItemVersionCriteria, ExtendCriteria);
+ // }
+
+ // // locate hints that match properties in the ContentItemRecord
+ // foreach (var hit in contentItemMetadata.PropertyNames.Where(hintDictionary.ContainsKey).SelectMany(key => hintDictionary[key])) {
+ // contentItemVersionCriteria.SetFetchMode("ContentItemRecord." + hit.Hint, FetchMode.Eager);
+ // hit.Segments.Take(hit.Segments.Count() - 1).Aggregate(contentItemCriteria, ExtendCriteria);
+ // }
+
+ // if (hintDictionary.SelectMany(x => x.Value).Any(x => x.Segments.Count() > 1))
+ // contentItemVersionCriteria.SetResultTransformer(new DistinctRootEntityResultTransformer());
+ // }
+
+ // contentItemCriteria.SetCacheable(true);
+
+ // return contentItemVersionCriteria.List();
+ // }
+
+ // private static ICriteria ExtendCriteria(ICriteria criteria, string segment) {
+ // return criteria.GetCriteriaByPath(segment) ?? criteria.CreateCriteria(segment, JoinType.LeftOuterJoin);
+ // }
+
+ public virtual void Publish(ContentItem contentItem) {
+ if (contentItem.VersionRecord.Published) {
+ return;
+ }
+ // create a context for the item and it's previous published record
+ var previous = contentItem.Record.Versions.SingleOrDefault(x => x.Published);
+ var context = new PublishContentContext(contentItem, previous);
+
+ // invoke handlers to acquire state, or at least establish lazy loading callbacks
+ Handlers.Invoke(handler => handler.Publishing(context));
+
+ if (context.Cancel) {
+ return;
+ }
+
+ if (previous != null) {
+ previous.Published = false;
+ }
+ contentItem.VersionRecord.Published = true;
+
+ Handlers.Invoke(handler => handler.Published(context));
+ }
+
+ public virtual void Unpublish(ContentItem contentItem) {
+ ContentItem publishedItem;
+ if (contentItem.VersionRecord.Published) {
+ // the version passed in is the published one
+ publishedItem = contentItem;
+ }
+ else {
+ // try to locate the published version of this item
+ publishedItem = Get(contentItem.Id, VersionOptions.Published);
+ }
+
+ if (publishedItem == null) {
+ // no published version exists. no work to perform.
+ return;
+ }
+
+ // create a context for the item. the publishing version is null in this case
+ // and the previous version is the one active prior to unpublishing. handlers
+ // should take this null check into account
+ var context = new PublishContentContext(contentItem, publishedItem.VersionRecord) {
+ PublishingItemVersionRecord = null
+ };
+
+ Handlers.Invoke(handler => handler.Unpublishing(context));
+
+ publishedItem.VersionRecord.Published = false;
+
+ Handlers.Invoke(handler => handler.Unpublished(context));
+ }
+
+ // public virtual void Remove(ContentItem contentItem) {
+ // var activeVersions = _contentItemVersionRepository.Fetch(x => x.ContentItemRecord == contentItem.Record && (x.Published || x.Latest));
+ // var context = new RemoveContentContext(contentItem);
+
+ // Handlers.Invoke(handler => handler.Removing(context), Logger);
+
+ // foreach (var version in activeVersions) {
+ // if (version.Published) {
+ // version.Published = false;
+ // }
+ // if (version.Latest) {
+ // version.Latest = false;
+ // }
+ // }
+
+ // Handlers.Invoke(handler => handler.Removed(context), Logger);
+ // }
+
+ // public virtual void Destroy(ContentItem contentItem) {
+ // var session = _sessionLocator.Value.For(typeof(ContentItemVersionRecord));
+ // var context = new DestroyContentContext(contentItem);
+
+ // // Give storage filters a chance to delete content part records.
+ // Handlers.Invoke(handler => handler.Destroying(context), Logger);
+
+ // // Delete content item version and content item records.
+ // session
+ // .CreateQuery("delete from Orchard.ContentManagement.Records.ContentItemVersionRecord civ where civ.ContentItemRecord.Id = (:id)")
+ // .SetParameter("id", contentItem.Id)
+ // .ExecuteUpdate();
+
+ // // Delete the content item record itself.
+ // session
+ // .CreateQuery("delete from Orchard.ContentManagement.Records.ContentItemRecord ci where ci.Id = (:id)")
+ // .SetParameter("id", contentItem.Id)
+ // .ExecuteUpdate();
+
+ // Handlers.Invoke(handler => handler.Destroyed(context), Logger);
+ // }
+
+ protected virtual ContentItem BuildNewVersion(ContentItem existingContentItem) {
+ var contentItemRecord = existingContentItem.Record;
+
+ // locate the existing and the current latest versions, allocate building version
+ var existingItemVersionRecord = existingContentItem.VersionRecord;
+ var buildingItemVersionRecord = new ContentItemVersionRecord {
+ ContentItemRecord = contentItemRecord,
+ Latest = true,
+ Published = false,
+ Data = existingItemVersionRecord.Data,
+ };
+
+
+ var latestVersion = contentItemRecord.Versions.SingleOrDefault(x => x.Latest);
+
+ if (latestVersion != null) {
+ latestVersion.Latest = false;
+ buildingItemVersionRecord.Number = latestVersion.Number + 1;
+ }
+ else {
+ buildingItemVersionRecord.Number = contentItemRecord.Versions.Max(x => x.Number) + 1;
+ }
+
+ contentItemRecord.Versions.Add(buildingItemVersionRecord);
+ _contentStorageProvider.Store(buildingItemVersionRecord);
+
+ var buildingContentItem = New(existingContentItem.ContentType);
+ buildingContentItem.VersionRecord = buildingItemVersionRecord;
+
+ var context = new VersionContentContext {
+ Id = existingContentItem.Id,
+ ContentType = existingContentItem.ContentType,
+ ContentItemRecord = contentItemRecord,
+ ExistingContentItem = existingContentItem,
+ BuildingContentItem = buildingContentItem,
+ ExistingItemVersionRecord = existingItemVersionRecord,
+ BuildingItemVersionRecord = buildingItemVersionRecord,
+ };
+ Handlers.Invoke(handler => handler.Versioning(context));
+ Handlers.Invoke(handler => handler.Versioned(context));
+
+ return context.BuildingContentItem;
+ }
+
+ public virtual void Create(ContentItem contentItem) {
+ Create(contentItem, VersionOptions.Published);
+ }
+
+ public virtual void Create(ContentItem contentItem, VersionOptions options) {
+ if (contentItem.VersionRecord == null) {
+ // produce root record to determine the model id
+ contentItem.VersionRecord = new ContentItemVersionRecord {
+ ContentItemRecord = new ContentItemRecord(),
+ Number = 1,
+ Latest = true,
+ Published = true
+ };
+ }
+
+ // add to the collection manually for the created case
+ contentItem.VersionRecord.ContentItemRecord.Versions.Add(contentItem.VersionRecord);
+
+ // version may be specified
+ if (options.VersionNumber != 0) {
+ contentItem.VersionRecord.Number = options.VersionNumber;
+ }
+
+ // draft flag on create is required for explicitly-published content items
+ if (options.IsDraft) {
+ contentItem.VersionRecord.Published = false;
+ }
+
+ _contentItemStore.Store(contentItem);
+
+ // build a context with the initialized instance to create
+ var context = new CreateContentContext(contentItem);
+
+ // invoke handlers to add information to persistent stores
+ Handlers.Invoke(handler => handler.Creating(context));
+
+ // deferring the assignment of ContentType as loading a Record might force NHibernate to AutoFlush
+ // the ContentPart, and needs the ContentItemRecord to be created before (created in previous statement)
+ contentItem.VersionRecord.ContentItemRecord.ContentType = AcquireContentTypeRecord(contentItem.ContentType);
+
+ Handlers.Invoke(handler => handler.Created(context));
+
+
+ if (options.IsPublished) {
+ var publishContext = new PublishContentContext(contentItem, null);
+
+ // invoke handlers to acquire state, or at least establish lazy loading callbacks
+ Handlers.Invoke(handler => handler.Publishing(publishContext));
+
+ // invoke handlers to acquire state, or at least establish lazy loading callbacks
+ Handlers.Invoke(handler => handler.Published(publishContext));
+ }
+ }
+
+ // public virtual ContentItem Clone(ContentItem contentItem) {
+ // // Mostly taken from: http://orchard.codeplex.com/discussions/396664
+ // var importContentSession = new ImportContentSession(this);
+
+ // var element = Export(contentItem);
+
+ // // If a handler prevents this element from being exported, it can't be cloned
+ // if (element == null) {
+ // throw new InvalidOperationException("The content item couldn't be cloned because a handler prevented it from being exported.");
+ // }
+
+ // var elementId = element.Attribute("Id");
+ // var copyId = elementId.Value + "-copy";
+ // elementId.SetValue(copyId);
+ // var status = element.Attribute("Status");
+ // if (status != null) status.SetValue("Draft"); // So the copy is always a draft.
+
+ // importContentSession.Set(copyId, element.Name.LocalName);
+
+ // Import(element, importContentSession);
+
+ // return importContentSession.Get(copyId, element.Name.LocalName);
+ // }
+
+ // public virtual ContentItem Restore(ContentItem contentItem, VersionOptions options) {
+ // // Invoke handlers.
+ // Handlers.Invoke(handler => handler.Restoring(new RestoreContentContext(contentItem, options)), Logger);
+
+ // // Get the latest version.
+ // var versions = contentItem.Record.Versions.OrderBy(x => x.Number).ToArray();
+ // var latestVersionRecord = versions.SingleOrDefault(x => x.Latest) ?? versions.Last();
+
+ // // Get the specified version.
+ // var specifiedVersionContentItem =
+ // contentItem.VersionRecord.Number == options.VersionNumber || contentItem.VersionRecord.Id == options.VersionRecordId
+ // ? contentItem
+ // : Get(contentItem.Id, options);
+
+ // // Create a new version record based on the specified version record.
+ // var rolledBackContentItem = BuildNewVersion(specifiedVersionContentItem);
+ // rolledBackContentItem.VersionRecord.Published = options.IsPublished;
+
+ // // Invoke handlers.
+ // Handlers.Invoke(handler => handler.Restored(new RestoreContentContext(rolledBackContentItem, options)), Logger);
+
+ // if (options.IsPublished) {
+ // // Unpublish the latest version.
+ // latestVersionRecord.Published = false;
+
+ // var publishContext = new PublishContentContext(rolledBackContentItem, previousItemVersionRecord: latestVersionRecord);
+
+ // Handlers.Invoke(handler => handler.Publishing(publishContext), Logger);
+ // Handlers.Invoke(handler => handler.Published(publishContext), Logger);
+ // }
+
+ // return rolledBackContentItem;
+ // }
+
+ // ///
+ // /// Lookup for a content item based on a . If multiple
+ // /// resolvers can give a result, the one with the highest priority is used. As soon as
+ // /// only one content item is returned from resolvers, it is returned as the result.
+ // ///
+ // /// The instance to lookup
+ // /// The instance represented by the identity object.
+ // public ContentItem ResolveIdentity(ContentIdentity contentIdentity) {
+ // var resolvers = _identityResolverSelectors.Value
+ // .Select(x => x.GetResolver(contentIdentity))
+ // .Where(x => x != null)
+ // .OrderByDescending(x => x.Priority);
+
+ // if (!resolvers.Any())
+ // return null;
+
+ // IEnumerable contentItems = null;
+ // foreach (var resolver in resolvers) {
+ // var resolved = resolver.Resolve(contentIdentity).ToArray();
+
+ // // first pass
+ // if (contentItems == null) {
+ // contentItems = resolved;
+ // }
+ // else { // subsquent passes means we need to intersect
+ // contentItems = contentItems.Intersect(resolved).ToArray();
+ // }
+
+ // if (contentItems.Count() == 1) {
+ // return contentItems.First();
+ // }
+ // }
+
+ // return contentItems.FirstOrDefault();
+ // }
+
+ // public ContentItemMetadata GetItemMetadata(IContent content) {
+ // var context = new GetContentItemMetadataContext {
+ // ContentItem = content.ContentItem,
+ // Metadata = new ContentItemMetadata()
+ // };
+
+ // Handlers.Invoke(handler => handler.GetContentItemMetadata(context), Logger);
+
+ // return context.Metadata;
+ // }
+
+ // public IEnumerable GetEditorGroupInfos(IContent content) {
+ // var metadata = GetItemMetadata(content);
+ // return metadata.EditorGroupInfo
+ // .GroupBy(groupInfo => groupInfo.Id)
+ // .Select(grouping => grouping.OrderBy(groupInfo => groupInfo.Position, new FlatPositionComparer()).FirstOrDefault());
+ // }
+
+ // public IEnumerable GetDisplayGroupInfos(IContent content) {
+ // var metadata = GetItemMetadata(content);
+ // return metadata.DisplayGroupInfo
+ // .GroupBy(groupInfo => groupInfo.Id)
+ // .Select(grouping => grouping.OrderBy(groupInfo => groupInfo.Position, new FlatPositionComparer()).FirstOrDefault());
+ // }
+
+ // public GroupInfo GetEditorGroupInfo(IContent content, string groupInfoId) {
+ // return GetEditorGroupInfos(content).FirstOrDefault(gi => string.Equals(gi.Id, groupInfoId, StringComparison.OrdinalIgnoreCase));
+ // }
+
+ // public GroupInfo GetDisplayGroupInfo(IContent content, string groupInfoId) {
+ // return GetDisplayGroupInfos(content).FirstOrDefault(gi => string.Equals(gi.Id, groupInfoId, StringComparison.OrdinalIgnoreCase));
+ // }
+
+ // public dynamic BuildDisplay(IContent content, string displayType = "", string groupId = "") {
+ // return _contentDisplay.Value.BuildDisplay(content, displayType, groupId);
+ // }
+
+ // public dynamic BuildEditor(IContent content, string groupId = "") {
+ // return _contentDisplay.Value.BuildEditor(content, groupId);
+ // }
+
+ // public dynamic UpdateEditor(IContent content, IUpdateModel updater, string groupId = "") {
+ // var context = new UpdateContentContext(content.ContentItem);
+
+ // Handlers.Invoke(handler => handler.Updating(context), Logger);
+
+ // var result = _contentDisplay.Value.UpdateEditor(content, updater, groupId);
+
+ // Handlers.Invoke(handler => handler.Updated(context), Logger);
+
+ // return result;
+ // }
+
+ // public void Clear() {
+ // }
+
+ // public IContentQuery Query() {
+ // var query = _context.Resolve(TypedParameter.From(this));
+ // return query.ForPart();
+ // }
+
+ // public IHqlQuery HqlQuery() {
+ // return new DefaultHqlQuery(this, _sessionLocator.Value.For(typeof(ContentItemVersionRecord)), _sqlStatementProviders.Value, _shellSettings);
+ // }
+
+ // // Insert or Update imported data into the content manager.
+ // // Call content item handlers.
+ // public void Import(XElement element, ImportContentSession importContentSession) {
+ // var elementId = element.Attribute("Id");
+ // if (elementId == null) {
+ // return;
+ // }
+
+ // var identity = elementId.Value;
+
+ // if (String.IsNullOrWhiteSpace(identity)) {
+ // return;
+ // }
+
+ // var status = element.Attribute("Status");
+
+ // var item = importContentSession.Get(identity, VersionOptions.Latest, XmlConvert.DecodeName(element.Name.LocalName));
+ // if (item == null) {
+ // item = New(XmlConvert.DecodeName(element.Name.LocalName));
+ // if (status != null && status.Value == "Draft") {
+ // Create(item, VersionOptions.Draft);
+ // }
+ // else {
+ // Create(item);
+ // }
+ // }
+
+ // // create a version record if import handlers need it
+ // if(item.VersionRecord == null) {
+ // item.VersionRecord = new ContentItemVersionRecord {
+ // ContentItemRecord = new ContentItemRecord {
+ // ContentType = AcquireContentTypeRecord(item.ContentType)
+ // },
+ // Number = 1,
+ // Latest = true,
+ // Published = true
+ // };
+ // }
+
+ // var context = new ImportContentContext(item, element, importContentSession);
+ // foreach (var contentHandler in Handlers) {
+ // contentHandler.Importing(context);
+ // }
+
+ // foreach (var contentHandler in Handlers) {
+ // contentHandler.Imported(context);
+ // }
+
+ // var savedItem = Get(item.Id, VersionOptions.Latest);
+
+ // // the item has been pre-created in the first pass of the import, create it in db
+ // if(savedItem == null) {
+ // if (status != null && status.Value == "Draft") {
+ // Create(item, VersionOptions.Draft);
+ // }
+ // else {
+ // Create(item);
+ // }
+ // }
+
+ // if (status == null || status.Value == Published) {
+ // Publish(item);
+ // }
+ // }
+
+ // public XElement Export(ContentItem contentItem) {
+ // var context = new ExportContentContext(contentItem, new XElement(XmlConvert.EncodeLocalName(contentItem.ContentType)));
+
+ // foreach (var contentHandler in Handlers) {
+ // contentHandler.Exporting(context);
+ // }
+
+ // foreach (var contentHandler in Handlers) {
+ // contentHandler.Exported(context);
+ // }
+
+ // if (context.Exclude) {
+ // return null;
+ // }
+
+ // context.Data.SetAttributeValue("Id", GetItemMetadata(contentItem).Identity.ToString());
+ // if (contentItem.IsPublished()) {
+ // context.Data.SetAttributeValue("Status", Published);
+ // }
+ // else {
+ // context.Data.SetAttributeValue("Status", Draft);
+ // }
+
+ // return context.Data;
+ // }
+
+ private ContentTypeRecord AcquireContentTypeRecord(string contentType) {
+
+ var contentTypeRecord = _contentStorageProvider
+ .Query(x => x.Name == contentType)
+ .FirstOrDefault();
+
+ if (contentTypeRecord == null) {
+ //TEMP: this is not safe... ContentItem types could be created concurrently?
+ contentTypeRecord = new ContentTypeRecord { Name = contentType };
+ _contentStorageProvider.Store(contentTypeRecord);
+ }
+
+ var contentTypeId = contentTypeRecord.Id;
+
+ // There is a case when a content type record is created locally but the transaction is actually
+ // cancelled. In this case we are caching an Id which is none existent, or might represent another
+ // content type. Thus we need to ensure that the cache is valid, or invalidate it and retrieve it
+ // another time.
+
+ var result = _contentStorageProvider
+ .Query(x => x.Id == contentTypeId)
+ .FirstOrDefault();
+
+ if (result != null && result.Name.Equals(contentType, StringComparison.OrdinalIgnoreCase)) {
+ return result;
+ }
+
+ // invalidate the cache entry and load it again
+ return AcquireContentTypeRecord(contentType);
+ }
+
+ // public void Index(ContentItem contentItem, IDocumentIndex documentIndex) {
+ // var indexContentContext = new IndexContentContext(contentItem, documentIndex);
+
+ // // dispatch to handlers to retrieve index information
+ // Handlers.Invoke(handler => handler.Indexing(indexContentContext), Logger);
+
+ // Handlers.Invoke(handler => handler.Indexed(indexContentContext), Logger);
+ // }
+ //}
+
+ //internal class CallSiteCollection : ConcurrentDictionary>> {
+ // private readonly Func>> _valueFactory;
+
+ // public CallSiteCollection(Func>> callSiteFactory) {
+ // _valueFactory = callSiteFactory;
+ // }
+
+ // public CallSiteCollection(Func callSiteBinderFactory) {
+ // _valueFactory = key => CallSite>.Create(callSiteBinderFactory(key));
+ // }
+
+ // public object Invoke(object callee, string key) {
+ // var callSite = GetOrAdd(key, _valueFactory);
+ // return callSite.Target(callSite, callee);
+ // }
+ }
+}
diff --git a/src/OrchardVNext/ContentManagement/DefaultContentManagerSession.cs b/src/OrchardVNext/ContentManagement/DefaultContentManagerSession.cs
new file mode 100644
index 00000000000..41cfe94cd4a
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/DefaultContentManagerSession.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+
+namespace OrchardVNext.ContentManagement {
+ public class DefaultContentManagerSession : IContentManagerSession {
+ private readonly IDictionary _itemByVersionRecordId = new Dictionary();
+ private readonly IDictionary, ContentItem> _itemByVersionNumber = new Dictionary, ContentItem>();
+ private readonly IDictionary _publishedItemsByContentRecordId = new Dictionary();
+
+ public void Store(ContentItem item) {
+ _itemByVersionRecordId.Add(item.VersionRecord.Id, item);
+ _itemByVersionNumber.Add(Tuple.Create(item.Id, item.Version), item);
+
+ // is it the Published version ?
+ if (item.VersionRecord.Latest && item.VersionRecord.Published) {
+ _publishedItemsByContentRecordId[item.Id] = item;
+ }
+ }
+
+ public bool RecallVersionRecordId(int id, out ContentItem item) {
+ return _itemByVersionRecordId.TryGetValue(id, out item);
+ }
+
+ public bool RecallVersionNumber(int id, int version, out ContentItem item) {
+ return _itemByVersionNumber.TryGetValue(Tuple.Create(id, version), out item);
+ }
+
+ public bool RecallContentRecordId(int id, out ContentItem item) {
+ return _publishedItemsByContentRecordId.TryGetValue(id, out item);
+ }
+
+ public void Clear() {
+ _itemByVersionRecordId.Clear();
+ _itemByVersionNumber.Clear();
+ _publishedItemsByContentRecordId.Clear();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/FieldStorage/FieldStorageProviderSelector.cs b/src/OrchardVNext/ContentManagement/FieldStorage/FieldStorageProviderSelector.cs
new file mode 100644
index 00000000000..3c018a82ed8
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/FieldStorage/FieldStorageProviderSelector.cs
@@ -0,0 +1,30 @@
+using System.Collections.Generic;
+using System.Linq;
+using OrchardVNext.ContentManagement.MetaData.Models;
+
+namespace OrchardVNext.ContentManagement.FieldStorage {
+ public class FieldStorageProviderSelector : IFieldStorageProviderSelector {
+ public const string Storage = "Storage";
+ public const string DefaultProviderName = "Infoset";
+
+ private readonly IEnumerable _storageProviders;
+
+ public FieldStorageProviderSelector(IEnumerable storageProviders) {
+ _storageProviders = storageProviders;
+ }
+
+ public IFieldStorageProvider GetProvider(ContentPartFieldDefinition partFieldDefinition) {
+ IFieldStorageProvider provider = null;
+
+ string storage;
+ if (partFieldDefinition.Settings.TryGetValue(Storage, out storage))
+ provider = Locate(storage);
+
+ return provider ?? Locate(DefaultProviderName);
+ }
+
+ private IFieldStorageProvider Locate(string providerName) {
+ return _storageProviders.FirstOrDefault(provider => provider.ProviderName == providerName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/FieldStorage/IFieldStorage.cs b/src/OrchardVNext/ContentManagement/FieldStorage/IFieldStorage.cs
new file mode 100644
index 00000000000..bd13ba174c6
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/FieldStorage/IFieldStorage.cs
@@ -0,0 +1,14 @@
+namespace OrchardVNext.ContentManagement.FieldStorage {
+ public interface IFieldStorage {
+ T Get(string name);
+ void Set(string name, T value);
+ }
+ public static class FieldStorageExtension{
+ public static T Get(this IFieldStorage storage) {
+ return storage.Get(null);
+ }
+ public static void Set(this IFieldStorage storage, T value) {
+ storage.Set(null, value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/FieldStorage/IFieldStorageProvider.cs b/src/OrchardVNext/ContentManagement/FieldStorage/IFieldStorageProvider.cs
new file mode 100644
index 00000000000..e9f0595b818
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/FieldStorage/IFieldStorageProvider.cs
@@ -0,0 +1,11 @@
+using OrchardVNext.ContentManagement.MetaData.Models;
+
+namespace OrchardVNext.ContentManagement.FieldStorage {
+ public interface IFieldStorageProvider : IDependency {
+ string ProviderName { get; }
+
+ IFieldStorage BindStorage(
+ ContentPart contentPart,
+ ContentPartFieldDefinition partFieldDefinition);
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/FieldStorage/IFieldStorageProviderSelector.cs b/src/OrchardVNext/ContentManagement/FieldStorage/IFieldStorageProviderSelector.cs
new file mode 100644
index 00000000000..7f49a5b021d
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/FieldStorage/IFieldStorageProviderSelector.cs
@@ -0,0 +1,7 @@
+using OrchardVNext.ContentManagement.MetaData.Models;
+
+namespace OrchardVNext.ContentManagement.FieldStorage {
+ public interface IFieldStorageProviderSelector : IDependency {
+ IFieldStorageProvider GetProvider(ContentPartFieldDefinition partFieldDefinition);
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/Infoset.cs b/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/Infoset.cs
new file mode 100644
index 00000000000..ef64d8e3356
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/Infoset.cs
@@ -0,0 +1,26 @@
+using System.Xml.Linq;
+
+namespace OrchardVNext.ContentManagement.FieldStorage.InfosetStorage {
+ public class Infoset {
+ private XElement _element;
+
+ private void SetElement(XElement value) {
+ _element = value;
+ }
+
+ public XElement Element {
+ get {
+ return _element ?? (_element = new XElement("Data"));
+ }
+ }
+
+ public string Data {
+ get {
+ return _element == null ? null : Element.ToString(SaveOptions.DisableFormatting);
+ }
+ set {
+ SetElement(string.IsNullOrEmpty(value) ? null : XElement.Parse(value, LoadOptions.PreserveWhitespace));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/InfosetHandler.cs b/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/InfosetHandler.cs
new file mode 100644
index 00000000000..474bbba0d8f
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/InfosetHandler.cs
@@ -0,0 +1,34 @@
+using OrchardVNext.ContentManagement.Handlers;
+
+namespace OrchardVNext.ContentManagement.FieldStorage.InfosetStorage {
+ public class InfosetHandler : ContentHandlerBase {
+ public override void Activating(ActivatingContentContext context) {
+ context.Builder.Weld();
+ }
+
+ public override void Creating(CreateContentContext context) {
+ var infosetPart = context.ContentItem.As();
+ if (infosetPart != null) {
+ context.ContentItemRecord.Data = infosetPart.Infoset.Data;
+ context.ContentItemVersionRecord.Data = infosetPart.VersionInfoset.Data;
+
+ infosetPart.Infoset = context.ContentItemRecord.Infoset;
+ infosetPart.VersionInfoset = context.ContentItemVersionRecord.Infoset;
+ }
+ }
+ public override void Loading(LoadContentContext context) {
+ var infosetPart = context.ContentItem.As();
+ if (infosetPart != null) {
+ infosetPart.Infoset = context.ContentItemRecord.Infoset;
+ infosetPart.VersionInfoset = context.ContentItemVersionRecord.Infoset;
+ }
+ }
+ public override void Versioning(VersionContentContext context) {
+ var infosetPart = context.BuildingContentItem.As();
+ if (infosetPart != null) {
+ infosetPart.Infoset = context.ContentItemRecord.Infoset;
+ infosetPart.VersionInfoset = context.BuildingItemVersionRecord.Infoset;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/InfosetPart.cs b/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/InfosetPart.cs
new file mode 100644
index 00000000000..c917869c9d4
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/InfosetPart.cs
@@ -0,0 +1,103 @@
+using System.Xml;
+using System.Xml.Linq;
+using System.Reflection;
+using OrchardVNext.ContentManagement.Records;
+
+namespace OrchardVNext.ContentManagement.FieldStorage.InfosetStorage {
+ public class InfosetPart : ContentPart {
+ public InfosetPart() {
+ Document = new DocumentRecord();
+ }
+
+ private DocumentRecord Document { get; set; }
+
+ public Infoset Infoset {
+ get { return Document.Infoset; }
+ set { Document.Infoset = value; }
+ }
+ public Infoset VersionInfoset {
+ get { return Document.VersionInfoset; }
+ set { Document.VersionInfoset = value; }
+ }
+
+ public string Get(string fieldName) {
+ return Get(fieldName, null);
+ }
+
+ public string Get(string fieldName, string valueName) {
+ return Get(typeof(TPart).Name, fieldName, valueName, typeof(TPart).GetTypeInfo().IsAssignableFrom(typeof(ContentItemVersionRecord).GetTypeInfo()));
+ }
+
+ public string Get(string partName, string fieldName) {
+ return Get(partName, fieldName, null, false);
+ }
+
+ public string GetVersioned(string partName, string fieldName) {
+ return Get(partName, fieldName, null, true);
+ }
+
+ public string Get(string partName, string fieldName, string valueName, bool versionable = false) {
+
+ var element = versionable ? VersionInfoset.Element : Infoset.Element;
+
+ var partElement = element.Element(XmlConvert.EncodeName(partName));
+ if (partElement == null) {
+ return null;
+ }
+ var fieldElement = partElement.Element(XmlConvert.EncodeName(fieldName));
+ if (fieldElement == null) {
+ return null;
+ }
+ if (string.IsNullOrEmpty(valueName)) {
+ return fieldElement.Value;
+ }
+ var valueAttribute = fieldElement.Attribute(XmlConvert.EncodeName(valueName));
+ if (valueAttribute == null) {
+ return null;
+ }
+ return valueAttribute.Value;
+ }
+
+ public void Set(string fieldName, string valueName, string value) {
+ Set(fieldName, value);
+ }
+
+ public void Set(string fieldName, string value) {
+ Set(typeof(TPart).Name, fieldName, null, value, typeof(TPart).GetTypeInfo().IsAssignableFrom(typeof(ContentItemVersionRecord).GetTypeInfo()));
+ }
+
+ public void Set(string partName, string fieldName, string value) {
+ Set(partName, fieldName, null, value, false);
+ }
+
+ public void SetVersioned(string partName, string fieldName, string value) {
+ Set(partName, fieldName, null, value, true);
+ }
+
+ public void Set(string partName, string fieldName, string valueName, string value, bool versionable = false) {
+
+ var element = versionable ? VersionInfoset.Element : Infoset.Element;
+
+ var encodedPartName = XmlConvert.EncodeName(partName);
+ var partElement = element.Element(encodedPartName);
+ if (partElement == null) {
+ partElement = new XElement(encodedPartName);
+ Infoset.Element.Add(partElement);
+ }
+
+ var encodedFieldName = XmlConvert.EncodeName(fieldName);
+ var fieldElement = partElement.Element(encodedFieldName);
+ if (fieldElement == null) {
+ fieldElement = new XElement(encodedFieldName);
+ partElement.Add(fieldElement);
+ }
+
+ if (string.IsNullOrEmpty(valueName)) {
+ fieldElement.Value = value ?? "";
+ }
+ else {
+ fieldElement.SetAttributeValue(XmlConvert.EncodeName(valueName), value);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/InfosetStorageProvider.cs b/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/InfosetStorageProvider.cs
new file mode 100644
index 00000000000..e8fb2654cb9
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/FieldStorage/InfosetStorage/InfosetStorageProvider.cs
@@ -0,0 +1,59 @@
+using System.Xml;
+using System.Xml.Linq;
+using OrchardVNext.ContentManagement.MetaData.Models;
+
+namespace OrchardVNext.ContentManagement.FieldStorage.InfosetStorage {
+ public class InfosetStorageProvider : IFieldStorageProvider {
+ public string ProviderName {
+ get { return FieldStorageProviderSelector.DefaultProviderName; }
+ }
+
+ public IFieldStorage BindStorage(ContentPart contentPart, ContentPartFieldDefinition partFieldDefinition) {
+ var partName = XmlConvert.EncodeLocalName(contentPart.PartDefinition.Name);
+ var fieldName = XmlConvert.EncodeLocalName(partFieldDefinition.Name);
+ var infosetPart = contentPart.As();
+
+ return new SimpleFieldStorage(
+ (name, valueType) => Get(infosetPart.ContentItem.VersionRecord == null ? infosetPart.Infoset.Element : infosetPart.VersionInfoset.Element, partName, fieldName, name),
+ (name, valueType, value) => Set(infosetPart.ContentItem.VersionRecord == null ? infosetPart.Infoset.Element : infosetPart.VersionInfoset.Element, partName, fieldName, name, value));
+ }
+
+ private static string Get(XElement element, string partName, string fieldName, string valueName) {
+ var partElement = element.Element(partName);
+ if (partElement == null) {
+ return null;
+ }
+ var fieldElement = partElement.Element(fieldName);
+ if (fieldElement == null) {
+ return null;
+ }
+ if (string.IsNullOrEmpty(valueName)) {
+ return fieldElement.Value;
+ }
+ var valueAttribute = fieldElement.Attribute(XmlConvert.EncodeLocalName(valueName));
+ if (valueAttribute == null) {
+ return null;
+ }
+ return valueAttribute.Value;
+ }
+
+ private void Set(XElement element, string partName, string fieldName, string valueName, string value) {
+ var partElement = element.Element(partName);
+ if (partElement == null) {
+ partElement = new XElement(partName);
+ element.Add(partElement);
+ }
+ var fieldElement = partElement.Element(fieldName);
+ if (fieldElement == null) {
+ fieldElement = new XElement(fieldName);
+ partElement.Add(fieldElement);
+ }
+ if (string.IsNullOrEmpty(valueName)) {
+ fieldElement.Value = value;
+ }
+ else {
+ fieldElement.SetAttributeValue(XmlConvert.EncodeLocalName(valueName), value);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/FieldStorage/SimpleFieldStorage.cs b/src/OrchardVNext/ContentManagement/FieldStorage/SimpleFieldStorage.cs
new file mode 100644
index 00000000000..4df63175b9e
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/FieldStorage/SimpleFieldStorage.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Globalization;
+using System.Xml;
+using System.Reflection;
+
+namespace OrchardVNext.ContentManagement.FieldStorage {
+ public class SimpleFieldStorage : IFieldStorage {
+ public SimpleFieldStorage(Func getter, Action setter) {
+ Getter = getter;
+ Setter = setter;
+ }
+
+ public Func Getter { get; set; }
+ public Action Setter { get; set; }
+
+ public T Get(string name) {
+ var value = Getter(name, typeof(T));
+ if(string.IsNullOrEmpty(value)) {
+ return default(T);
+ }
+
+ var t = typeof (T);
+
+ // the T is nullable, convert using underlying type
+ if (t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) {
+ t = Nullable.GetUnderlyingType(t);
+ }
+
+ // using a special case for DateTime as it would lose milliseconds otherwise
+ if (typeof(T) == typeof(DateTime)) {
+ var result = XmlConvert.ToDateTime(value, XmlDateTimeSerializationMode.Utc);
+ return (T) (object)result;
+ }
+
+ return (T)Convert.ChangeType(value, t, CultureInfo.InvariantCulture);
+ }
+
+ public void Set(string name, T value) {
+
+ // using a special case for DateTime as it would lose milliseconds otherwise
+ if (typeof(T) == typeof(DateTime)) {
+ var text = ((DateTime)(object)value).ToString("o", CultureInfo.InvariantCulture);
+ Setter(name, typeof(T), text);
+ }
+ else {
+ Setter(name, typeof (T), Convert.ToString(value, CultureInfo.InvariantCulture));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/Handlers/ActivatedContentContext.cs b/src/OrchardVNext/ContentManagement/Handlers/ActivatedContentContext.cs
new file mode 100644
index 00000000000..f9ed27f69a8
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/Handlers/ActivatedContentContext.cs
@@ -0,0 +1,6 @@
+namespace OrchardVNext.ContentManagement.Handlers {
+ public class ActivatedContentContext {
+ public string ContentType { get; set; }
+ public ContentItem ContentItem { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/Handlers/ActivatingContentContext.cs b/src/OrchardVNext/ContentManagement/Handlers/ActivatingContentContext.cs
new file mode 100644
index 00000000000..191d2a40066
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/Handlers/ActivatingContentContext.cs
@@ -0,0 +1,9 @@
+using OrchardVNext.ContentManagement.MetaData.Models;
+
+namespace OrchardVNext.ContentManagement.Handlers {
+ public class ActivatingContentContext {
+ public string ContentType { get; set; }
+ public ContentTypeDefinition Definition { get; set; }
+ public ContentItemBuilder Builder { get; set; }
+ }
+}
diff --git a/src/OrchardVNext/ContentManagement/Handlers/ActivatingFilter.cs b/src/OrchardVNext/ContentManagement/Handlers/ActivatingFilter.cs
new file mode 100644
index 00000000000..ac77c95e8f1
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/Handlers/ActivatingFilter.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Linq;
+
+namespace OrchardVNext.ContentManagement.Handlers {
+ ///
+ /// Filter reponsible for adding a part to a content item when content items are activated
+ ///
+ public class ActivatingFilter : IContentActivatingFilter where TPart : ContentPart, new() {
+ private readonly Func _predicate;
+
+ public ActivatingFilter(Func predicate) {
+ _predicate = predicate;
+ }
+
+ public ActivatingFilter(params string[] contentTypes)
+ : this(contentType => contentTypes.Contains(contentType)) {
+ }
+
+ public void Activating(ActivatingContentContext context) {
+ if (_predicate(context.ContentType))
+ context.Builder.Weld();
+ }
+ }
+}
diff --git a/src/OrchardVNext/ContentManagement/Handlers/ContentContextBase.cs b/src/OrchardVNext/ContentManagement/Handlers/ContentContextBase.cs
new file mode 100644
index 00000000000..53d79954dd1
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/Handlers/ContentContextBase.cs
@@ -0,0 +1,17 @@
+using OrchardVNext.ContentManagement.Records;
+
+namespace OrchardVNext.ContentManagement.Handlers {
+ public class ContentContextBase {
+ protected ContentContextBase (ContentItem contentItem) {
+ ContentItem = contentItem;
+ Id = contentItem.Id;
+ ContentType = contentItem.ContentType;
+ ContentItemRecord = contentItem.Record;
+ }
+
+ public int Id { get; private set; }
+ public string ContentType { get; private set; }
+ public ContentItem ContentItem { get; private set; }
+ public ContentItemRecord ContentItemRecord { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/src/OrchardVNext/ContentManagement/Handlers/ContentHandler.cs b/src/OrchardVNext/ContentManagement/Handlers/ContentHandler.cs
new file mode 100644
index 00000000000..3958c0ac9ba
--- /dev/null
+++ b/src/OrchardVNext/ContentManagement/Handlers/ContentHandler.cs
@@ -0,0 +1,433 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace OrchardVNext.ContentManagement.Handlers {
+ public abstract class ContentHandler : IContentHandler {
+ protected ContentHandler() {
+ Filters = new List();
+ }
+
+ public List Filters { get; set; }
+
+ protected void OnActivated(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnActivated = handler });
+ }
+
+ protected void OnInitializing(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnInitializing = handler });
+ }
+
+ protected void OnInitialized(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnInitialized = handler });
+ }
+
+ protected void OnCreating(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnCreating = handler });
+ }
+
+ protected void OnCreated(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnCreated = handler });
+ }
+
+ protected void OnLoading(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnLoading = handler });
+ }
+
+ protected void OnLoaded(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnLoaded = handler });
+ }
+
+ protected void OnUpdating(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnUpdating = handler });
+ }
+
+ protected void OnUpdated(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnUpdated = handler });
+ }
+
+ protected void OnVersioning(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnVersioning = handler });
+ }
+
+ protected void OnVersioned(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnVersioned = handler });
+ }
+
+ protected void OnPublishing(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnPublishing = handler });
+ }
+
+ protected void OnPublished(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnPublished = handler });
+ }
+
+ protected void OnUnpublishing(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnUnpublishing = handler });
+ }
+
+ protected void OnUnpublished(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnUnpublished = handler });
+ }
+
+ protected void OnRemoving(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnRemoving = handler });
+ }
+
+ protected void OnRemoved(Action handler) where TPart : class, IContent {
+ Filters.Add(new InlineStorageFilter { OnRemoved = handler });
+ }
+
+ //protected void OnDestroying(Action handler) where TPart : class, IContent {
+ // Filters.Add(new InlineStorageFilter { OnDestroying = handler });
+ //}
+
+ //protected void OnDestroyed(Action handler) where TPart : class, IContent {
+ // Filters.Add(new InlineStorageFilter { OnDestroyed = handler });
+ //}
+
+ //protected void OnIndexing(Action handler) where TPart : class, IContent {
+ // Filters.Add(new InlineStorageFilter { OnIndexing = handler });
+ //}
+
+ //protected void OnIndexed(Action handler) where TPart : class, IContent {
+ // Filters.Add(new InlineStorageFilter { OnIndexed = handler });
+ //}
+
+ //protected void OnGetContentItemMetadata(Action handler) where TPart : class, IContent {
+ // Filters.Add(new InlineTemplateFilter { OnGetItemMetadata = handler });
+ //}
+ //protected void OnGetDisplayShape(Action handler) where TPart : class, IContent {
+ // Filters.Add(new InlineTemplateFilter { OnGetDisplayShape = handler });
+ //}
+
+ //protected void OnGetEditorShape(Action handler) where TPart : class, IContent {
+ // Filters.Add(new InlineTemplateFilter { OnGetEditorShape = handler });
+ //}
+
+ //protected void OnUpdateEditorShape(Action handler) where TPart : class, IContent {
+ // Filters.Add(new InlineTemplateFilter { OnUpdateEditorShape = handler });
+ //}
+
+ class InlineStorageFilter : StorageFilterBase where TPart : class, IContent {
+ public Action OnActivated { get; set; }
+ public Action OnInitializing { get; set; }
+ public Action OnInitialized { get; set; }
+ public Action OnCreating { get; set; }
+ public Action OnCreated { get; set; }
+ public Action OnLoading { get; set; }
+ public Action OnLoaded { get; set; }
+ public Action OnUpdating { get; set; }
+ public Action OnUpdated { get; set; }
+ public Action OnVersioning { get; set; }
+ public Action OnVersioned { get; set; }
+ public Action OnPublishing { get; set; }
+ public Action OnPublished { get; set; }
+ public Action OnUnpublishing { get; set; }
+ public Action OnUnpublished { get; set; }
+ public Action OnRemoving { get; set; }
+ public Action OnRemoved { get; set; }
+ //public Action OnIndexing { get; set; }
+ //public Action OnIndexed { get; set; }
+ //public Action OnRestoring { get; set; }
+ //public Action OnRestored { get; set; }
+ //public Action OnDestroying { get; set; }
+ //public Action OnDestroyed { get; set; }
+ protected override void Activated(ActivatedContentContext context, TPart instance) {
+ if (OnActivated != null) OnActivated(context, instance);
+ }
+ protected override void Initializing(InitializingContentContext context, TPart instance) {
+ if (OnInitializing != null) OnInitializing(context, instance);
+ }
+ protected override void Initialized(InitializingContentContext context, TPart instance) {
+ if (OnInitialized != null) OnInitialized(context, instance);
+ }
+ protected override void Creating(CreateContentContext context, TPart instance) {
+ if (OnCreating != null) OnCreating(context, instance);
+ }
+ protected override void Created(CreateContentContext context, TPart instance) {
+ if (OnCreated != null) OnCreated(context, instance);
+ }
+ protected override void Loading(LoadContentContext context, TPart instance) {
+ if (OnLoading != null) OnLoading(context, instance);
+ }
+ protected override void Loaded(LoadContentContext context, TPart instance) {
+ if (OnLoaded != null) OnLoaded(context, instance);
+ }
+ protected override void Updating(UpdateContentContext context, TPart instance) {
+ if (OnUpdating != null) OnUpdating(context, instance);
+ }
+ protected override void Updated(UpdateContentContext context, TPart instance) {
+ if (OnUpdated != null) OnUpdated(context, instance);
+ }
+ protected override void Versioning(VersionContentContext context, TPart existing, TPart building) {
+ if (OnVersioning != null) OnVersioning(context, existing, building);
+ }
+ protected override void Versioned(VersionContentContext context, TPart existing, TPart building) {
+ if (OnVersioned != null) OnVersioned(context, existing, building);
+ }
+ protected override void Publishing(PublishContentContext context, TPart instance) {
+ if (OnPublishing != null) OnPublishing(context, instance);
+ }
+ protected override void Published(PublishContentContext context, TPart instance) {
+ if (OnPublished != null) OnPublished(context, instance);
+ }
+ protected override void Unpublishing(PublishContentContext context, TPart instance) {
+ if (OnUnpublishing != null) OnUnpublishing(context, instance);
+ }
+ protected override void Unpublished(PublishContentContext context, TPart instance) {
+ if (OnUnpublished != null) OnUnpublished(context, instance);
+ }
+ protected override void Removing(RemoveContentContext context, TPart instance) {
+ if (OnRemoving != null) OnRemoving(context, instance);
+ }
+ protected override void Removed(RemoveContentContext context, TPart instance) {
+ if (OnRemoved != null) OnRemoved(context, instance);
+ }
+ //protected override void Indexing(IndexContentContext context, TPart instance) {
+ // if ( OnIndexing != null )
+ // OnIndexing(context, instance);
+ //}
+ //protected override void Indexed(IndexContentContext context, TPart instance) {
+ // if ( OnIndexed != null )
+ // OnIndexed(context, instance);
+ //}
+ //protected override void Restoring(RestoreContentContext context, TPart instance) {
+ // if (OnRestoring != null)
+ // OnRestoring(context, instance);
+ //}
+ //protected override void Restored(RestoreContentContext context, TPart instance) {
+ // if (OnRestored != null)
+ // OnRestored(context, instance);
+ //}
+ //protected override void Destroying(DestroyContentContext context, TPart instance) {
+ // if (OnDestroying != null)
+ // OnDestroying(context, instance);
+ //}
+ //protected override void Destroyed(DestroyContentContext context, TPart instance) {
+ // if (OnDestroyed != null)
+ // OnDestroyed(context, instance);
+ //}
+ }
+
+ void IContentHandler.Activating(ActivatingContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Activating(context);
+ Activating(context);
+ }
+
+ void IContentHandler.Activated(ActivatedContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Activated(context);
+ Activated(context);
+ }
+
+ void IContentHandler.Initializing(InitializingContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Initializing(context);
+ Initializing(context);
+ }
+
+ void IContentHandler.Initialized(InitializingContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Initialized(context);
+ Initialized(context);
+ }
+
+ void IContentHandler.Creating(CreateContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Creating(context);
+ Creating(context);
+ }
+
+ void IContentHandler.Created(CreateContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Created(context);
+ Created(context);
+ }
+
+ void IContentHandler.Loading(LoadContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Loading(context);
+ Loading(context);
+ }
+
+ void IContentHandler.Loaded(LoadContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Loaded(context);
+ Loaded(context);
+ }
+
+ void IContentHandler.Updating(UpdateContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Updating(context);
+ Updating(context);
+ }
+
+ void IContentHandler.Updated(UpdateContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Updated(context);
+ Updated(context);
+ }
+
+ void IContentHandler.Versioning(VersionContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Versioning(context);
+ Versioning(context);
+ }
+
+ void IContentHandler.Versioned(VersionContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Versioned(context);
+ Versioned(context);
+ }
+
+ void IContentHandler.Publishing(PublishContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Publishing(context);
+ Publishing(context);
+ }
+
+ void IContentHandler.Published(PublishContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Published(context);
+ Published(context);
+ }
+
+ void IContentHandler.Unpublishing(PublishContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Unpublishing(context);
+ Unpublishing(context);
+ }
+
+ void IContentHandler.Unpublished(PublishContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Unpublished(context);
+ Unpublished(context);
+ }
+
+ void IContentHandler.Removing(RemoveContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Removing(context);
+ Removing(context);
+ }
+
+ void IContentHandler.Removed(RemoveContentContext context) {
+ foreach (var filter in Filters.OfType())
+ filter.Removed(context);
+ Removed(context);
+ }
+
+ //void IContentHandler.Indexing(IndexContentContext context) {
+ // foreach ( var filter in Filters.OfType() )
+ // filter.Indexing(context);
+ // Indexing(context);
+ //}
+
+ //void IContentHandler.Indexed(IndexContentContext context) {
+ // foreach ( var filter in Filters.OfType() )
+ // filter.Indexed(context);
+ // Indexed(context);
+ //}
+
+ //void IContentHandler.Importing(ImportContentContext context) {
+ // Importing(context);
+ //}
+
+ //void IContentHandler.Imported(ImportContentContext context) {
+ // Imported(context);
+ //}
+
+ //void IContentHandler.Exporting(ExportContentContext context) {
+ // Exporting(context);
+ //}
+
+ //void IContentHandler.Exported(ExportContentContext context) {
+ // Exported(context);
+ //}
+
+ //void IContentHandler.Restoring(RestoreContentContext context) {
+ // foreach (var filter in Filters.OfType())
+ // filter.Restoring(context);
+ // Restoring(context);
+ //}
+
+ //void IContentHandler.Restored(RestoreContentContext context) {
+ // foreach (var filter in Filters.OfType())
+ // filter.Restored(context);
+ // Restored(context);
+ //}
+
+ //void IContentHandler.Destroying(DestroyContentContext context) {
+ // foreach (var filter in Filters.OfType())
+ // filter.Destroying(context);
+ // Destroying(context);
+ //}
+
+ //void IContentHandler.Destroyed(DestroyContentContext context) {
+ // foreach (var filter in Filters.OfType())
+ // filter.Destroyed(context);
+ // Destroyed(context);
+ //}
+
+ //void IContentHandler.GetContentItemMetadata(GetContentItemMetadataContext context) {
+ // foreach (var filter in Filters.OfType())
+ // filter.GetContentItemMetadata(context);
+ // GetItemMetadata(context);
+ //}
+ //void IContentHandler.BuildDisplay(BuildDisplayContext context) {
+ // foreach (var filter in Filters.OfType