diff --git a/src/Orchard.Specs/Orchard.Specs.csproj b/src/Orchard.Specs/Orchard.Specs.csproj
index 0d6693518..cdc4d4544 100644
--- a/src/Orchard.Specs/Orchard.Specs.csproj
+++ b/src/Orchard.Specs/Orchard.Specs.csproj
@@ -228,10 +228,6 @@
{9916839C-39FC-4CEB-A5AF-89CA7E87119F}
Orchard.Core
-
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}
- Orchard.DevTools
-
{D10AD48F-407D-4DB5-A328-173EC7CB010F}
Orchard.Roles
diff --git a/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj b/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj
index 82b375e1b..010a7cda9 100644
--- a/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj
+++ b/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj
@@ -106,6 +106,7 @@
+
@@ -127,6 +128,10 @@
{9916839C-39FC-4CEB-A5AF-89CA7E87119F}
Orchard.Core
+
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}
+ Orchard.CodeGeneration
+
{D10AD48F-407D-4DB5-A328-173EC7CB010F}
Orchard.Roles
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/Controller.txt b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/Controller.txt
new file mode 100644
index 000000000..2e1d7a9e4
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/Controller.txt
@@ -0,0 +1,16 @@
+using System.Web.Mvc;
+using Orchard.Localization;
+using Orchard;
+
+namespace $$ModuleName$$.Controllers {
+ public class $$ControllerName$$ : Controller {
+ public IOrchardServices Services { get; set; }
+
+ public $$ControllerName$$(IOrchardServices services) {
+ Services = services;
+ T = NullLocalizer.Instance;
+ }
+
+ public Localizer T { get; set; }
+ }
+}
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/DataMigration.txt b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/DataMigration.txt
new file mode 100644
index 000000000..e80ad786c
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/DataMigration.txt
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using Orchard.ContentManagement.Drivers;
+using Orchard.ContentManagement.MetaData;
+using Orchard.ContentManagement.MetaData.Builders;
+using Orchard.Core.Contents.Extensions;
+using Orchard.Data.Migration;
+
+namespace $$FeatureName$$.DataMigrations {
+ public class $$ClassName$$DataMigration : DataMigrationImpl {
+
+ public int Create() {
+$$Commands$$
+
+ return 1;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleAssemblyInfo.txt b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleAssemblyInfo.txt
new file mode 100644
index 000000000..22a4eceba
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleAssemblyInfo.txt
@@ -0,0 +1,34 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("$$ModuleName$$")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyProduct("Orchard")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("$$ModuleTypeLibGuid$$")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleCsProj.txt b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleCsProj.txt
new file mode 100644
index 000000000..fd2336c8c
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleCsProj.txt
@@ -0,0 +1,130 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {$$ModuleProjectGuid$$}
+ {F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
+ Library
+ Properties
+ $$ModuleName$$
+ $$ModuleName$$
+ v4.0
+ false
+
+
+ 3.5
+
+
+
+
+ true
+ full
+ false
+ bin\
+ DEBUG;TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ bin\
+ TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+
+
+ 3.5
+
+
+
+
+
+
+
+ False
+ ..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}
+ Orchard.Framework
+
+
+ {9916839C-39FC-4CEB-A5AF-89CA7E87119F}
+ Orchard.Core
+
+
+
+
+
+
+
+ $(ProjectDir)\..\Manifests
+
+
+
+
+
+
+
+
+
+
+
+ False
+ True
+ 45979
+ /
+
+
+ False
+ True
+ http://orchard.codeplex.com
+ False
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleManifest.txt b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleManifest.txt
new file mode 100644
index 000000000..193964f30
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleManifest.txt
@@ -0,0 +1,10 @@
+name: $$ModuleName$$
+antiforgery: enabled
+author: The Orchard Team
+website: http://orchardproject.net
+version: 0.5.0
+orchardversion: 0.5.0
+description: Description for the module
+features:
+ $$ModuleName$$:
+ Description: Description for feature $$ModuleName$$.
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleWebConfig.txt b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleWebConfig.txt
new file mode 100644
index 000000000..87bf40af5
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ModuleWebConfig.txt
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ViewsWebConfig.txt b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ViewsWebConfig.txt
new file mode 100644
index 000000000..7022197d4
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ViewsWebConfig.txt
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/Commands/CodeGenerationCommands.cs b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Commands/CodeGenerationCommands.cs
new file mode 100644
index 000000000..caed8bf12
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Commands/CodeGenerationCommands.cs
@@ -0,0 +1,228 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Web.Hosting;
+using Orchard.Commands;
+using Orchard.Data.Migration.Generator;
+using Orchard.CodeGeneration.Services;
+using Orchard.Data.Migration.Schema;
+using Orchard.Environment.Extensions;
+using Orchard.Environment.Extensions.Models;
+
+namespace Orchard.CodeGeneration.Commands {
+
+ [OrchardFeature("Generate")]
+ public class CodeGenerationCommands : DefaultOrchardCommandHandler {
+ private readonly IExtensionManager _extensionManager;
+ private readonly ISchemaCommandGenerator _schemaCommandGenerator;
+
+ private const string ModuleName = "CodeGeneration";
+
+ public CodeGenerationCommands(
+ IExtensionManager extensionManager,
+ ISchemaCommandGenerator schemaCommandGenerator) {
+ _extensionManager = extensionManager;
+ _schemaCommandGenerator = schemaCommandGenerator;
+ }
+
+ [OrchardSwitch]
+ public bool IncludeInSolution { get; set; }
+
+ [CommandHelp("generate create datamigration \r\n\t" + "Create a new Data Migration class")]
+ [CommandName("generate create datamigration")]
+ public void CreateDataMigration(string featureName) {
+ Context.Output.WriteLine(T("Creating Data Migration for {0}", featureName));
+
+ ExtensionDescriptor extensionDescriptor = _extensionManager.AvailableExtensions().FirstOrDefault(extension => extension.ExtensionType == "Module" &&
+ extension.Features.Any(feature => String.Equals(feature.Name, featureName, StringComparison.OrdinalIgnoreCase)));
+
+ if (extensionDescriptor == null) {
+ Context.Output.WriteLine(T("Creating data migration failed: target Feature {0} could not be found.", featureName));
+ return;
+ }
+
+ string dataMigrationsPath = HostingEnvironment.MapPath("~/Modules/" + extensionDescriptor.Name + "/DataMigrations/");
+ string dataMigrationPath = dataMigrationsPath + extensionDescriptor.DisplayName + "DataMigration.cs";
+ string templatesPath = HostingEnvironment.MapPath("~/Modules/Orchard." + ModuleName + "/CodeGenerationTemplates/");
+ string moduleCsProjPath = HostingEnvironment.MapPath(string.Format("~/Modules/{0}/{0}.csproj", extensionDescriptor.Name));
+
+ if (!Directory.Exists(dataMigrationsPath)) {
+ Directory.CreateDirectory(dataMigrationsPath);
+ }
+
+ if (File.Exists(dataMigrationPath)) {
+ Context.Output.WriteLine(T("Data migration already exists in target Module {0}.", extensionDescriptor.Name));
+ return;
+ }
+
+ List commands = _schemaCommandGenerator.GetCreateFeatureCommands(featureName, false).ToList();
+
+ var stringWriter = new StringWriter();
+ var interpreter = new CodeGenerationCommandInterpreter(stringWriter);
+
+ foreach (var command in commands) {
+ interpreter.Visit(command);
+ stringWriter.WriteLine();
+ }
+
+ string dataMigrationText = File.ReadAllText(templatesPath + "DataMigration.txt");
+ dataMigrationText = dataMigrationText.Replace("$$FeatureName$$", featureName);
+ dataMigrationText = dataMigrationText.Replace("$$ClassName$$", extensionDescriptor.DisplayName);
+ dataMigrationText = dataMigrationText.Replace("$$Commands$$", stringWriter.ToString());
+ File.WriteAllText(dataMigrationPath, dataMigrationText);
+
+ string projectFileText = File.ReadAllText(moduleCsProjPath);
+
+ // The string searches in solution/project files can be made aware of comment lines.
+ if ( projectFileText.Contains("\r\n ", "DataMigrations\\" + extensionDescriptor.DisplayName + "DataMigration.cs");
+ projectFileText = projectFileText.Insert(projectFileText.LastIndexOf("\r\n \r\n \r\n ", "DataMigrations\\" + extensionDescriptor.DisplayName + "DataMigration.cs");
+ projectFileText = projectFileText.Insert(projectFileText.LastIndexOf(""), itemGroupReference);
+ }
+
+ File.WriteAllText(moduleCsProjPath, projectFileText);
+ TouchSolution();
+ Context.Output.WriteLine(T("Data migration created successfully in Module {0}", extensionDescriptor.Name));
+ }
+
+ [CommandHelp("generate create module [/IncludeInSolution:true|false]\r\n\t" + "Create a new Orchard module")]
+ [CommandName("generate create module")]
+ [OrchardSwitches("IncludeInSolution")]
+ public void CreateModule(string moduleName) {
+ Context.Output.WriteLine(T("Creating Module {0}", moduleName));
+
+ if ( _extensionManager.AvailableExtensions().Any(extension => extension.ExtensionType == "Module" && String.Equals(moduleName, extension.DisplayName, StringComparison.OrdinalIgnoreCase)) ) {
+ Context.Output.WriteLine(T("Creating Module {0} failed: a module of the same name already exists", moduleName));
+ return;
+ }
+
+ IntegrateModule(moduleName);
+ Context.Output.WriteLine(T("Module {0} created successfully", moduleName));
+ }
+
+
+ [CommandHelp("generate create controller \r\n\t" + "Create a new Orchard controller in a module")]
+ [CommandName("generate create controller")]
+ public void CreateController(string moduleName, string controllerName) {
+ Context.Output.WriteLine(T("Creating Controller {0} in Module {1}", controllerName, moduleName));
+
+ ExtensionDescriptor extensionDescriptor = _extensionManager.AvailableExtensions().FirstOrDefault(extension => extension.ExtensionType == "Module" &&
+ string.Equals(moduleName, extension.DisplayName, StringComparison.OrdinalIgnoreCase));
+
+ if (extensionDescriptor == null) {
+ Context.Output.WriteLine(T("Creating Controller {0} failed: target Module {1} could not be found.", controllerName, moduleName));
+ return;
+ }
+
+ string moduleControllersPath = HostingEnvironment.MapPath("~/Modules/" + extensionDescriptor.Name + "/Controllers/");
+ string controllerPath = moduleControllersPath + controllerName + ".cs";
+ string moduleCsProjPath = HostingEnvironment.MapPath(string.Format("~/Modules/{0}/{0}.csproj", extensionDescriptor.Name));
+ string templatesPath = HostingEnvironment.MapPath("~/Modules/Orchard." + ModuleName + "/CodeGenerationTemplates/");
+
+ if (!Directory.Exists(moduleControllersPath)) {
+ Directory.CreateDirectory(moduleControllersPath);
+ }
+ if (File.Exists(controllerPath)) {
+ Context.Output.WriteLine(T("Controller {0} already exists in target Module {1}.", controllerName, moduleName));
+ return;
+ }
+
+ string controllerText = File.ReadAllText(templatesPath + "Controller.txt");
+ controllerText = controllerText.Replace("$$ModuleName$$", moduleName);
+ controllerText = controllerText.Replace("$$ControllerName$$", controllerName);
+ File.WriteAllText(controllerPath, controllerText);
+ string projectFileText = File.ReadAllText(moduleCsProjPath);
+
+ // The string searches in solution/project files can be made aware of comment lines.
+ if (projectFileText.Contains("\r\n ", "Controllers\\" + controllerName + ".cs");
+ projectFileText = projectFileText.Insert(projectFileText.LastIndexOf("\r\n \r\n \r\n ", "Controllers\\" + controllerName + ".cs");
+ projectFileText = projectFileText.Insert(projectFileText.LastIndexOf(""), itemGroupReference);
+ }
+
+ File.WriteAllText(moduleCsProjPath, projectFileText);
+ Context.Output.WriteLine(T("Controller {0} created successfully in Module {1}", controllerName, moduleName));
+ TouchSolution();
+ }
+
+ private void IntegrateModule(string moduleName) {
+ string rootWebProjectPath = HostingEnvironment.MapPath("~/Orchard.Web.csproj");
+ string projectGuid = Guid.NewGuid().ToString().ToUpper();
+
+ CreateFilesFromTemplates(moduleName, projectGuid);
+ // The string searches in solution/project files can be made aware of comment lines.
+ if (IncludeInSolution) {
+ // Add project to Orchard.sln
+ string solutionPath = Directory.GetParent(rootWebProjectPath).Parent.FullName + "\\Orchard.sln";
+ if (File.Exists(solutionPath)) {
+ string projectReference = string.Format(
+ "EndProject\r\nProject(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"{0}\", \"Orchard.Web\\Modules\\{0}\\{0}.csproj\", \"{{{1}}}\"\r\n",
+ moduleName, projectGuid);
+ string projectConfiguationPlatforms = string.Format(
+ "GlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{{{0}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{{{0}}}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{{{0}}}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{{{0}}}.Release|Any CPU.Build.0 = Release|Any CPU\r\n",
+ projectGuid);
+ string solutionText = File.ReadAllText(solutionPath);
+ solutionText = solutionText.Insert(solutionText.LastIndexOf("EndProject\r\n"), projectReference);
+ solutionText = solutionText.Replace("GlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n", projectConfiguationPlatforms);
+ solutionText = solutionText.Insert(solutionText.LastIndexOf("EndGlobalSection"), "\t{" + projectGuid + "} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}\r\n\t");
+
+ File.WriteAllText(solutionPath, solutionText);
+ TouchSolution();
+ }
+ else {
+ Context.Output.WriteLine(T("Warning: Solution file could not be found at {0}", solutionPath));
+ }
+ }
+ }
+
+ private static void CreateFilesFromTemplates(string moduleName, string projectGuid) {
+ string modulePath = HostingEnvironment.MapPath("~/Modules/" + moduleName + "/");
+ string propertiesPath = modulePath + "Properties";
+ string templatesPath = HostingEnvironment.MapPath("~/Modules/Orchard." + ModuleName + "/CodeGenerationTemplates/");
+
+ Directory.CreateDirectory(modulePath);
+ Directory.CreateDirectory(propertiesPath);
+ Directory.CreateDirectory(modulePath + "Controllers");
+ Directory.CreateDirectory(modulePath + "Views");
+ File.WriteAllText(modulePath + "\\Views\\Web.config", File.ReadAllText(templatesPath + "ViewsWebConfig.txt"));
+ Directory.CreateDirectory(modulePath + "Models");
+ Directory.CreateDirectory(modulePath + "Scripts");
+
+ string templateText = File.ReadAllText(templatesPath + "ModuleAssemblyInfo.txt");
+ templateText = templateText.Replace("$$ModuleName$$", moduleName);
+ templateText = templateText.Replace("$$ModuleTypeLibGuid$$", Guid.NewGuid().ToString());
+ File.WriteAllText(propertiesPath + "\\AssemblyInfo.cs", templateText);
+ File.WriteAllText(modulePath + "\\Web.config", File.ReadAllText(templatesPath + "ModuleWebConfig.txt"));
+ templateText = File.ReadAllText(templatesPath + "ModuleManifest.txt");
+ templateText = templateText.Replace("$$ModuleName$$", moduleName);
+ File.WriteAllText(modulePath + "\\Module.txt", templateText);
+ templateText = File.ReadAllText(templatesPath + "\\ModuleCsProj.txt");
+ templateText = templateText.Replace("$$ModuleName$$", moduleName);
+ templateText = templateText.Replace("$$ModuleProjectGuid$$", projectGuid);
+ File.WriteAllText(modulePath + "\\" + moduleName + ".csproj", templateText);
+ }
+
+ private void TouchSolution() {
+ string rootWebProjectPath = HostingEnvironment.MapPath("~/Orchard.Web.csproj");
+ string solutionPath = Directory.GetParent(rootWebProjectPath).Parent.FullName + "\\Orchard.sln";
+ if (!File.Exists(solutionPath)) {
+ Context.Output.WriteLine(T("Warning: Solution file could not be found at {0}", solutionPath));
+ return;
+ }
+
+ try {
+ File.SetLastWriteTime(solutionPath, DateTime.Now);
+ }
+ catch {
+ Context.Output.WriteLine(T("An unexpected error occured while trying to refresh the Visual Studio solution. Please reload it."));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/Module.txt b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Module.txt
new file mode 100644
index 000000000..bddae50b7
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Module.txt
@@ -0,0 +1,11 @@
+Name: Code generation module
+antiforgery: enabled
+author: The Orchard Team
+website: http://orchardproject.net
+version: 0.1.0
+orchardversion: 0.6.0
+description:
+features:
+ Generate:
+ Description: Tools to create Orchard components.
+ Category: Developer
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/Orchard.CodeGeneration.csproj b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Orchard.CodeGeneration.csproj
new file mode 100644
index 000000000..faef74dd8
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Orchard.CodeGeneration.csproj
@@ -0,0 +1,128 @@
+
+
+
+ Debug
+ AnyCPU
+
+
+ 2.0
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}
+ {F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
+ Library
+ Properties
+ Orchard.CodeGeneration
+ Orchard.CodeGeneration
+ v4.0
+ false
+
+
+ true
+ full
+ false
+ bin\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\..\..\..\lib\nhprof\HibernatingRhinos.Profiler.Appender.dll
+
+
+
+
+
+
+
+
+
+ 3.5
+
+
+ 3.5
+
+
+ 3.5
+
+
+ False
+ ..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll
+
+
+ 3.5
+
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}
+ Orchard.Framework
+
+
+ {9916839C-39FC-4CEB-A5AF-89CA7E87119F}
+ Orchard.Core
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ True
+ 53274
+ /
+
+
+ False
+ False
+
+
+ False
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..979584f46
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Orchard.CodeGeneration")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyProduct("Orchard")]
+[assembly: AssemblyCopyright("Copyright © CodePlex Foundation 2009")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a5ae5869-1454-4fe8-a998-a3f2e79c91a3")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0")]
+[assembly: AssemblyFileVersion("0.5.0")]
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/Services/CodeGenerationCommandInterpreter.cs b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Services/CodeGenerationCommandInterpreter.cs
new file mode 100644
index 000000000..a4907ed47
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Services/CodeGenerationCommandInterpreter.cs
@@ -0,0 +1,111 @@
+using System.Collections.Generic;
+using System.Data;
+using System.IO;
+using System.Linq;
+using Orchard.Data.Migration.Interpreters;
+using Orchard.Data.Migration.Schema;
+
+namespace Orchard.CodeGeneration.Services {
+ public class CodeGenerationCommandInterpreter : AbstractDataMigrationInterpreter {
+ private readonly TextWriter _output;
+
+ public CodeGenerationCommandInterpreter(TextWriter output) {
+ _output = output;
+ }
+
+ public override void Visit(CreateTableCommand command) {
+ _output.WriteLine("\t\t\t// Creating table {0}", command.Name);
+ _output.WriteLine("\t\t\tSchemaBuilder.CreateTable(\"{0}\", table => table", command.Name);
+
+ var matchContentPartRecord = command.TableCommands.OfType().Any(
+ c =>
+ c.IsPrimaryKey
+ && c.ColumnName == "Id"
+ && !c.IsIdentity
+ && c.DbType == DbType.Int32);
+
+ var matchContentPartVersionRecord = matchContentPartRecord && command.TableCommands.OfType().Any(
+ c =>
+ c.ColumnName == "ContentItemRecord_id"
+ && c.DbType == DbType.Int32);
+
+ if ( matchContentPartVersionRecord ) {
+ _output.WriteLine("\t\t\t\t.ContentPartVersionRecord()");
+ }
+ else if ( matchContentPartRecord ) {
+ _output.WriteLine("\t\t\t\t.ContentPartRecord()");
+ }
+
+ foreach ( var createColumn in command.TableCommands.OfType() ) {
+ if(createColumn.ColumnName == "Id" && matchContentPartRecord) {
+ continue;
+ }
+
+ if(createColumn.ColumnName == "ContentItemRecord_id" && matchContentPartVersionRecord) {
+ continue;
+ }
+
+ var type = createColumn.DbType.ToString();
+ var field = createColumn.ColumnName;
+ var options = new List();
+
+ if ( createColumn.IsPrimaryKey ) {
+ options.Add("PrimaryKey()");
+ }
+
+ if ( createColumn.IsIdentity ) {
+ options.Add("Identity()");
+ }
+
+ if ( createColumn.IsUnique ) {
+ options.Add("Unique()");
+ }
+
+ if ( createColumn.IsNotNull ) {
+ options.Add("NotNull()");
+ }
+
+ if ( createColumn.Length.HasValue ) {
+ if ( createColumn.Length == 10000 ) {
+ options.Add("Unlimited()");
+ }
+ else {
+ options.Add(string.Format("WithLength({0})", createColumn.Length));
+ }
+ }
+
+ if ( createColumn.Precision > 0 ) {
+ options.Add(string.Format("WithPrecision({0})", createColumn.Precision));
+ options.Add(string.Format("WithScale({0})", createColumn.Scale));
+ }
+
+ _output.WriteLine("\t\t\t\t.Column(\"{0}\", DbType.{1}{2})", field, type, options.Any() ? ", column => column." + string.Join(".", options) : string.Empty);
+ }
+
+ _output.WriteLine("\t\t\t);");
+
+ }
+
+ public override void Visit(AlterTableCommand command) {
+ _output.WriteLine("// Altering table {0}", command.Name);
+ }
+
+ public override void Visit(DropTableCommand command) {
+ _output.WriteLine("// Dropping table {0}", command.Name);
+ _output.WriteLine("\t\t\tSchemaBuilder.DropTable(\"{0}\", command.Name);");
+ }
+
+ public override void Visit(SqlStatementCommand command) {
+ _output.WriteLine("// Executing sql statement\n\n {0}", command.Sql);
+ }
+
+ public override void Visit(CreateForeignKeyCommand command) {
+ _output.WriteLine("// Creating foreign key {0}", command.Name);
+ }
+
+ public override void Visit(DropForeignKeyCommand command) {
+ _output.WriteLine("// Dropping foreign key {0}", command.Name);
+ }
+
+ }
+}
diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/Web.config b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Web.config
new file mode 100644
index 000000000..97c1c726a
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/Web.config
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Orchard.sln b/src/Orchard.sln
index b85065f36..d37cab7bb 100644
--- a/src/Orchard.sln
+++ b/src/Orchard.sln
@@ -27,8 +27,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Core", "Orchard.Web
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Core.Tests", "Orchard.Core.Tests\Orchard.Core.Tests.csproj", "{2FC1D9C8-446D-4414-B252-5E9FBE61EB63}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.DevTools", "Orchard.Web\Modules\Orchard.DevTools\Orchard.DevTools.csproj", "{67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Setup", "Orchard.Web\Modules\Orchard.Setup\Orchard.Setup.csproj", "{8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSBuild.Orchard.Tasks", "Tools\MSBuild.Orchard.Tasks\MSBuild.Orchard.Tasks.csproj", "{5E5E7A21-C7B2-44D8-8593-2F9541AE041D}"
@@ -84,6 +82,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Futures.Widgets", "Orchard.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene", "Orchard.Web\Modules\Lucene\Lucene.csproj", "{D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Experimental", "Orchard.Web\Modules\Orchard.Experimental\Orchard.Experimental.csproj", "{AB3C207C-0126-4143-8D62-1119DF80D366}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.CodeGeneration", "Orchard.Web\Modules\Orchard.CodeGeneration\Orchard.CodeGeneration.csproj", "{C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
CodeCoverage|Any CPU = CodeCoverage|Any CPU
@@ -183,16 +185,6 @@ Global
{2FC1D9C8-446D-4414-B252-5E9FBE61EB63}.FxCop|Any CPU.Build.0 = Release|Any CPU
{2FC1D9C8-446D-4414-B252-5E9FBE61EB63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FC1D9C8-446D-4414-B252-5E9FBE61EB63}.Release|Any CPU.Build.0 = Release|Any CPU
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}.Coverage|Any CPU.ActiveCfg = Release|Any CPU
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}.Coverage|Any CPU.Build.0 = Release|Any CPU
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}.FxCop|Any CPU.Build.0 = Release|Any CPU
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890}.Release|Any CPU.Build.0 = Release|Any CPU
{8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
{8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
{8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4}.Coverage|Any CPU.ActiveCfg = Release|Any CPU
@@ -443,6 +435,26 @@ Global
{D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D}.FxCop|Any CPU.Build.0 = Release|Any CPU
{D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB3C207C-0126-4143-8D62-1119DF80D366}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
+ {AB3C207C-0126-4143-8D62-1119DF80D366}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
+ {AB3C207C-0126-4143-8D62-1119DF80D366}.Coverage|Any CPU.ActiveCfg = Release|Any CPU
+ {AB3C207C-0126-4143-8D62-1119DF80D366}.Coverage|Any CPU.Build.0 = Release|Any CPU
+ {AB3C207C-0126-4143-8D62-1119DF80D366}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB3C207C-0126-4143-8D62-1119DF80D366}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB3C207C-0126-4143-8D62-1119DF80D366}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+ {AB3C207C-0126-4143-8D62-1119DF80D366}.FxCop|Any CPU.Build.0 = Release|Any CPU
+ {AB3C207C-0126-4143-8D62-1119DF80D366}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AB3C207C-0126-4143-8D62-1119DF80D366}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}.Coverage|Any CPU.ActiveCfg = Release|Any CPU
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}.Coverage|Any CPU.Build.0 = Release|Any CPU
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}.FxCop|Any CPU.Build.0 = Release|Any CPU
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -450,7 +462,6 @@ Global
GlobalSection(NestedProjects) = preSolution
{79AED36E-ABD0-4747-93D3-8722B042454B} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{D10AD48F-407D-4DB5-A328-173EC7CB010F} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
- {67C1D3AF-A0EC-46B2-BAE1-DF1DA8E0B890} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{CDE24A24-01D3-403C-84B9-37722E18DFB7} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{17F86780-9A1F-4AA1-86F1-875EEC2730C7} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
@@ -468,6 +479,8 @@ Global
{EA2B9121-EF54-40A6-A53E-6593C86EE696} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{4BE4EB01-AC56-4048-924E-2CA77F509ABA} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{D5D447D7-EF8E-43A6-B9A4-3B025DD9F45D} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
+ {AB3C207C-0126-4143-8D62-1119DF80D366} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
+ {C0C45321-B51D-4D8D-9B7B-AA4C2E0B2962} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{ABC826D4-2FA1-4F2F-87DE-E6095F653810} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
{F112851D-B023-4746-B6B1-8D2E5AD8F7AA} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
{6CB3EB30-F725-45C0-9742-42599BA8E8D2} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}