From 1290ea7d6e3869913d4ee3ecbc0d20e3abab620a Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Tue, 22 Jun 2010 10:21:24 -0700 Subject: [PATCH] Refactor OrchardException classes All constructors now take a"LocalizedString" as the error message. --HG-- branch : dev --- .../Models/LuceneDocumentIndex.cs | 8 +++- .../Services/LuceneIndexProvider.cs | 11 +++-- .../RolesBasedAuthorizationService.cs | 10 ++++- src/Orchard/Commands/DefaultCommandManager.cs | 12 +++++- src/Orchard/Data/SessionFactoryHolder.cs | 8 +++- .../Compilers/DefaultExtensionCompiler.cs | 30 ++++++++++---- .../Extensions/ExtensionLoaderCoordinator.cs | 4 +- .../Loaders/DynamicExtensionLoader.cs | 2 + .../OrchardHostContainerRegistry.cs | 40 ++++++++++++------- .../FileSystems/AppData/AppDataFolder.cs | 2 +- .../Dependencies/DefaultDependenciesFolder.cs | 2 +- src/Orchard/Orchard.Framework.csproj | 1 + src/Orchard/OrchardException.cs | 25 +++++++++--- src/Orchard/OrchardSystemException.cs | 25 ++++++++++++ .../Security/OrchardSecurityException.cs | 12 +++--- 15 files changed, 145 insertions(+), 47 deletions(-) create mode 100644 src/Orchard/OrchardSystemException.cs diff --git a/src/Orchard.Web/Modules/Orchard.Indexing/Models/LuceneDocumentIndex.cs b/src/Orchard.Web/Modules/Orchard.Indexing/Models/LuceneDocumentIndex.cs index a4b9a0b1d..32cab14c3 100644 --- a/src/Orchard.Web/Modules/Orchard.Indexing/Models/LuceneDocumentIndex.cs +++ b/src/Orchard.Web/Modules/Orchard.Indexing/Models/LuceneDocumentIndex.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Lucene.Net.Documents; +using Orchard.Localization; using Orchard.Utility.Extensions; namespace Orchard.Indexing.Models { @@ -20,14 +21,17 @@ namespace Orchard.Indexing.Models { public int ContentItemId { get; private set; } - public LuceneDocumentIndex(int documentId) { + public LuceneDocumentIndex(int documentId, Localizer t) { Fields = new List(); SetContentItemId(documentId); IsDirty = false; _typeCode = TypeCode.Empty; + T = t; } + public Localizer T { get; set; } + public bool IsDirty { get; private set; } public IDocumentIndex Add(string name, string value) { @@ -113,7 +117,7 @@ namespace Orchard.Indexing.Models { case TypeCode.Empty: break; default: - throw new OrchardException("Unexpected index type"); + throw new OrchardException(T("Unexpected index type")); } _removeTags = false; diff --git a/src/Orchard.Web/Modules/Orchard.Indexing/Services/LuceneIndexProvider.cs b/src/Orchard.Web/Modules/Orchard.Indexing/Services/LuceneIndexProvider.cs index 9cf84e509..e2271a8ec 100644 --- a/src/Orchard.Web/Modules/Orchard.Indexing/Services/LuceneIndexProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.Indexing/Services/LuceneIndexProvider.cs @@ -10,6 +10,7 @@ using Lucene.Net.Store; using Orchard.Environment.Configuration; using Orchard.FileSystems.AppData; using Orchard.Indexing.Models; +using Orchard.Localization; using Orchard.Logging; using System.Xml.Linq; using Directory = Lucene.Net.Store.Directory; @@ -29,8 +30,6 @@ namespace Orchard.Indexing.Services { public static readonly string Settings = "Settings"; public static readonly string LastIndexUtc = "LastIndexedUtc"; - public ILogger Logger { get; set; } - public LuceneIndexProvider(IAppDataFolder appDataFolder, ShellSettings shellSettings) { _appDataFolder = appDataFolder; _shellSettings = shellSettings; @@ -43,8 +42,14 @@ namespace Orchard.Indexing.Services { // Ensures the directory exists EnsureDirectoryExists(); + + T = NullLocalizer.Instance; + Logger = NullLogger.Instance; } + public Localizer T { get; set; } + public ILogger Logger { get; set; } + public static Analyzer CreateAnalyzer() { // StandardAnalyzer does lower-case and stop-word filtering. It also removes punctuation return new StandardAnalyzer(LuceneVersion); @@ -189,7 +194,7 @@ namespace Orchard.Indexing.Services { } public IDocumentIndex New(int documentId) { - return new LuceneDocumentIndex(documentId); + return new LuceneDocumentIndex(documentId, T); } public ISearchBuilder CreateSearchBuilder(string indexName) { diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Services/RolesBasedAuthorizationService.cs b/src/Orchard.Web/Modules/Orchard.Roles/Services/RolesBasedAuthorizationService.cs index a74ed21d0..ce5f857b1 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Services/RolesBasedAuthorizationService.cs +++ b/src/Orchard.Web/Modules/Orchard.Roles/Services/RolesBasedAuthorizationService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; +using Orchard.Localization; using Orchard.Logging; using Orchard.ContentManagement; using Orchard.Roles.Models; @@ -20,16 +21,23 @@ namespace Orchard.Roles.Services { public RolesBasedAuthorizationService(IRoleService roleService, IAuthorizationServiceEventHandler authorizationServiceEventHandler) { _roleService = roleService; _authorizationServiceEventHandler = authorizationServiceEventHandler; + + T = NullLocalizer.Instance; Logger = NullLogger.Instance; } + public Localizer T { get; set; } public ILogger Logger { get; set; } protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; } public void CheckAccess(Permission permission, IUser user, IContent content) { if (!TryCheckAccess(permission, user, content)) { - throw new OrchardSecurityException { PermissionName = permission.Name }; + throw new OrchardSecurityException(T("A security exception occurred in the content management system.")) { + PermissionName = permission.Name, + User = user, + Content = content + }; } } diff --git a/src/Orchard/Commands/DefaultCommandManager.cs b/src/Orchard/Commands/DefaultCommandManager.cs index d49d15b93..87841e159 100644 --- a/src/Orchard/Commands/DefaultCommandManager.cs +++ b/src/Orchard/Commands/DefaultCommandManager.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using Autofac.Features.Metadata; +using Orchard.Localization; +using Orchard.Logging; namespace Orchard.Commands { public class DefaultCommandManager : ICommandManager { @@ -9,8 +11,14 @@ namespace Orchard.Commands { public DefaultCommandManager(IEnumerable>> handlers) { _handlers = handlers; + + T = NullLocalizer.Instance; + Logger = NullLogger.Instance; } + public Localizer T { get; set; } + public ILogger Logger { get; set; } + public void Execute(CommandParameters parameters) { var matches = MatchCommands(parameters); @@ -22,11 +30,11 @@ namespace Orchard.Commands { var commandMatch = string.Join(" ", parameters.Arguments.ToArray()); var commandList = string.Join(",", GetCommandDescriptors().Select(d => d.Name).ToArray()); if (matches.Any()) { - throw new OrchardException(string.Format("Multiple commands found matching arguments \"{0}\". Commands available: {1}.", + throw new OrchardSystemException(T("Multiple commands found matching arguments \"{0}\". Commands available: {1}.", commandMatch, commandList)); } else { - throw new OrchardException(string.Format("No command found matching arguments \"{0}\". Commands available: {1}.", + throw new OrchardSystemException(T("No command found matching arguments \"{0}\". Commands available: {1}.", commandMatch, commandList)); } } diff --git a/src/Orchard/Data/SessionFactoryHolder.cs b/src/Orchard/Data/SessionFactoryHolder.cs index 0c95bcdd0..5b820bd3f 100644 --- a/src/Orchard/Data/SessionFactoryHolder.cs +++ b/src/Orchard/Data/SessionFactoryHolder.cs @@ -7,6 +7,7 @@ using Orchard.Environment.Descriptor; using Orchard.Environment.Descriptor.Models; using Orchard.Environment.ShellBuilders.Models; using Orchard.FileSystems.AppData; +using Orchard.Localization; using Orchard.Logging; namespace Orchard.Data { @@ -33,16 +34,19 @@ namespace Orchard.Data { _shellBlueprint = shellBlueprint; _sessionFactoryBuilder = sessionFactoryBuilder; _appDataFolder = appDataFolder; + + T = NullLocalizer.Instance; Logger = NullLogger.Instance; } + public Localizer T { get; set; } public ILogger Logger { get; set; } public void CreateDatabase() { lock (this) { if (_sessionFactory != null) { Logger.Error("CreateSchema can not be called after a session factory was created"); - throw new OrchardException("CreateSchema can not be called after a session factory was created"); + throw new OrchardSystemException(T("CreateSchema can not be called after a session factory was created")); } _sessionFactory = BuildSessionFactory(true /*createDatabase*/, false /*updateSchema*/); @@ -53,7 +57,7 @@ namespace Orchard.Data { lock (this) { if (_sessionFactory != null) { Logger.Error("UpdateSchema can not be called after a session factory was created"); - throw new OrchardException("UpdateSchema can not be called after a session factory was created"); + throw new OrchardSystemException(T("UpdateSchema can not be called after a session factory was created")); } _sessionFactory = BuildSessionFactory(false /*createDatabase*/, true /*updateSchema*/); diff --git a/src/Orchard/Environment/Extensions/Compilers/DefaultExtensionCompiler.cs b/src/Orchard/Environment/Extensions/Compilers/DefaultExtensionCompiler.cs index 8da6db268..34e97cdba 100644 --- a/src/Orchard/Environment/Extensions/Compilers/DefaultExtensionCompiler.cs +++ b/src/Orchard/Environment/Extensions/Compilers/DefaultExtensionCompiler.cs @@ -1,7 +1,10 @@ -using System.CodeDom; +using System; +using System.CodeDom; using System.IO; using System.Linq; +using Orchard.FileSystems.Dependencies; using Orchard.FileSystems.VirtualPath; +using Orchard.Localization; using Orchard.Logging; namespace Orchard.Environment.Extensions.Compilers { @@ -11,26 +14,39 @@ namespace Orchard.Environment.Extensions.Compilers { public class DefaultExtensionCompiler : IExtensionCompiler { private readonly IVirtualPathProvider _virtualPathProvider; private readonly IProjectFileParser _projectFileParser; + private readonly IDependenciesFolder _dependenciesFolder; - public DefaultExtensionCompiler(IVirtualPathProvider virtualPathProvider, IProjectFileParser projectFileParser) { + public DefaultExtensionCompiler(IVirtualPathProvider virtualPathProvider, IProjectFileParser projectFileParser, IDependenciesFolder dependenciesFolder ) { _virtualPathProvider = virtualPathProvider; _projectFileParser = projectFileParser; + _dependenciesFolder = dependenciesFolder; + + T = NullLocalizer.Instance; Logger = NullLogger.Instance; } + public Localizer T { get; set; } public ILogger Logger { get; set; } public void Compile(CompileExtensionContext context) { Logger.Information("Generate code for file \"{0}\"", context.VirtualPath); + var moduleName = Path.GetFileNameWithoutExtension(context.VirtualPath); + if (_dependenciesFolder.GetDescriptor(moduleName) == null) + return; - using (var stream = _virtualPathProvider.OpenFile(context.VirtualPath)) { - var descriptor = _projectFileParser.Parse(stream); + try { + using (var stream = _virtualPathProvider.OpenFile(context.VirtualPath)) { + var descriptor = _projectFileParser.Parse(stream); - var directory = _virtualPathProvider.GetDirectoryName(context.VirtualPath); - foreach (var filename in descriptor.SourceFilenames.Select(f => _virtualPathProvider.Combine(directory, f))) { - context.AssemblyBuilder.AddCodeCompileUnit(CreateCompileUnit(filename)); + var directory = _virtualPathProvider.GetDirectoryName(context.VirtualPath); + foreach (var filename in descriptor.SourceFilenames.Select(f => _virtualPathProvider.Combine(directory, f))) { + context.AssemblyBuilder.AddCodeCompileUnit(CreateCompileUnit(filename)); + } } } + catch(Exception e) { + throw new OrchardSystemException(T("Error compiling module \"{0}\" from file \"{1}\"", moduleName, context.VirtualPath), e); + } } private CodeCompileUnit CreateCompileUnit(string virtualPath) { diff --git a/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs b/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs index 61bda79ed..a26267211 100644 --- a/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs +++ b/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs @@ -38,7 +38,7 @@ namespace Orchard.Environment.Extensions { var extensions = _extensionManager.AvailableExtensions().Where(d => d.ExtensionType == "Module").ToList(); var existingDependencies = _dependenciesFolder.LoadDescriptors().ToList(); - var deletedDependencies = existingDependencies.Where(e => !extensions.Any(e2 => e2.Name == e.Name)).ToList(); + var deletedDependencies = existingDependencies.Where(e => !extensions.Any(e2 => StringComparer.OrdinalIgnoreCase.Equals(e2.Name, e.Name))).ToList(); var loadingContext = new ExtensionLoadingContext(); @@ -91,7 +91,7 @@ namespace Orchard.Environment.Extensions { } var activatedExtension = extensionProbes.FirstOrDefault(); - var previousDependency = existingDependencies.Where(d => d.Name == extension.Name).FirstOrDefault(); + var previousDependency = existingDependencies.Where(d => StringComparer.OrdinalIgnoreCase.Equals(d.Name, extension.Name)).FirstOrDefault(); if (activatedExtension == null) { Logger.Warning("No loader found for extension \"{0}\"!", extension.Name); diff --git a/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs index 7585b2e45..b14e675e9 100644 --- a/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs +++ b/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs @@ -93,6 +93,8 @@ namespace Orchard.Environment.Extensions.Loaders { return null; var assembly = _buildManager.GetCompiledAssembly(projectPath); + if (assembly == null) + return null; //Logger.Information("Loading extension \"{0}\": assembly name=\"{1}\"", descriptor.Name, assembly.GetName().Name); return new ExtensionEntry { diff --git a/src/Orchard/Environment/OrchardHostContainerRegistry.cs b/src/Orchard/Environment/OrchardHostContainerRegistry.cs index 8dd27ea12..a1ec7b1bb 100644 --- a/src/Orchard/Environment/OrchardHostContainerRegistry.cs +++ b/src/Orchard/Environment/OrchardHostContainerRegistry.cs @@ -1,36 +1,46 @@ using System.Collections.Generic; +using Orchard.Caching; namespace Orchard.Environment { /// - /// Provides ability to connect Shims and the OrchardHostContainer + /// Provides ability to connect Shims to the OrchardHostContainer /// public static class OrchardHostContainerRegistry { - private static readonly IList _shims = new List(); + private static readonly IList> _shims = new List>(); private static IOrchardHostContainer _hostContainer; + private static readonly object _syncLock = new object(); public static void RegisterShim(IShim shim) { - _shims.Add(shim); - shim.HostContainer = _hostContainer; + lock (_syncLock) { + CleanupShims(); + + _shims.Add(new Weak(shim)); + shim.HostContainer = _hostContainer; + } } public static void RegisterHostContainer(IOrchardHostContainer container) { - if (object.ReferenceEquals(_hostContainer, container)) - return; + lock (_syncLock) { + CleanupShims(); - UnregisterContainerShims(); - _hostContainer = container; - RegisterContainerInShims(); - } - - private static void UnregisterContainerShims() { - foreach (var shim in _shims) { - shim.HostContainer = null; + _hostContainer = container; + RegisterContainerInShims(); } } private static void RegisterContainerInShims() { foreach (var shim in _shims) { - shim.HostContainer = _hostContainer; + var target = shim.Target; + if (target != null) { + target.HostContainer = _hostContainer; + } + } + } + + private static void CleanupShims() { + for (int i = _shims.Count - 1; i >= 0; i--) { + if (_shims[i].Target == null) + _shims.RemoveAt(i); } } } diff --git a/src/Orchard/FileSystems/AppData/AppDataFolder.cs b/src/Orchard/FileSystems/AppData/AppDataFolder.cs index e980848b6..b914074ea 100644 --- a/src/Orchard/FileSystems/AppData/AppDataFolder.cs +++ b/src/Orchard/FileSystems/AppData/AppDataFolder.cs @@ -65,7 +65,7 @@ namespace Orchard.FileSystems.AppData { } // Everything failed, throw an exception - throw new OrchardException(T("Unable to make room for file \"{0}\" in \"App_Data\" folder: too many conflicts.", destinationFileName).Text); + throw new OrchardSystemException(T("Unable to make room for file \"{0}\" in \"App_Data\" folder: too many conflicts.", destinationFileName)); } /// diff --git a/src/Orchard/FileSystems/Dependencies/DefaultDependenciesFolder.cs b/src/Orchard/FileSystems/Dependencies/DefaultDependenciesFolder.cs index 9e721be2a..b42d1d46d 100644 --- a/src/Orchard/FileSystems/Dependencies/DefaultDependenciesFolder.cs +++ b/src/Orchard/FileSystems/Dependencies/DefaultDependenciesFolder.cs @@ -30,7 +30,7 @@ namespace Orchard.FileSystems.Dependencies { } public DependencyDescriptor GetDescriptor(string moduleName) { - return LoadDescriptors().SingleOrDefault(d => d.Name == moduleName); + return LoadDescriptors().SingleOrDefault(d => StringComparer.OrdinalIgnoreCase.Equals(d.Name, moduleName)); } public IEnumerable LoadDescriptors() { diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index eea79bacb..1437a00db 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -418,6 +418,7 @@ + diff --git a/src/Orchard/OrchardException.cs b/src/Orchard/OrchardException.cs index b2a4d4b65..5e41408b4 100644 --- a/src/Orchard/OrchardException.cs +++ b/src/Orchard/OrchardException.cs @@ -1,12 +1,25 @@ using System; using System.Runtime.Serialization; +using Orchard.Localization; namespace Orchard { public class OrchardException : ApplicationException { - public OrchardException() : base("An exception occurred in the content management system.") { } - public OrchardException(Exception innerException) : base(innerException.Message, innerException) { } - public OrchardException(string message) : base(message) { } - protected OrchardException(SerializationInfo info, StreamingContext context) : base(info, context) { } - public OrchardException(string message, Exception innerException) : base(message, innerException) { } + private readonly LocalizedString _localizedMessage; + + public OrchardException(LocalizedString message) + : base(message.Text) { + _localizedMessage = message; + } + + public OrchardException(LocalizedString message, Exception innerException) + : base(message.Text, innerException) { + _localizedMessage = message; + } + + protected OrchardException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } + + public LocalizedString LocalizedMessage { get { return _localizedMessage; } } } -} +} \ No newline at end of file diff --git a/src/Orchard/OrchardSystemException.cs b/src/Orchard/OrchardSystemException.cs new file mode 100644 index 000000000..7eb42f13d --- /dev/null +++ b/src/Orchard/OrchardSystemException.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.Serialization; +using Orchard.Localization; + +namespace Orchard { + public class OrchardSystemException : Exception { + private readonly LocalizedString _localizedMessage; + + public OrchardSystemException(LocalizedString message) + : base(message.Text) { + _localizedMessage = message; + } + + public OrchardSystemException(LocalizedString message, Exception innerException) + : base(message.Text, innerException) { + _localizedMessage = message; + } + + protected OrchardSystemException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } + + public LocalizedString LocalizedMessage { get { return _localizedMessage; } } + } +} \ No newline at end of file diff --git a/src/Orchard/Security/OrchardSecurityException.cs b/src/Orchard/Security/OrchardSecurityException.cs index 9d1d36993..acad24c44 100644 --- a/src/Orchard/Security/OrchardSecurityException.cs +++ b/src/Orchard/Security/OrchardSecurityException.cs @@ -1,14 +1,16 @@ using System; using System.Runtime.Serialization; +using Orchard.ContentManagement; +using Orchard.Localization; namespace Orchard.Security { - public class OrchardSecurityException : OrchardException { - public OrchardSecurityException() : base("A security exception occurred in the content management system.") { } - public OrchardSecurityException(Exception innerException) : base(innerException.Message, innerException) { } - public OrchardSecurityException(string message) : base(message) { } + public class OrchardSecurityException : OrchardSystemException { + public OrchardSecurityException(LocalizedString message) : base(message) { } + public OrchardSecurityException(LocalizedString message, Exception innerException) : base(message, innerException) { } protected OrchardSecurityException(SerializationInfo info, StreamingContext context) : base(info, context) { } - public OrchardSecurityException(string message, Exception innerException) : base(message, innerException) { } public string PermissionName { get; set; } + public IUser User { get; set; } + public IContent Content { get; set; } } }