diff --git a/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs b/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs index f6f6271fd..3924b5eea 100644 --- a/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs +++ b/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs @@ -108,6 +108,10 @@ namespace Orchard.Tests.Environment.Extensions { throw new NotImplementedException(); } + public IEnumerable GetFileDependencies(DependencyDescriptor dependency, string virtualPath) { + throw new NotImplementedException(); + } + #endregion } diff --git a/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs b/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs index af342a9fb..f967ea44d 100644 --- a/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs +++ b/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs @@ -108,6 +108,10 @@ namespace Orchard.Tests.Environment.Extensions { throw new NotImplementedException(); } + public IEnumerable GetFileDependencies(DependencyDescriptor dependency, string virtualPath) { + throw new NotImplementedException(); + } + #endregion } diff --git a/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs index 29f5bff13..a2cd2b4e9 100644 --- a/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs +++ b/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs @@ -47,6 +47,16 @@ namespace Orchard.Environment.Extensions.Loaders { return GetDependencies(dependency.VirtualPath); } + public override IEnumerable GetFileDependencies(DependencyDescriptor dependency, string virtualPath){ + var path1 = virtualPath.StartsWith("~") ? virtualPath : "~" + virtualPath; + var path2 = dependency.VirtualPath.StartsWith("~") ? dependency.VirtualPath : "~" + dependency.VirtualPath; + + if (StringComparer.OrdinalIgnoreCase.Equals(path1, path2)) { + return GetSourceFiles(virtualPath); + } + return base.GetFileDependencies(dependency, virtualPath); + } + public override void Monitor(ExtensionDescriptor descriptor, Action monitor) { // Monitor .csproj and all .cs files string projectPath = GetProjectPath(descriptor); diff --git a/src/Orchard/Environment/Extensions/Loaders/ExtensionLoaderBase.cs b/src/Orchard/Environment/Extensions/Loaders/ExtensionLoaderBase.cs index 70a5f41e2..f9fe2b8bc 100644 --- a/src/Orchard/Environment/Extensions/Loaders/ExtensionLoaderBase.cs +++ b/src/Orchard/Environment/Extensions/Loaders/ExtensionLoaderBase.cs @@ -57,5 +57,9 @@ namespace Orchard.Environment.Extensions.Loaders { public virtual IEnumerable GetWebFormVirtualDependencies(DependencyDescriptor dependency) { return Enumerable.Empty(); } + + public virtual IEnumerable GetFileDependencies(DependencyDescriptor dependency, string virtualPath) { + return Enumerable.Empty(); + } } } \ No newline at end of file diff --git a/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs index 2b07e6ff5..41ff0146c 100644 --- a/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs +++ b/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs @@ -42,5 +42,6 @@ namespace Orchard.Environment.Extensions.Loaders { string GetWebFormAssemblyDirective(DependencyDescriptor dependency); IEnumerable GetWebFormVirtualDependencies(DependencyDescriptor dependency); + IEnumerable GetFileDependencies(DependencyDescriptor dependency, string virtualPath); } } \ No newline at end of file diff --git a/src/Orchard/Environment/OrchardStarter.cs b/src/Orchard/Environment/OrchardStarter.cs index 761487d50..4854baa83 100644 --- a/src/Orchard/Environment/OrchardStarter.cs +++ b/src/Orchard/Environment/OrchardStarter.cs @@ -38,6 +38,7 @@ namespace Orchard.Environment { builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); diff --git a/src/Orchard/FileSystems/Dependencies/DynamicModuleVirtualPathProvider.cs b/src/Orchard/FileSystems/Dependencies/DynamicModuleVirtualPathProvider.cs new file mode 100644 index 000000000..a3e2b64db --- /dev/null +++ b/src/Orchard/FileSystems/Dependencies/DynamicModuleVirtualPathProvider.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Web.Hosting; +using Orchard.Environment.Extensions.Loaders; +using Orchard.FileSystems.VirtualPath; +using Orchard.Logging; + +namespace Orchard.FileSystems.Dependencies { + public class DynamicModuleVirtualPathProvider : VirtualPathProvider, ICustomVirtualPathProvider { + private readonly IDependenciesFolder _dependenciesFolder; + private readonly IEnumerable _loaders; + private readonly string[] _modulesPrefixes = { "~/Modules/", "/Modules/" }; + + public DynamicModuleVirtualPathProvider(IDependenciesFolder dependenciesFolder, IEnumerable loaders) { + _dependenciesFolder = dependenciesFolder; + _loaders = loaders; + Logger = NullLogger.Instance; + } + + public ILogger Logger { get; set; } + + public override bool DirectoryExists(string virtualDir) { + return Previous.DirectoryExists(virtualDir); + } + + public override bool FileExists(string virtualPath) { + return Previous.FileExists(virtualPath); + } + + public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies) { + var result = GetFileHashWorker(virtualPath, virtualPathDependencies); + //Logger.Information("GetFileHash(\"{0}\"): {1}", virtualPath, result); + return result; + } + + private string GetFileHashWorker(string virtualPath, IEnumerable virtualPathDependencies) { + var desc = GetDependencyDescriptor(virtualPath); + if (desc != null) { + + var loader = _loaders.Where(l => l.Name == desc.LoaderName).FirstOrDefault(); + if (loader != null) { + + var otherDependencies = loader.GetFileDependencies(desc, virtualPath); + if (otherDependencies.Any()) { + + var allDependencies = virtualPathDependencies.OfType().Concat(otherDependencies); + + if (Logger.IsEnabled(LogLevel.Debug)) { + Logger.Debug("GetFileHash(\"{0}\") - virtual path dependencies:", virtualPath); + foreach (var dependency in allDependencies) { + Logger.Debug(" Dependency: \"{0}\"", dependency); + } + } + + return base.GetFileHash(virtualPath, allDependencies); + } + } + } + return base.GetFileHash(virtualPath, virtualPathDependencies); + } + + public override VirtualFile GetFile(string virtualPath) { + return Previous.GetFile(virtualPath); + } + + private DependencyDescriptor GetDependencyDescriptor(string virtualPath) { + var prefix = PrefixMatch(virtualPath, _modulesPrefixes); + if (prefix == null) + return null; + + var moduleName = ModuleMatch(virtualPath, prefix); + if (moduleName == null) + return null; + + return _dependenciesFolder.GetDescriptor(moduleName); + } + + private string ModuleMatch(string virtualPath, string prefix) { + var index = virtualPath.IndexOf('/', prefix.Length, virtualPath.Length - prefix.Length); + if (index < 0) + return null; + + var moduleName = virtualPath.Substring(prefix.Length, index - prefix.Length); + return (string.IsNullOrEmpty(moduleName) ? null : moduleName); + } + + private string PrefixMatch(string virtualPath, params string[] prefixes) { + return prefixes + .FirstOrDefault(p => virtualPath.StartsWith(p, StringComparison.OrdinalIgnoreCase)); + } + + VirtualPathProvider ICustomVirtualPathProvider.Instance { + get { return this; } + } + } +} \ No newline at end of file diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index e38fd208a..8af3a2e34 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -360,6 +360,7 @@ Code +