diff --git a/Composite.Workflows/C1Console/Elements/ElementProviderHelpers/AssociatedDataElementProviderHelper/AddDataFolderExWorkflow.cs b/Composite.Workflows/C1Console/Elements/ElementProviderHelpers/AssociatedDataElementProviderHelper/AddDataFolderExWorkflow.cs index 80b8c9d6b3..4f54ed36c7 100644 --- a/Composite.Workflows/C1Console/Elements/ElementProviderHelpers/AssociatedDataElementProviderHelper/AddDataFolderExWorkflow.cs +++ b/Composite.Workflows/C1Console/Elements/ElementProviderHelpers/AssociatedDataElementProviderHelper/AddDataFolderExWorkflow.cs @@ -35,6 +35,8 @@ public sealed partial class AddDataFolderExWorkflow : Composite.C1Console.Workfl private string HasLocalizationBindingName { get { return "HasLocalization"; } } + private static readonly object _lock = new object(); + public AddDataFolderExWorkflow() { InitializeComponent(); @@ -228,7 +230,16 @@ private void finalizeCodeActivity_Finalize_ExecuteCode(object sender, EventArgs IPage page = (IPage)dataEntityToken.Data; - page.AddFolderDefinition(type.GetImmutableTypeId()); + Guid dataTypeId = type.GetImmutableTypeId(); + + lock (_lock) + { + if (page.GetFolderDefinitionId(dataTypeId) == Guid.Empty) + { + page.AddFolderDefinition(dataTypeId); + } + } + SpecificTreeRefresher specificTreeRefresher = this.CreateSpecificTreeRefresher(); specificTreeRefresher.PostRefreshMesseges(this.EntityToken); diff --git a/Composite.Workflows/C1Console/Trees/Workflows/RemoveApplicationWorkflow.cs b/Composite.Workflows/C1Console/Trees/Workflows/RemoveApplicationWorkflow.cs index 1aef90e222..195286ec31 100644 --- a/Composite.Workflows/C1Console/Trees/Workflows/RemoveApplicationWorkflow.cs +++ b/Composite.Workflows/C1Console/Trees/Workflows/RemoveApplicationWorkflow.cs @@ -37,7 +37,8 @@ private void initializeCodeActivity_UpdateBindings_ExecuteCode(object sender, Ev Dictionary selectableTreeIds = new Dictionary(); foreach (Tree tree in TreeFacade.AllTrees) { - if (tree.HasAttachmentPoints(this.EntityToken) == false) continue; + if (!tree.HasAttachmentPoints(this.EntityToken)) continue; + if (!tree.HasPossibleAttachmentPoints(this.EntityToken)) continue; selectableTreeIds.Add(tree.TreeId, tree.AllowedAttachmentApplicationName); } diff --git a/Composite.Workflows/Composite.Workflows.csproj b/Composite.Workflows/Composite.Workflows.csproj index 178935dd0e..a8f8223d6c 100644 --- a/Composite.Workflows/Composite.Workflows.csproj +++ b/Composite.Workflows/Composite.Workflows.csproj @@ -1371,8 +1371,10 @@ $(ProjectDir)git_branch.txt $(ProjectDir)git_commithash.txt - - + + + + $([System.IO.File]::ReadAllText("$(GitBranchFile)").Trim()) $([System.IO.File]::ReadAllText("$(GitCommitHashFile)").Trim()) diff --git a/Composite.Workflows/Plugins/Elements/ElementProviders/PageTypeElementProvider/AddPageTypeDefaultPageContentWorkflow.cs b/Composite.Workflows/Plugins/Elements/ElementProviders/PageTypeElementProvider/AddPageTypeDefaultPageContentWorkflow.cs index 976ed08a6d..ed1bb822f0 100644 --- a/Composite.Workflows/Plugins/Elements/ElementProviders/PageTypeElementProvider/AddPageTypeDefaultPageContentWorkflow.cs +++ b/Composite.Workflows/Plugins/Elements/ElementProviders/PageTypeElementProvider/AddPageTypeDefaultPageContentWorkflow.cs @@ -41,10 +41,19 @@ private void finalizeCodeActivity_Finalize_ExecuteCode(object sender, EventArgs DataEntityToken dataEntityToken = piggybag.GetParentEntityTokens().FindDataEntityToken(typeof(IPageType)); IPageType parentPageType = (IPageType)dataEntityToken.Data; - defaultPageContent.PageTypeId = parentPageType.Id; - defaultPageContent.Content = " "; + var duplicate = DataFacade.GetData(f => f.PageTypeId == parentPageType.Id && f.PlaceHolderId == defaultPageContent.PlaceHolderId).FirstOrDefault(); - defaultPageContent = DataFacade.AddNew(defaultPageContent); + if (duplicate == null) + { + defaultPageContent.PageTypeId = parentPageType.Id; + defaultPageContent.Content = " "; + + defaultPageContent = DataFacade.AddNew(defaultPageContent); + } + else + { + defaultPageContent = duplicate; + } this.CloseCurrentView(); this.RefreshCurrentEntityToken(); diff --git a/Composite/C1Console/Actions/FlowControllerServicesContainer.cs b/Composite/C1Console/Actions/FlowControllerServicesContainer.cs index 10bbf44078..81de3e765e 100644 --- a/Composite/C1Console/Actions/FlowControllerServicesContainer.cs +++ b/Composite/C1Console/Actions/FlowControllerServicesContainer.cs @@ -1,16 +1,17 @@ using System; using System.Collections.Generic; +using Composite.Core.Extensions; namespace Composite.C1Console.Actions { - /// + /// /// /// [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public sealed class FlowControllerServicesContainer { - private Dictionary> _services = new Dictionary>(); + private readonly Dictionary> _services = new Dictionary>(); /// @@ -18,6 +19,15 @@ public FlowControllerServicesContainer() { } + /// + public FlowControllerServicesContainer(params IFlowControllerService[] services) + { + foreach (var service in services) + { + AddService(service); + } + } + // Creates a new service container and initialized it with the services from servicesContainerToClone. /// public FlowControllerServicesContainer(FlowControllerServicesContainer servicesContainerToClone) @@ -34,14 +44,7 @@ public void AddService(IFlowControllerService flowControllerService) foreach (Type interfaceType in type.GetInterfaces()) { - List list; - - if (_services.TryGetValue(interfaceType, out list) == false) - { - list = new List(); - - _services.Add(interfaceType, list); - } + List list = _services.GetOrAdd(interfaceType, () => new List()); list.Add(flowControllerService); } @@ -56,8 +59,7 @@ public void RemoveService(IFlowControllerService flowControllerService) foreach (Type interfaceType in type.GetInterfaces()) { - List list; - if (_services.TryGetValue(interfaceType, out list) == false) throw new InvalidOperationException(); + if (!_services.TryGetValue(interfaceType, out var list)) throw new InvalidOperationException(); list.Remove(flowControllerService); } @@ -83,16 +85,14 @@ public T GetService() where T : IFlowControllerService /// public IFlowControllerService GetService(Type serviceType) { - List list; - - if (_services.TryGetValue(serviceType, out list) == false) + if (!_services.TryGetValue(serviceType, out var list)) { return null; } if (list.Count > 1) { - throw new InvalidOperationException(string.Format("More than one services of type '{0}' is added", serviceType)); + throw new InvalidOperationException($"More than one service of type '{serviceType}' was added"); } return (IFlowControllerService)list[0]; diff --git a/Composite/C1Console/Elements/ElementProviderHelpers/DataGroupingProviderHelper/DataGroupingProviderHelper.cs b/Composite/C1Console/Elements/ElementProviderHelpers/DataGroupingProviderHelper/DataGroupingProviderHelper.cs index b9896edcec..c29ae95fb8 100644 --- a/Composite/C1Console/Elements/ElementProviderHelpers/DataGroupingProviderHelper/DataGroupingProviderHelper.cs +++ b/Composite/C1Console/Elements/ElementProviderHelpers/DataGroupingProviderHelper/DataGroupingProviderHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -270,9 +270,9 @@ private IEnumerable GetRootGroupFolders(Type interfaceType, EntityToken var expressionBuilder = new ExpressionBuilder(interfaceType, queryable); IQueryable resultQueryable = expressionBuilder. + Distinct(). OrderBy(propertyInfo, true, firstDataFieldDescriptor.TreeOrderingProfile.OrderDescending). Select(propertyInfo, true). - Distinct(). CreateQuery(); var propertyInfoValueCollection = new PropertyInfoValueCollection(); diff --git a/Composite/C1Console/Security/Foundation/PermissionTypeFacadeCaching.cs b/Composite/C1Console/Security/Foundation/PermissionTypeFacadeCaching.cs index f6f4122529..ba3b5ee8a8 100644 --- a/Composite/C1Console/Security/Foundation/PermissionTypeFacadeCaching.cs +++ b/Composite/C1Console/Security/Foundation/PermissionTypeFacadeCaching.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Composite.Core.Caching; @@ -116,31 +116,14 @@ private static void SetToCache(UserToken userToken, EntityToken entityToken, IRe private static IReadOnlyCollection GetFromCache(UserToken userToken, EntityToken entityToken, object cachingKey) { - // Using RequestLifetimeCache and there for no thread locking /MRJ - - Dictionary>> permissionTypeCache; + var permissionTypeCache = RequestLifetimeCache.TryGet>>>(cachingKey); - if (RequestLifetimeCache.HasKey(cachingKey)) + if (permissionTypeCache == null || !permissionTypeCache.TryGetValue(userToken, out var entityTokenPermissionTypes)) { - permissionTypeCache = RequestLifetimeCache.TryGet>>>(cachingKey); + return null; } - else - { - permissionTypeCache = new Dictionary>>(); - - RequestLifetimeCache.Add(cachingKey, permissionTypeCache); - } - - Dictionary> entityTokenPermissionTypes; - if (!permissionTypeCache.TryGetValue(userToken, out entityTokenPermissionTypes)) - { - entityTokenPermissionTypes = new Dictionary>(); - permissionTypeCache.Add(userToken, entityTokenPermissionTypes); - } - - IReadOnlyCollection permissionTypes; - entityTokenPermissionTypes.TryGetValue(entityToken, out permissionTypes); + entityTokenPermissionTypes.TryGetValue(entityToken, out var permissionTypes); return permissionTypes; } diff --git a/Composite/C1Console/Security/Plugins/LoginSessionStore/Runtime/LoginSessionStoreResolver.cs b/Composite/C1Console/Security/Plugins/LoginSessionStore/Runtime/LoginSessionStoreResolver.cs index 195863827b..57e98ae067 100644 --- a/Composite/C1Console/Security/Plugins/LoginSessionStore/Runtime/LoginSessionStoreResolver.cs +++ b/Composite/C1Console/Security/Plugins/LoginSessionStore/Runtime/LoginSessionStoreResolver.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; -using Castle.Core.Internal; +using Composite.Core.Extensions; namespace Composite.C1Console.Security.Plugins.LoginSessionStore.Runtime { diff --git a/Composite/C1Console/Trees/TreeElementAttachingProvider.cs b/Composite/C1Console/Trees/TreeElementAttachingProvider.cs index 5aed056b2f..d6c38b50ec 100644 --- a/Composite/C1Console/Trees/TreeElementAttachingProvider.cs +++ b/Composite/C1Console/Trees/TreeElementAttachingProvider.cs @@ -79,7 +79,7 @@ public IEnumerable GetAlternateElementLists(Enti } catch (Exception ex) { - LoggingService.LogError("TreeFacade", string.Format("Getting elements from the three '{0}' failed", tree.TreeId)); + LoggingService.LogError("TreeFacade", string.Format("Getting elements from the tree '{0}' failed", tree.TreeId)); LoggingService.LogError("TreeFacade", ex); Element errorElement = ShowErrorElementHelper.CreateErrorElement( diff --git a/Composite/C1Console/Workflow/WorkflowFacadeImpl.cs b/Composite/C1Console/Workflow/WorkflowFacadeImpl.cs index 2f4f3504f0..b86e8ad5d0 100644 --- a/Composite/C1Console/Workflow/WorkflowFacadeImpl.cs +++ b/Composite/C1Console/Workflow/WorkflowFacadeImpl.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -161,10 +162,9 @@ public WorkflowInstance CreateNewWorkflow(Type workflowType) StringBuilder errors = new StringBuilder(); foreach (ValidationError error in exp.Errors) { - errors.AppendLine(error.ToString()); } - Log.LogError("WorkflowFacade", errors.ToString()); + Log.LogError(LogTitle, errors.ToString()); throw; } } @@ -182,14 +182,14 @@ public WorkflowInstance CreateNewWorkflow(Type workflowType, Dictionary attributes = workflowType.GetCustomAttributesRecursively().ToList(); - Verify.That(attributes.Count <= 1, "More than one attribute of type '{0}' found", typeof(AllowPersistingWorkflowAttribute).FullName); + Verify.That(attributes.Count <= 1, $"More than one attribute of type '{nameof(AllowPersistingWorkflowAttribute)}' found"); var persistenceType = attributes.Count == 1 ? attributes[0].WorkflowPersistingType : WorkflowPersistingType.Never; @@ -337,10 +326,7 @@ private void RemovePersistingType(Guid instanceId) { using (_resourceLocker.Locker) { - if (_resourceLocker.Resources.WorkflowPersistingTypeDictionary.ContainsKey(instanceId)) - { - _resourceLocker.Resources.WorkflowPersistingTypeDictionary.Remove(instanceId); - } + _resourceLocker.Resources.WorkflowPersistingTypeDictionary.Remove(instanceId); } } @@ -386,15 +372,8 @@ private void ReleaseAllLocks(Guid instanceId) private bool HasEntityTokenLockAttribute(Type workflowType) { - bool hasEntityLockAttribute; - if (!_hasEntityTokenLockAttributeCache.TryGetValue(workflowType, out hasEntityLockAttribute)) - { - hasEntityLockAttribute = workflowType.GetCustomAttributesRecursively().Any(); - - _hasEntityTokenLockAttributeCache.Add(workflowType, hasEntityLockAttribute); - } - - return hasEntityLockAttribute; + return _hasEntityTokenLockAttributeCache.GetOrAdd(workflowType, + type => type.GetCustomAttributesRecursively().Any()); } #endregion @@ -407,14 +386,7 @@ public void SetFlowControllerServicesContainer(Guid instanceId, FlowControllerSe using (_resourceLocker.Locker) { - if (!_resourceLocker.Resources.FlowControllerServicesContainers.ContainsKey(instanceId)) - { - _resourceLocker.Resources.FlowControllerServicesContainers.Add(instanceId, flowControllerServicesContainer); - } - else - { - _resourceLocker.Resources.FlowControllerServicesContainers[instanceId] = flowControllerServicesContainer; - } + _resourceLocker.Resources.FlowControllerServicesContainers[instanceId] = flowControllerServicesContainer; } } @@ -442,10 +414,7 @@ public void RemoveFlowControllerServicesContainer(Guid instanceId) using (_resourceLocker.Locker) { - if (_resourceLocker.Resources.FlowControllerServicesContainers.ContainsKey(instanceId)) - { - _resourceLocker.Resources.FlowControllerServicesContainers.Remove(instanceId); - } + _resourceLocker.Resources.FlowControllerServicesContainers.Remove(instanceId); } } #endregion @@ -481,11 +450,8 @@ public Semaphore WaitForIdleStatus(Guid instanceId) { return null; } - - if (_resourceLocker.Resources.WorkflowIdleWaitSemaphores.ContainsKey(instanceId)) - { - _resourceLocker.Resources.WorkflowIdleWaitSemaphores.Remove(instanceId); - } + + _resourceLocker.Resources.WorkflowIdleWaitSemaphores.Remove(instanceId); Semaphore semaphore = new Semaphore(0, 1); _resourceLocker.Resources.WorkflowIdleWaitSemaphores.Add(instanceId, semaphore); @@ -501,13 +467,11 @@ private void SetWorkflowInstanceStatus(Guid instanceId, WorkflowInstanceStatus w { var resources = _resourceLocker.Resources; - string identity = UserValidationFacade.IsLoggedIn() ? UserValidationFacade.GetUsername() : "(system process)"; - Action releaseIdleWaitSemaphore = () => { - if (resources.WorkflowIdleWaitSemaphores.ContainsKey(instanceId)) + if (resources.WorkflowIdleWaitSemaphores.TryGetValue(instanceId, out var semaphore)) { - resources.WorkflowIdleWaitSemaphores[instanceId].Release(); + semaphore.Release(); resources.WorkflowIdleWaitSemaphores.Remove(instanceId); } }; @@ -517,12 +481,7 @@ private void SetWorkflowInstanceStatus(Guid instanceId, WorkflowInstanceStatus w case WorkflowInstanceStatus.Idle: releaseIdleWaitSemaphore(); - if (!resources.WorkflowStatusDictionary.ContainsKey(instanceId) && newlyCreateOrLoaded) - { - resources.WorkflowStatusDictionary.Add(instanceId, WorkflowInstanceStatus.Idle); - } - - resources.WorkflowStatusDictionary[instanceId] = WorkflowInstanceStatus.Idle; + resources.WorkflowStatusDictionary[instanceId] = WorkflowInstanceStatus.Idle; PersistFormData(instanceId); @@ -539,9 +498,10 @@ private void SetWorkflowInstanceStatus(Guid instanceId, WorkflowInstanceStatus w default: throw new InvalidOperationException("This line should not be reachable."); } - - Log.LogVerbose(LogTitle, "Workflow instance status changed to {0}. Id = {1}, User = {2}", workflowInstanceStatus, instanceId, identity); } + + string identity = UserValidationFacade.IsLoggedIn() ? UserValidationFacade.GetUsername() : "(system process)"; + Log.LogVerbose(LogTitle, $"Workflow instance status changed to {workflowInstanceStatus}. Id = {instanceId}, User = {identity}"); } #endregion @@ -718,7 +678,7 @@ public void FireCustomEvent(int customEventNumber, Guid instanceId, Dictionary 5) throw new ArgumentException("Number must be between 1 and 5", "customEventNumber"); + if (customEventNumber < 1 || customEventNumber > 5) throw new ArgumentException("Number must be between 1 and 5", nameof(customEventNumber)); using (_resourceLocker.Locker) { @@ -767,9 +727,9 @@ public void FireChildWorkflowDoneEvent(Guid parentInstanceId, string workflowRes #region FormData methods public void AddFormData(Guid instanceId, FormData formData) { - using (_resourceLocker.Locker) + if (!_resourceLocker.Resources.FormData.TryAdd(instanceId, formData)) { - _resourceLocker.Resources.FormData.Add(instanceId, formData); + throw new ArgumentException($"Form data for instance ID '{instanceId}' has already been added"); } } @@ -777,37 +737,28 @@ public void AddFormData(Guid instanceId, FormData formData) public bool TryGetFormData(Guid instanceId, out FormData formData) { - using (_resourceLocker.Locker) - { - return _resourceLocker.Resources.FormData.TryGetValue(instanceId, out formData); - } + return _resourceLocker.Resources.FormData.TryGetValue(instanceId, out formData); } public FormData GetFormData(Guid instanceId, bool allowCreationIfNotExisting = false) { - FormData formData; - if (!TryGetFormData(instanceId, out formData) && allowCreationIfNotExisting) + var allFormData = _resourceLocker.Resources.FormData; + + if (allowCreationIfNotExisting) { - formData = new FormData(); - AddFormData(instanceId, formData); + return allFormData.GetOrAdd(instanceId, key => new FormData()); } - return formData; + return allFormData.TryGetValue(instanceId, out var formData) ? formData : null; } private void RemoveIfExistFormData(Guid instanceId) { - using (_resourceLocker.Locker) - { - if (_resourceLocker.Resources.FormData.ContainsKey(instanceId)) - { - _resourceLocker.Resources.FormData.Remove(instanceId); - } - } + _resourceLocker.Resources.FormData.TryRemove(instanceId, out _); } #endregion @@ -987,10 +938,7 @@ private WorkflowRuntime InitializeWorkflowRuntime() OnWorkflowInstanceTerminatedCleanup(args.WorkflowInstance.InstanceId); } - using (_resourceLocker.Locker) - { - _resourceLocker.Resources.ExceptionFromWorkflow.Add(Thread.CurrentThread.ManagedThreadId, args.Exception); - } + _resourceLocker.Resources.ExceptionFromWorkflow[Thread.CurrentThread.ManagedThreadId] = args.Exception; }; @@ -1188,7 +1136,7 @@ private void TryLoadPersistedFormData(string filename) if (!_resourceLocker.Resources.FormData.ContainsKey(id)) { - _resourceLocker.Resources.FormData.Add(id, formData); + _resourceLocker.Resources.FormData.TryAdd(id, formData); FormsWorkflowBindingCache.Bindings.TryAdd(id, formData.Bindings); } @@ -1288,19 +1236,15 @@ private void PersistFormData(Guid instanceId) { var resources = _resourceLocker.Resources; - bool shouldPersist = - resources.WorkflowPersistingTypeDictionary - .Any(f => f.Key == instanceId && f.Value != WorkflowPersistingType.Never); + bool shouldPersist = resources.WorkflowPersistingTypeDictionary.TryGetValue(instanceId, out var persistanceType) + && persistanceType != WorkflowPersistingType.Never; - if (!shouldPersist) return; - - - FormData formData = resources.FormData. - Where(f => f.Key == instanceId). - Select(f => f.Value). - SingleOrDefault(); - - if (formData == null) return; + if (!shouldPersist + || !resources.FormData.TryGetValue(instanceId, out FormData formData) + || formData == null) + { + return; + } PersistFormData(instanceId, formData); } @@ -1455,20 +1399,20 @@ private sealed class Resources public Resources() { this.WorkflowStatusDictionary = new Dictionary(); - this.FormData = new Dictionary(); + this.FormData = new ConcurrentDictionary(); this.FlowControllerServicesContainers = new Dictionary(); this.WorkflowPersistingTypeDictionary = new Dictionary(); this.EventHandleFilters = new Dictionary(); } public Dictionary WorkflowStatusDictionary { get; } - public Dictionary FormData { get; } + public ConcurrentDictionary FormData { get; } public Dictionary FlowControllerServicesContainers { get; } public Dictionary WorkflowPersistingTypeDictionary { get; } public Dictionary WorkflowIdleWaitSemaphores { get; private set; } - public Dictionary ExceptionFromWorkflow { get; private set; } + public ConcurrentDictionary ExceptionFromWorkflow { get; private set; } public Dictionary EventHandleFilters { get; } @@ -1481,26 +1425,14 @@ public static void InitializeResources(Resources resources) foreach (Guid instanceId in instanceIds) { - if (resources.WorkflowStatusDictionary.ContainsKey(instanceId)) - { - resources.WorkflowStatusDictionary.Remove(instanceId); - } - - if (resources.FormData.ContainsKey(instanceId)) - { - resources.FormData.Remove(instanceId); - } - - if (resources.FlowControllerServicesContainers.ContainsKey(instanceId)) - { - resources.FlowControllerServicesContainers.Remove(instanceId); - } - + resources.WorkflowStatusDictionary.Remove(instanceId); + resources.FormData.TryRemove(instanceId, out _); + resources.FlowControllerServicesContainers.Remove(instanceId); resources.WorkflowPersistingTypeDictionary.Remove(instanceId); } resources.WorkflowIdleWaitSemaphores = new Dictionary(); - resources.ExceptionFromWorkflow = new Dictionary(); + resources.ExceptionFromWorkflow = new ConcurrentDictionary(); } } } diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 385e2e52ca..8b5cf4e758 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -1,4 +1,4 @@ - + Debug @@ -68,8 +68,8 @@ false - - ..\packages\Castle.Core.3.3.1\lib\net45\Castle.Core.dll + + ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll True @@ -97,10 +97,6 @@ False ..\bin\Microsoft.Practices.ObjectBuilder.dll - - ..\packages\Microsoft.WebSockets.0.2.3.1\lib\net45\Microsoft.WebSockets.dll - True - ..\packages\Newtonsoft.Json.6.0.5\lib\net45\Newtonsoft.Json.dll True @@ -154,7 +150,14 @@ 3.5 + + ..\packages\System.Threading.Tasks.Dataflow.4.7.0\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll + + + ..\packages\System.ValueTuple.4.4.0\lib\net47\System.ValueTuple.dll + True + ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll @@ -190,19 +193,19 @@ ..\bin\TidyNet.dll - ..\packages\WampSharp.1.2.5.32-beta\lib\net45\WampSharp.dll + ..\packages\WampSharp.18.3.1\lib\net45\WampSharp.dll True - ..\packages\WampSharp.AspNet.WebSockets.Server.1.2.5.32-beta\lib\net45\WampSharp.AspNet.WebSockets.Server.dll + ..\packages\WampSharp.AspNet.WebSockets.Server.18.3.1\lib\net45\WampSharp.AspNet.WebSockets.Server.dll True - ..\packages\WampSharp.NewtonsoftJson.1.2.5.32-beta\lib\net45\WampSharp.NewtonsoftJson.dll + ..\packages\WampSharp.NewtonsoftJson.18.3.1\lib\net45\WampSharp.NewtonsoftJson.dll True - ..\packages\WampSharp.WebSockets.1.2.5.32-beta\lib\net45\WampSharp.WebSockets.dll + ..\packages\WampSharp.WebSockets.18.3.1\lib\net45\WampSharp.WebSockets.dll True @@ -2676,8 +2679,10 @@ $(ProjectDir)git_branch.txt $(ProjectDir)git_commithash.txt - - + + + + $([System.IO.File]::ReadAllText("$(GitBranchFile)").Trim()) $([System.IO.File]::ReadAllText("$(GitCommitHashFile)").Trim()) diff --git a/Composite/Core/Collections/Generic/ResourceLocker.cs b/Composite/Core/Collections/Generic/ResourceLocker.cs index 0264dcbd87..da96ca855b 100644 --- a/Composite/Core/Collections/Generic/ResourceLocker.cs +++ b/Composite/Core/Collections/Generic/ResourceLocker.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; @@ -60,13 +60,7 @@ public T Resources /// - public bool IsInitialized - { - get - { - return _initialized; - } - } + public bool IsInitialized => _initialized; /// @@ -114,32 +108,17 @@ public void Initialize() } finally { - if(globalReaderLock != null) - { - globalReaderLock.Dispose(); - } + globalReaderLock?.Dispose(); } } /// - public IDisposable Locker - { - get - { - return new ResourceLockerToken(this); - } - } + public IDisposable Locker => new ResourceLockerToken(this); /// - public IDisposable ReadLocker - { - get - { - return new ResourceLockerToken(this); - } - } + public IDisposable ReadLocker => new ResourceLockerToken(this); /// @@ -170,9 +149,7 @@ private sealed class ResourceLockerToken : IDisposable internal ResourceLockerToken(ResourceLocker resourceLocker) { - if (resourceLocker == null) throw new ArgumentNullException("resourceLocker"); - - _resourceLocker = resourceLocker; + _resourceLocker = resourceLocker ?? throw new ArgumentNullException(nameof(resourceLocker)); int tires = 120; @@ -192,10 +169,7 @@ internal ResourceLockerToken(ResourceLocker resourceLocker) } finally { - if (coreLock != null) - { - coreLock.Dispose(); - } + coreLock?.Dispose(); } if (!success) diff --git a/Composite/Core/Configuration/BuildinPlugins/GlobalSettingsProvider/BuildinGlobalSettingsProvider.cs b/Composite/Core/Configuration/BuildinPlugins/GlobalSettingsProvider/BuildinGlobalSettingsProvider.cs index ba4480c67b..5f6238a023 100644 --- a/Composite/Core/Configuration/BuildinPlugins/GlobalSettingsProvider/BuildinGlobalSettingsProvider.cs +++ b/Composite/Core/Configuration/BuildinPlugins/GlobalSettingsProvider/BuildinGlobalSettingsProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Threading; using Composite.Core.Configuration.Plugins.GlobalSettingsProvider; @@ -27,7 +27,7 @@ internal sealed class BuildinGlobalSettingsProvider : IGlobalSettingsProvider private string _packageLicenseDirectory = "~/PackageLicenses"; private readonly ICachingSettings _cachingSettings = new BuildinCachingSettings(); private readonly List _nonProbableAssemblyNames = new List(); - private readonly int _consoleMessageQueueSecondToLive = TimeSpan.FromMinutes(10).Seconds; + private readonly int _consoleMessageQueueSecondToLive = (int) TimeSpan.FromMinutes(10).TotalSeconds; private bool _enableDataTypesAutoUpdate = false; private bool _broadcastConsoleElementChanges = true; private bool _prettifyPublicMarkup = true; diff --git a/Composite/Core/Extensions/DictionaryExtensionMethods.cs b/Composite/Core/Extensions/DictionaryExtensionMethods.cs index 77872d9008..ceb284c4a8 100644 --- a/Composite/Core/Extensions/DictionaryExtensionMethods.cs +++ b/Composite/Core/Extensions/DictionaryExtensionMethods.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -10,9 +10,8 @@ internal static class DictionaryExtensionMethods { public static TValue GetOrAdd(this IDictionary dictionary, TKey key, Func createValue) { - if (dictionary is ConcurrentDictionary) + if (dictionary is ConcurrentDictionary concurrentDictionary) { - var concurrentDictionary = dictionary as ConcurrentDictionary; return concurrentDictionary.GetOrAdd(key, k => createValue()); } @@ -36,6 +35,33 @@ public static TValue GetOrAdd(this IDictionary dicti return value; } + public static TValue GetOrAdd(this IDictionary dictionary, TKey key, Func createValue) + { + if (dictionary is ConcurrentDictionary concurrentDictionary) + { + return concurrentDictionary.GetOrAdd(key, createValue); + } + + TValue value; + if (dictionary.TryGetValue(key, out value)) + { + return value; + } + + lock (dictionary) + { + if (dictionary.TryGetValue(key, out value)) + { + return value; + } + + value = createValue(key); + dictionary.Add(key, value); + } + + return value; + } + public static List> SortByKeys(this Dictionary dictionary) { var result = dictionary.ToList(); diff --git a/Composite/Core/IO/MimeTypeInfo.cs b/Composite/Core/IO/MimeTypeInfo.cs index f6148db8c5..7972ad8219 100644 --- a/Composite/Core/IO/MimeTypeInfo.cs +++ b/Composite/Core/IO/MimeTypeInfo.cs @@ -1,4 +1,4 @@ -using System.Collections.Concurrent; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Configuration; using System.Diagnostics.CodeAnalysis; @@ -28,7 +28,7 @@ public static class MimeTypeInfo private static readonly ConcurrentDictionary _iisServeableExtensions = new ConcurrentDictionary(); private static List _textMimeTypes = - new List { MimeTypeInfo.Css, MimeTypeInfo.Js, MimeTypeInfo.Xml, MimeTypeInfo.Text, MimeTypeInfo.Html, MimeTypeInfo.Sass, + new List { MimeTypeInfo.Css, MimeTypeInfo.Js, MimeTypeInfo.Json, MimeTypeInfo.Xml, MimeTypeInfo.Text, MimeTypeInfo.Html, MimeTypeInfo.Sass, MimeTypeInfo.Ascx, MimeTypeInfo.Ashx, MimeTypeInfo.Asmx, MimeTypeInfo.Aspx, MimeTypeInfo.Asax, MimeTypeInfo.CSharp, MimeTypeInfo.Resx, MimeTypeInfo.MasterPage, MimeTypeInfo.CsHtml, MimeTypeInfo.Svg }; @@ -67,6 +67,9 @@ private static ResourceHandle GetIconHandle(string name) /// public static string Js => "text/js"; + /// + public static string Json => "application/json"; + /// public static string Xml => "text/xml"; @@ -161,7 +164,8 @@ static MimeTypeInfo() _toCanonical.Add("application/x-javascript", MimeTypeInfo.Js); RegisterMimeType(MimeTypeInfo.Js, "js", "mimetype-js", true); - RegisterMimeType("text/html", new[] { "htm", "html", "xhtml" }, "mimetype-html", true); + RegisterMimeType(MimeTypeInfo.Json, new[] { "json" }, "mimetype-js"); + RegisterMimeType(MimeTypeInfo.Html, new[] { "htm", "html", "xhtml" }, "mimetype-html", true); // Audio/Video RegisterMimeType("audio/x-wav", "wav", null, true); diff --git a/Composite/Core/Logging/DebugLoggingScope.cs b/Composite/Core/Logging/DebugLoggingScope.cs index bff952a137..b2c50cec93 100644 --- a/Composite/Core/Logging/DebugLoggingScope.cs +++ b/Composite/Core/Logging/DebugLoggingScope.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System; using System.Diagnostics; @@ -13,8 +10,6 @@ namespace Composite.Core.Logging [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public sealed class DebugLoggingScope : IDisposable { - private static IDisposable _noActionDisposable = new NoActionDisposable(); - /// public static IDisposable CompletionTime( Type callingType, string actionInfo ) { @@ -22,10 +17,8 @@ public static IDisposable CompletionTime( Type callingType, string actionInfo ) { return new DebugLoggingScope(callingType.Name, actionInfo, false, TimeSpan.MinValue); } - else - { - return _noActionDisposable; - } + + return EmptyDisposable.Instance; } @@ -36,10 +29,8 @@ public static IDisposable CompletionTime(Type callingType, string actionInfo, Ti { return new DebugLoggingScope(callingType.Name, actionInfo, false, loggingThreshold); } - else - { - return _noActionDisposable; - } + + return EmptyDisposable.Instance; } @@ -50,24 +41,22 @@ public static IDisposable MethodInfoScope { if (RuntimeInformation.IsDebugBuild) { - StackTrace stackTrace = new StackTrace(); - StackFrame stackFrame = stackTrace.GetFrame(1); - string scopeName = string.Format("{0}.{1}", stackFrame.GetMethod().DeclaringType.Name, stackFrame.GetMethod().Name); + var stackTrace = new StackTrace(); + var method = stackTrace.GetFrame(1).GetMethod(); + string scopeName = $"{method.DeclaringType.Name}.{method.Name}"; return new DebugLoggingScope(scopeName, "Method", true, TimeSpan.MinValue); } - else - { - return _noActionDisposable; - } + + return EmptyDisposable.Instance; } } - private int _startTickCount; - private string _scopeName; - private string _actionInfo; - private TimeSpan _threshold; + private readonly int _startTickCount; + private readonly string _scopeName; + private readonly string _actionInfo; + private readonly TimeSpan _threshold; private DebugLoggingScope(string scopeName, string actionInfo, bool logStart, TimeSpan threshold) { @@ -76,9 +65,9 @@ private DebugLoggingScope(string scopeName, string actionInfo, bool logStart, Ti _actionInfo = actionInfo; _threshold = threshold; - if (logStart==true) + if (logStart) { - LoggingService.LogVerbose(_scopeName, string.Format("Starting {0}", _actionInfo)); + Log.LogVerbose(_scopeName, $"Starting {_actionInfo}"); } } @@ -87,9 +76,10 @@ private DebugLoggingScope(string scopeName, string actionInfo, bool logStart, Ti public void Dispose() { int endTickCount = Environment.TickCount; - if ((endTickCount - _startTickCount) >= _threshold.Milliseconds) + var totalMilliseconds = endTickCount - _startTickCount; + if (totalMilliseconds >= _threshold.TotalMilliseconds) { - LoggingService.LogVerbose(_scopeName, string.Format("Finished {0} ({1} ms)", _actionInfo, endTickCount - _startTickCount)); + Log.LogVerbose(_scopeName, $"Finished {_actionInfo} ({totalMilliseconds} ms)"); } #if LeakCheck GC.SuppressFinalize(this); @@ -105,14 +95,5 @@ public void Dispose() Composite.Core.Instrumentation.DisposableResourceTracer.RegisterFinalizerExecution(stack); } #endif - - - private class NoActionDisposable : IDisposable - { - public void Dispose() - { - } - } - } } diff --git a/Composite/Core/PackageSystem/PackageFragmentInstallers/DataPackageFragmentInstaller.cs b/Composite/Core/PackageSystem/PackageFragmentInstallers/DataPackageFragmentInstaller.cs index 38d299cb77..b23a922a01 100644 --- a/Composite/Core/PackageSystem/PackageFragmentInstallers/DataPackageFragmentInstaller.cs +++ b/Composite/Core/PackageSystem/PackageFragmentInstallers/DataPackageFragmentInstaller.cs @@ -36,7 +36,7 @@ public sealed class DataPackageFragmentInstaller : BasePackageFragmentInstaller private Dictionary>> _missingDataReferences; - private static Dictionary _pageVersionIds = new Dictionary(); + private static readonly Dictionary _pageVersionIds = new Dictionary(); /// public override IEnumerable Validate() @@ -208,15 +208,14 @@ private XElement AddData(DataType dataType, CultureInfo cultureInfo) } } - ILocalizedControlled localizedControlled = data as ILocalizedControlled; - if (localizedControlled != null) + if (data is ILocalizedControlled localizedControlled) { localizedControlled.SourceCultureName = LocalizationScopeManager.MapByType(interfaceType).Name; } - if (data is IVersioned) + if (data is IVersioned versionedData) { - UpdateVersionId((IVersioned)data); + UpdateVersionId(versionedData); } DataFacade.AddNew(data, false, true, false); // Ignore validation, this should have been done in the validation face @@ -249,13 +248,9 @@ private void UpdateVersionId(IVersioned data) return; } - if (data is IPage) + if (data is IPage page) { - var page = (IPage)data; - - Guid versionId; - - if (_pageVersionIds.TryGetValue(page.Id, out versionId)) + if (_pageVersionIds.TryGetValue(page.Id, out Guid versionId)) { page.VersionId = versionId; } @@ -266,22 +261,16 @@ private void UpdateVersionId(IVersioned data) } } - else if (data is IPagePlaceholderContent) + else if (data is IPagePlaceholderContent pagePlaceholderContent) { - Guid pageId = ((IPagePlaceholderContent)data).PageId; - Guid versionId; - - if (_pageVersionIds.TryGetValue(pageId, out versionId)) + if (_pageVersionIds.TryGetValue(pagePlaceholderContent.PageId, out Guid versionId)) { data.VersionId = versionId; } } - else if (data is IPageData) + else if (data is IPageData pageData) { - Guid pageId = ((IPageData)data).PageId; - Guid versionId; - - if (_pageVersionIds.TryGetValue(pageId, out versionId)) + if (_pageVersionIds.TryGetValue(pageData.PageId, out Guid versionId)) { data.VersionId = versionId; } @@ -681,7 +670,7 @@ private static Dictionary GetDataTypeProperties(Type type) private static bool IsObsoleteProperty(PropertyInfo propertyInfo) { - return propertyInfo.Name == "PageId" && propertyInfo.DeclaringType == typeof(IPageData); + return propertyInfo.Name == nameof(IPageData.PageId) && propertyInfo.DeclaringType == typeof(IPageData); } private static bool IsObsoleteField(DataTypeDescriptor dataTypeDescriptor, string fieldName) @@ -694,11 +683,11 @@ private static void MapReference(Type type, string propertyName, object key, out { if ((type == typeof(IImageFile) || type == typeof(IMediaFile)) && ((string)key).StartsWith("MediaArchive:") - && propertyName == "KeyPath") + && propertyName == nameof(IMediaFile.KeyPath)) { referenceType = typeof(IMediaFileData); referenceKey = new Guid(((string)key).Substring("MediaArchive:".Length)); - keyPropertyName = "Id"; + keyPropertyName = nameof(IMediaFileData.Id); return; } @@ -820,8 +809,7 @@ private void ValidateDynamicAddedType(DataType dataType) // Checking foreign key references foreach (var referenceField in dataTypeDescriptor.Fields.Where(f => f.ForeignKeyReferenceTypeName != null)) { - object propertyValue; - if (!fieldValues.TryGetValue(referenceField.Name, out propertyValue) + if (!fieldValues.TryGetValue(referenceField.Name, out object propertyValue) || propertyValue == null || (propertyValue is Guid guid && guid == Guid.Empty) || (propertyValue is string str && str == "")) diff --git a/Composite/Core/PackageSystem/PackageFragmentInstallers/DynamicDataTypePackageFragmentUninstaller.cs b/Composite/Core/PackageSystem/PackageFragmentInstallers/DynamicDataTypePackageFragmentUninstaller.cs index 80b11c2d2b..68bbf66d52 100644 --- a/Composite/Core/PackageSystem/PackageFragmentInstallers/DynamicDataTypePackageFragmentUninstaller.cs +++ b/Composite/Core/PackageSystem/PackageFragmentInstallers/DynamicDataTypePackageFragmentUninstaller.cs @@ -1,13 +1,14 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; -using Composite.Core.Extensions; -using Composite.Data.DynamicTypes; -using Composite.Data.GeneratedTypes; using Composite.C1Console.Events; +using Composite.Core.Extensions; +using Composite.Core.Types; using Composite.Core.Xml; using Composite.Data; +using Composite.Data.DynamicTypes; +using Composite.Data.GeneratedTypes; namespace Composite.Core.PackageSystem.PackageFragmentInstallers @@ -104,7 +105,7 @@ public override void Uninstall() if (flushTheSystem) { - GlobalEventSystemFacade.FlushTheSystem(true); + CodeGenerationManager.GenerateCompositeGeneratedAssembly(true); } } diff --git a/Composite/Core/WebClient/BuildManagerHelper.cs b/Composite/Core/WebClient/BuildManagerHelper.cs index f3fbde6023..687c6669a0 100644 --- a/Composite/Core/WebClient/BuildManagerHelper.cs +++ b/Composite/Core/WebClient/BuildManagerHelper.cs @@ -1,4 +1,4 @@ -using Composite.Core.IO; +using Composite.Core.IO; using System; using System.Collections.Generic; using System.Diagnostics; @@ -41,7 +41,7 @@ private static void LoadAllControls() try { const int waitSlice = 500; - for (int i = 0; i < InitializationDelay.Milliseconds / waitSlice; i++) + for (int i = 0; i < InitializationDelay.TotalMilliseconds / waitSlice; i++) { if(IsRestarting) return; Thread.Sleep(waitSlice); diff --git a/Composite/Core/WebClient/FlowMediators/ActionExecutionMediator.cs b/Composite/Core/WebClient/FlowMediators/ActionExecutionMediator.cs index 3db0ccae58..de79a66a59 100644 --- a/Composite/Core/WebClient/FlowMediators/ActionExecutionMediator.cs +++ b/Composite/Core/WebClient/FlowMediators/ActionExecutionMediator.cs @@ -1,4 +1,4 @@ -using Composite.C1Console.Actions; +using Composite.C1Console.Actions; using Composite.C1Console.Events; using Composite.C1Console.Elements; using Composite.C1Console.Security; @@ -10,20 +10,21 @@ internal static class ActionExecutionMediator { public static void ExecuteElementAction(ElementHandle elementHandle, ActionHandle actionHandle, string consoleId) { - FlowControllerServicesContainer flowServicesContainer = new FlowControllerServicesContainer(); - flowServicesContainer.AddService(new ManagementConsoleMessageService(consoleId)); - flowServicesContainer.AddService(new ElementDataExchangeService(elementHandle.ProviderName)); - flowServicesContainer.AddService(new ActionExecutionService(elementHandle.ProviderName, consoleId)); - flowServicesContainer.AddService(new ElementInformationService(elementHandle)); + var flowServicesContainer = new FlowControllerServicesContainer( + new ManagementConsoleMessageService(consoleId), + new ElementDataExchangeService(elementHandle.ProviderName), + new ActionExecutionService(elementHandle.ProviderName, consoleId), + new ElementInformationService(elementHandle) + ); FlowToken flowToken = ActionExecutorFacade.Execute(elementHandle.EntityToken, actionHandle.ActionToken, flowServicesContainer); IFlowUiDefinition uiDefinition = FlowControllerFacade.GetCurrentUiDefinition(flowToken, flowServicesContainer); - if (typeof(FlowUiDefinitionBase).IsAssignableFrom(uiDefinition.GetType())) + if (uiDefinition is FlowUiDefinitionBase flowUiDefinition) { string serializedEntityToken = EntityTokenSerializer.Serialize(elementHandle.EntityToken, true); - ViewTransitionHelper.HandleNew(consoleId, elementHandle.ProviderName, serializedEntityToken, flowToken, (FlowUiDefinitionBase)uiDefinition); + ViewTransitionHelper.HandleNew(consoleId, elementHandle.ProviderName, serializedEntityToken, flowToken, flowUiDefinition); } } @@ -31,10 +32,11 @@ public static void ExecuteElementAction(ElementHandle elementHandle, ActionHandl public static bool ExecuteElementDraggedAndDropped(ElementHandle draggedElementHandle, ElementHandle newParentdElementHandle, int dropIndex, string consoleId, bool isCopy) { - FlowControllerServicesContainer flowServicesContainer = new FlowControllerServicesContainer(); - flowServicesContainer.AddService(new ManagementConsoleMessageService(consoleId)); - flowServicesContainer.AddService(new ElementDataExchangeService(draggedElementHandle.ProviderName)); - flowServicesContainer.AddService(new ActionExecutionService(draggedElementHandle.ProviderName, consoleId)); + var flowServicesContainer = new FlowControllerServicesContainer( + new ManagementConsoleMessageService(consoleId), + new ElementDataExchangeService(draggedElementHandle.ProviderName), + new ActionExecutionService(draggedElementHandle.ProviderName, consoleId) + ); return ElementFacade.ExecuteElementDraggedAndDropped(draggedElementHandle, newParentdElementHandle, dropIndex, isCopy, flowServicesContainer); } diff --git a/Composite/Core/WebClient/FlowMediators/ActionExecutionService.cs b/Composite/Core/WebClient/FlowMediators/ActionExecutionService.cs index 1ba66e4caf..a1864b9490 100644 --- a/Composite/Core/WebClient/FlowMediators/ActionExecutionService.cs +++ b/Composite/Core/WebClient/FlowMediators/ActionExecutionService.cs @@ -1,4 +1,4 @@ -using Composite.C1Console.Actions; +using Composite.C1Console.Actions; using Composite.C1Console.Events; using Composite.C1Console.Elements; using Composite.C1Console.Security; @@ -15,26 +15,25 @@ public ActionExecutionService(string elementProviderName, string consoleId) this.ConsoleId = consoleId; } - private string ElementProviderName { get; set; } - private string ConsoleId { get; set; } + private string ElementProviderName { get; } + private string ConsoleId { get; } public void Execute(EntityToken entityToken, ActionToken actionToken, TaskManagerEvent taskManagerEvent) { - FlowControllerServicesContainer flowServicesContainer = new FlowControllerServicesContainer(); - flowServicesContainer.AddService(new ManagementConsoleMessageService(this.ConsoleId)); - flowServicesContainer.AddService(new ElementDataExchangeService(this.ElementProviderName)); - flowServicesContainer.AddService(this); + var flowServicesContainer = new FlowControllerServicesContainer( + new ManagementConsoleMessageService(this.ConsoleId), + new ElementDataExchangeService(this.ElementProviderName), + this + ); FlowToken flowToken = ActionExecutorFacade.Execute(entityToken, actionToken, flowServicesContainer, taskManagerEvent); IFlowUiDefinition uiDefinition = FlowControllerFacade.GetCurrentUiDefinition(flowToken, flowServicesContainer); - ActionResult result = new ActionResult(); - - if (typeof(FlowUiDefinitionBase).IsAssignableFrom(uiDefinition.GetType())) + if (uiDefinition is FlowUiDefinitionBase flowUiDefinition) { string serializedEntityToken = EntityTokenSerializer.Serialize(entityToken, true); - ViewTransitionHelper.HandleNew(this.ConsoleId, this.ElementProviderName, serializedEntityToken, flowToken, (FlowUiDefinitionBase)uiDefinition); + ViewTransitionHelper.HandleNew(this.ConsoleId, this.ElementProviderName, serializedEntityToken, flowToken, flowUiDefinition); } } } diff --git a/Composite/Core/WebClient/FlowMediators/WebFlowUiMediator.cs b/Composite/Core/WebClient/FlowMediators/WebFlowUiMediator.cs index a9094c9004..d047379fba 100644 --- a/Composite/Core/WebClient/FlowMediators/WebFlowUiMediator.cs +++ b/Composite/Core/WebClient/FlowMediators/WebFlowUiMediator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Web.UI; using Composite.C1Console.Actions; using Composite.C1Console.Events; @@ -26,16 +26,16 @@ public static Control GetFlowUi(FlowHandle flowHandle, string elementProviderNam Control webControl = null; string viewId = ViewTransitionHelper.MakeViewId(flowHandle.Serialize()); - FlowControllerServicesContainer flowServicesContainer = new FlowControllerServicesContainer(); - flowServicesContainer.AddService(new ActionExecutionService(elementProviderName, consoleId)); - flowServicesContainer.AddService(new ManagementConsoleMessageService(consoleId, viewId)); - flowServicesContainer.AddService(new ElementDataExchangeService(elementProviderName)); + var flowServicesContainer = new FlowControllerServicesContainer( + new ActionExecutionService(elementProviderName, consoleId), + new ManagementConsoleMessageService(consoleId, viewId), + new ElementDataExchangeService(elementProviderName) + ); FlowToken flowToken = flowHandle.FlowToken; IFlowUiDefinition flowUiDefinition = FlowControllerFacade.GetCurrentUiDefinition(flowToken, flowServicesContainer); - var formFlowUiDefinition = flowUiDefinition as FormFlowUiDefinition; - if (formFlowUiDefinition != null) + if (flowUiDefinition is FormFlowUiDefinition formFlowUiDefinition) { uiContainerName = formFlowUiDefinition.UiContainerType.ContainerName; @@ -45,15 +45,12 @@ public static Control GetFlowUi(FlowHandle flowHandle, string elementProviderNam if (string.IsNullOrEmpty(webControl.ID)) webControl.ID = "FlowUI"; - if (RuntimeInformation.TestAutomationEnabled) + if (RuntimeInformation.TestAutomationEnabled + && formFlowUiDefinition.MarkupProvider is ITestAutomationLocatorInformation testAutomationLocatorInformation) { - var testAutomationLocatorInformation = formFlowUiDefinition.MarkupProvider as ITestAutomationLocatorInformation; - if (testAutomationLocatorInformation != null) { - var htmlform = webControl.Controls.OfType().FirstOrDefault(); - if (htmlform != null) { - htmlform.Attributes.Add("data-qa", testAutomationLocatorInformation.TestAutomationLocator); - } - } + var htmlform = webControl.Controls.OfType().FirstOrDefault(); + + htmlform?.Attributes.Add("data-qa", testAutomationLocatorInformation.TestAutomationLocator); } } diff --git a/Composite/Core/WebClient/FunctionBoxRouteHandler.cs b/Composite/Core/WebClient/FunctionBoxRouteHandler.cs index a469bfa733..d0df2f4806 100644 --- a/Composite/Core/WebClient/FunctionBoxRouteHandler.cs +++ b/Composite/Core/WebClient/FunctionBoxRouteHandler.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; @@ -12,6 +12,7 @@ using Composite.C1Console.Security; using Composite.Core.Configuration; using Composite.Core.Extensions; +using Composite.Core.IO; using Composite.Core.WebClient.Renderings; @@ -39,12 +40,15 @@ public IHttpHandler GetHttpHandler(RequestContext requestContext) internal class FunctionBoxHttpHandler : HttpTaskAsyncHandler { private const int MinCharsPerDescriptionLine = 55; - private static readonly string LogTitle = typeof (FunctionBoxHttpHandler).Name; + private static readonly string LogTitle = nameof(FunctionBoxHttpHandler); public override async Task ProcessRequestAsync(HttpContext context) { if (!UserValidationFacade.IsLoggedIn()) { + context.Response.ContentType = MimeTypeInfo.Text; + context.Response.Write("No user logged in"); + context.Response.StatusCode = 401; return; } diff --git a/Composite/Core/WebClient/HttpModules/AdministrativeAuthorizationHttpModule.cs b/Composite/Core/WebClient/HttpModules/AdministrativeAuthorizationHttpModule.cs index 7e52e1fc92..9a698e2822 100644 --- a/Composite/Core/WebClient/HttpModules/AdministrativeAuthorizationHttpModule.cs +++ b/Composite/Core/WebClient/HttpModules/AdministrativeAuthorizationHttpModule.cs @@ -1,4 +1,4 @@ -using Composite.C1Console.Security; +using Composite.C1Console.Security; using Composite.Core.Application; using Composite.Core.Configuration; using Composite.Core.IO; @@ -120,7 +120,6 @@ private void context_AuthorizeRequest(object sender, EventArgs e) if (!_allowC1ConsoleRequests) { - context.Response.StatusCode = 403; context.Response.ContentType = "text/html"; string iePadding = new String('!', 512); context.Response.Write(string.Format(c1ConsoleRequestsNotAllowedHtmlTemplate, iePadding)); diff --git a/Composite/Core/WebClient/TemplatePreviewRouteHandler.cs b/Composite/Core/WebClient/TemplatePreviewRouteHandler.cs index 0f2ac37eda..3086adb894 100644 --- a/Composite/Core/WebClient/TemplatePreviewRouteHandler.cs +++ b/Composite/Core/WebClient/TemplatePreviewRouteHandler.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Web; using System.Web.Routing; using Composite.C1Console.Security; @@ -34,6 +34,9 @@ public void ProcessRequest(HttpContext context) { if (!UserValidationFacade.IsLoggedIn()) { + context.Response.ContentType = MimeTypeInfo.Text; + context.Response.Write("No user logged in"); + context.Response.StatusCode = 401; return; } @@ -49,10 +52,7 @@ public void ProcessRequest(HttpContext context) Guid pageId = Guid.Parse(p); - string filePath; - - PageTemplatePreview.PlaceholderInformation[] placeholders; - PageTemplatePreview.GetPreviewInformation(context, pageId, templateId, out filePath, out placeholders); + PageTemplatePreview.GetPreviewInformation(context, pageId, templateId, out string filePath, out _); Verify.That(C1File.Exists(filePath), "Preview file missing"); context.Response.ContentType = "image/png"; @@ -60,15 +60,12 @@ public void ProcessRequest(HttpContext context) } catch (Exception ex) { - Log.LogError(this.GetType().ToString(), ex.ToString()); + Log.LogError(nameof(TemplatePreviewHttpHandler), ex); throw; } } - public bool IsReusable - { - get { return true; } - } + public bool IsReusable => true; } } diff --git a/Composite/Core/WebClient/UrlUtils.cs b/Composite/Core/WebClient/UrlUtils.cs index 08c0e8e473..a480854840 100644 --- a/Composite/Core/WebClient/UrlUtils.cs +++ b/Composite/Core/WebClient/UrlUtils.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.IO.Compression; using System.Security.Cryptography; @@ -14,42 +14,56 @@ namespace Composite.Core.WebClient { - /// + /// /// /// [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public static class UrlUtils - { + public static class UrlUtils + { + private const char UrlEncode_EscapeCharacter = '$'; + private const char UrlEncode_SpaceReplacement = '-'; + private const char UrlEncode_SpaceReplacementReplacement = '_'; + private static readonly string _adminFolderName = "Composite"; private static readonly string _renderersFolderName = "Renderers"; private static readonly string _applicationVirtualPath; private static readonly string[] UrlStartMarkers = { "\"", "\'", "'", """ }; private static readonly string SessionUrlPrefix = "Session_"; + + /// + public static string PublicRootPath => _applicationVirtualPath; + + + /// + public static string AdminRootPath => $"{_applicationVirtualPath}/{_adminFolderName}"; + + + /// + public static string RenderersRootPath => $"{_applicationVirtualPath}/{_renderersFolderName}"; + + + /// + internal static string AdminFolderName => _adminFolderName; + + static UrlUtils() { - if (HostingEnvironment.ApplicationVirtualPath != null) - { - string appPath = HostingEnvironment.ApplicationVirtualPath; - - if (appPath.EndsWith("/") || appPath.EndsWith(@"\")) - { - appPath = appPath.Remove(appPath.Length - 1, 1); - } + string appPath = HostingEnvironment.ApplicationVirtualPath ?? ""; - _applicationVirtualPath = appPath; - } - else + if (appPath.EndsWith("/") || appPath.EndsWith(@"\")) { - _applicationVirtualPath = ""; + appPath = appPath.Remove(appPath.Length - 1, 1); } + + _applicationVirtualPath = appPath; } /// public static string ResolveAdminUrl(string adminRelativePath) { - if (adminRelativePath == null) throw new ArgumentNullException("adminRelativePath"); + if (adminRelativePath == null) throw new ArgumentNullException(nameof(adminRelativePath)); if (adminRelativePath.IndexOf('~') > -1 || adminRelativePath.StartsWith("/") ) { throw new ArgumentException("The relative URL may not be rooted or contain '~'"); @@ -59,17 +73,17 @@ public static string ResolveAdminUrl(string adminRelativePath) string checkForBackSlashes = split[0]; if (checkForBackSlashes.Contains(@"\")) { - Log.LogWarning("ResolveAdminUrl", string.Format(@"The url '{0}' contains '\' which is not allowed.", checkForBackSlashes)); + Log.LogWarning("ResolveAdminUrl", $@"The url '{checkForBackSlashes}' contains '\' which is not allowed."); } - return string.Format("{0}/{1}/{2}", _applicationVirtualPath, _adminFolderName, adminRelativePath); + return $"{_applicationVirtualPath}/{_adminFolderName}/{adminRelativePath}"; } /// public static string ResolvePublicUrl(string publicRelativePath) { - if (publicRelativePath == null) throw new ArgumentNullException("publicRelativePath"); + if (publicRelativePath == null) throw new ArgumentNullException(nameof(publicRelativePath)); if (publicRelativePath.StartsWith("/")) { @@ -81,34 +95,10 @@ public static string ResolvePublicUrl(string publicRelativePath) publicRelativePath = publicRelativePath.Remove(0, 2); } - return string.Format("{0}/{1}", _applicationVirtualPath, publicRelativePath); - } - - - /// - public static string PublicRootPath - { - get - { - return _applicationVirtualPath; - } - } - - - /// - public static string AdminRootPath - { - get - { - return string.Format("{0}/{1}", _applicationVirtualPath, _adminFolderName); - } + return $"{_applicationVirtualPath}/{publicRelativePath}"; } - /// - internal static string AdminFolderName => _adminFolderName; - - /// /// Determines whether the current request is administration console request. /// (Requests to [/virtual path]/Composite/*) @@ -142,14 +132,6 @@ internal static bool IsAdminConsoleRequest(string requestPath) || requestPath.StartsWith(UrlUtils.AdminRootPath + "/", StringComparison.OrdinalIgnoreCase); } - /// - public static string RenderersRootPath - { - get - { - return string.Format("{0}/{1}", _applicationVirtualPath, _renderersFolderName); - } - } /// public static string Combine( string path1, string path2 ) @@ -262,7 +244,7 @@ public static string ZipContent(string text) { if (text.IsNullOrEmpty()) return text; - byte[] bytes = UTF8Encoding.UTF8.GetBytes(text); + byte[] bytes = Encoding.UTF8.GetBytes(text); byte[] newBytes; @@ -379,18 +361,27 @@ public static bool TryExpandGuid(string urlPart, out Guid guid) /// public static string EncodeUrlInvalidCharacters(string value) { - const char separator = '|'; - const char spaceReplacement = '-'; - var symbolsToEncode = new Hashset(new[] { '<', '>', '*', '%', '&', '\\', '?', '/' }); - symbolsToEncode.Add(separator); - symbolsToEncode.Add(spaceReplacement); + symbolsToEncode.Add(UrlEncode_EscapeCharacter); + symbolsToEncode.Add(UrlEncode_SpaceReplacementReplacement); var sb = new StringBuilder(value.Length); foreach (var ch in value) { + if (ch == UrlEncode_SpaceReplacement) + { + sb.Append(UrlEncode_SpaceReplacementReplacement); + continue; + } + + if (ch == ' ') + { + sb.Append(UrlEncode_SpaceReplacement); + continue; + } + if (!symbolsToEncode.Contains(ch)) { sb.Append(ch); @@ -400,31 +391,34 @@ public static string EncodeUrlInvalidCharacters(string value) int code = (int)ch; Verify.That(code <= 256, "1 byte ASCII code expected"); - sb.Append(separator).Append(code.ToString("X2")); + sb.Append(UrlEncode_EscapeCharacter).Append(code.ToString("X2")); } - return sb.Replace(' ', spaceReplacement).ToString(); + return sb.ToString(); } /// public static string DecodeUrlInvalidCharacters(string value) { - const char separator = '|'; - const char spaceReplacement = '-'; - var sb = new StringBuilder(value.Length); - ; + for (int position = 0; position < value.Length; position++) { var ch = value[position]; - if (ch == spaceReplacement) + if (ch == UrlEncode_SpaceReplacement) { sb.Append(' '); continue; } - if (ch == separator && position + 2 < value.Length) + if (ch == UrlEncode_SpaceReplacementReplacement) + { + sb.Append(UrlEncode_SpaceReplacement); + continue; + } + + if (ch == UrlEncode_EscapeCharacter && position + 2 < value.Length) { var hexCode = value.Substring(position + 1, 2).ToLowerInvariant(); const string hexadecimalDigits = "0123456789abcdef"; diff --git a/Composite/Core/WebClient/XsltServices.cs b/Composite/Core/WebClient/XsltServices.cs index ebf8d2e66e..d8f0335494 100644 --- a/Composite/Core/WebClient/XsltServices.cs +++ b/Composite/Core/WebClient/XsltServices.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Xml; using System.Xml.Linq; @@ -25,7 +25,7 @@ public static XslCompiledTransform GetCompiledXsltTransform(string stylesheetPat DateTime lastXsltFileWrite = C1File.GetLastWriteTime(stylesheetPath); bool compiledVersionExists = _xsltLookup.ContainsKey(stylesheetPath); - bool reloadFresh = (DateTime.Now - lastXsltFileWrite).Minutes < 30; + bool reloadFresh = (DateTime.Now - lastXsltFileWrite).TotalMinutes < 30; if (compiledVersionExists == false || lastXsltFileWrite > _xsltFileTimestamps[stylesheetPath] || reloadFresh) { diff --git a/Composite/Data/Caching/CachedTable.cs b/Composite/Data/Caching/CachedTable.cs index e66695ace2..2056377248 100644 --- a/Composite/Data/Caching/CachedTable.cs +++ b/Composite/Data/Caching/CachedTable.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace Composite.Data.Caching @@ -51,6 +51,7 @@ internal override bool Add(IEnumerable dataset) newTable.AddRange(toAdd); _items = newTable; + _rowsByKey = null; // Can be optimized as well return true; } diff --git a/Composite/Data/Caching/DataCachingFacade.cs b/Composite/Data/Caching/DataCachingFacade.cs index a2b1c73a73..d85d36d753 100644 --- a/Composite/Data/Caching/DataCachingFacade.cs +++ b/Composite/Data/Caching/DataCachingFacade.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; @@ -282,16 +282,16 @@ internal static void UpdateCachedTables( internal static void ClearCache(Type interfaceType, DataScopeIdentifier dataScopeIdentifier, CultureInfo localizationScope) { - TypeData typeData; - if (!_cachedData.TryGetValue(interfaceType, out typeData)) return; + if (!_cachedData.TryGetValue(interfaceType, out TypeData typeData)) return; dataScopeIdentifier = dataScopeIdentifier ?? DataScopeManager.MapByType(interfaceType); - localizationScope = localizationScope ?? LocalizationScopeManager.MapByType(interfaceType); + localizationScope = !DataLocalizationFacade.IsLocalized(interfaceType) + ? CultureInfo.InvariantCulture + : (localizationScope ?? LocalizationScopeManager.CurrentLocalizationScope); var key = new Tuple(dataScopeIdentifier, localizationScope); - CachedTable value; - typeData.TryRemove(key, out value); + typeData.TryRemove(key, out _); } diff --git a/Composite/Data/DynamicTypes/DataTypeDescriptor.cs b/Composite/Data/DynamicTypes/DataTypeDescriptor.cs index 790b59b8be..358f1b9eaa 100644 --- a/Composite/Data/DynamicTypes/DataTypeDescriptor.cs +++ b/Composite/Data/DynamicTypes/DataTypeDescriptor.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; @@ -548,6 +548,7 @@ public DataTypeDescriptor Clone() BuildNewHandlerTypeName = this.BuildNewHandlerTypeName, LabelFieldName = this.LabelFieldName, InternalUrlPrefix = this.InternalUrlPrefix, + Searchable = this.Searchable }; foreach (DataTypeAssociationDescriptor dataTypeAssociationDescriptor in this.DataAssociations) diff --git a/Composite/GlobalInitializerFacade.cs b/Composite/GlobalInitializerFacade.cs index 5965aa4030..37ca291adf 100644 --- a/Composite/GlobalInitializerFacade.cs +++ b/Composite/GlobalInitializerFacade.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -32,14 +32,14 @@ namespace Composite { - /// + /// /// /// [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public static class GlobalInitializerFacade { - private static readonly string LogTitle = "RGB(194, 252, 131)GlobalInitializerFacade"; - private static readonly string LogTitleNormal = "GlobalInitializerFacade"; + private static readonly string LogTitle = "RGB(194, 252, 131)" + nameof(GlobalInitializerFacade); + private static readonly string LogTitleNormal = nameof(GlobalInitializerFacade); private static bool _coreInitialized; private static bool _initializing; @@ -48,7 +48,7 @@ public static class GlobalInitializerFacade private static bool _preInitHandlersRunning; private static Exception _exceptionThrownDuringInitialization; private static DateTime _exceptionThrownDuringInitializationTimeStamp; - private static int _fatalErrorFlushCount = 0; + private static int _fatalErrorFlushCount; private static readonly ReaderWriterLock _readerWriterLock = new ReaderWriterLock(); private static Thread _hookingFacadeThread; // This is used to wait on the the thread if a reinitialize is issued private static Exception _hookingFacadeException; // This will hold the exception from the before the reinitialize was issued @@ -57,13 +57,14 @@ public static class GlobalInitializerFacade /// - public static bool DynamicTypesGenerated { get; private set; } + [Obsolete("Not used")] + public static bool DynamicTypesGenerated => false; /// - public static bool SystemCoreInitializing { get { return _initializing; } } + public static bool SystemCoreInitializing => _initializing; /// - public static bool SystemCoreInitialized { get { return _coreInitialized; } } + public static bool SystemCoreInitialized => _coreInitialized; /// /// This is true during a total flush of the system (re-initialize). @@ -96,15 +97,12 @@ public static void InitializeTheSystem() { Verify.That(!_preInitHandlersRunning, "DataFacade related methods should not be called in OnBeforeInitialize() method of a startup handler. Please move the code to OnInitialized() instead."); - // if (AppDomain.CurrentDomain.Id == 3) SimpleDebug.AddEntry(string.Format("INITIALIZING {0} {1} {2}", Thread.CurrentThread.ManagedThreadId, _initializing, _coreInitialized)); - - if (_exceptionThrownDuringInitialization != null) { TimeSpan timeSpan = DateTime.Now - _exceptionThrownDuringInitializationTimeStamp; if (timeSpan < TimeSpan.FromMinutes(5.0)) { - Log.LogCritical(LogTitleNormal, "Exception recorded:" + timeSpan + " ago"); + Log.LogCritical(LogTitleNormal, $"Exception recorded: {timeSpan} ago"); throw new Exception("Failed to initialize the system", _exceptionThrownDuringInitialization); } @@ -114,7 +112,7 @@ public static void InitializeTheSystem() if (!_initializing && !_coreInitialized) { - using (GlobalInitializerFacade.CoreLockScope) + using (CoreLockScope) { if (!_initializing && !_coreInitialized) { @@ -298,7 +296,7 @@ private static void DoInitialize() int executionTime = Environment.TickCount - startTime; - Log.LogVerbose(LogTitle, "Done initializing of the system core. ({0} ms)".FormatWith(executionTime)); + Log.LogVerbose(LogTitle, $"Done initializing of the system core. ({executionTime} ms)"); } @@ -345,7 +343,7 @@ internal static void ReinitializeTheSystem(RunInWriterLockScopeDelegate runInWri } } - using (GlobalInitializerFacade.CoreLockScope) + using (CoreLockScope) { IsReinitializingTheSystem = true; @@ -384,7 +382,7 @@ internal static void ReinitializeTheSystem(RunInWriterLockScopeDelegate runInWri private static void EnsureHookingFacade(object timeSpanToDelayStart) { // NOTE: Condition is made for unit-testing - if (System.Web.Hosting.HostingEnvironment.IsHosted) + if (HostingEnvironment.IsHosted) { var kvp = (KeyValuePair)timeSpanToDelayStart; _hookingFacadeException = null; @@ -393,7 +391,7 @@ private static void EnsureHookingFacade(object timeSpanToDelayStart) try { - using (GlobalInitializerFacade.CoreIsInitializedScope) + using (CoreIsInitializedScope) { using (ThreadDataManager.EnsureInitialize()) { @@ -417,11 +415,7 @@ public static void WaitUntilAllIsInitialized() { using (CoreIsInitializedScope) { - Thread hookingFacadeThread = _hookingFacadeThread; - if (hookingFacadeThread != null) - { - hookingFacadeThread.Join(); - } + _hookingFacadeThread?.Join(); } } @@ -432,7 +426,7 @@ public static void FatalResetTheSystem() { Log.LogWarning(LogTitle, "Unhandled error occurred, reinitializing the system!"); - ReinitializeTheSystem(delegate() { _fatalErrorFlushCount++; GlobalEventSystemFacade.FlushTheSystem(); }); + ReinitializeTheSystem(delegate { _fatalErrorFlushCount++; GlobalEventSystemFacade.FlushTheSystem(); }); } @@ -440,7 +434,7 @@ public static void FatalResetTheSystem() /// public static void UninitializeTheSystem(RunInWriterLockScopeDelegate runInWriterLockScopeDelegate) { - using (GlobalInitializerFacade.CoreLockScope) + using (CoreLockScope) { using (new LogExecutionTime(LogTitle, "Uninitializing the system")) { @@ -509,13 +503,14 @@ private static void DoAutoInstallPackages() string directory = PathUtil.Resolve(GlobalSettingsFacade.AutoPackageInstallDirectory); if (C1Directory.Exists(directory)) { - Log.LogVerbose(LogTitle, string.Format("Installing packages from: {0}", directory)); + Log.LogVerbose(LogTitle, $"Installing packages from: {directory}"); zipFiles.AddRange(C1Directory.GetFiles(directory, "*.zip") + .OrderBy(f => f) .Select(f => new AutoInstallPackageInfo { FilePath = f, ToBeDeleted = true })); } else { - Log.LogVerbose(LogTitle, string.Format("Auto install directory not found: {0}", directory)); + Log.LogVerbose(LogTitle, $"Auto install directory not found: {directory}"); } if (RuntimeInformation.IsDebugBuild) @@ -523,7 +518,7 @@ private static void DoAutoInstallPackages() string workflowTestDir = Path.Combine(PathUtil.Resolve(GlobalSettingsFacade.AutoPackageInstallDirectory), "WorkflowTesting"); if (C1Directory.Exists(workflowTestDir)) { - Log.LogVerbose(LogTitle, string.Format("Installing packages from: {0}", workflowTestDir)); + Log.LogVerbose(LogTitle, $"Installing packages from: {workflowTestDir}"); zipFiles.AddRange(C1Directory.GetFiles(workflowTestDir, "*.zip") .OrderBy(f => f) .Select(f => new AutoInstallPackageInfo { FilePath = f, ToBeDeleted = false })); @@ -537,7 +532,7 @@ private static void DoAutoInstallPackages() { using (Stream zipFileStream = C1File.OpenRead(zipFile.FilePath)) { - Log.LogVerbose(LogTitle, "Installing package: " + zipFile.FilePath); + Log.LogVerbose(LogTitle, $"Installing package: {zipFile.FilePath}"); PackageManagerInstallProcess packageManagerInstallProcess = PackageManager.Install(zipFileStream, true); @@ -601,7 +596,7 @@ public static void ValidateIsOnlyCalledFromGlobalInitializerFacade(StackTrace st if (methodInfo.DeclaringType != typeof(GlobalInitializerFacade)) { - throw new SystemException(string.Format("The method {0} may only be called by the {1}", stackTrace.GetFrame(1).GetMethod(), typeof(GlobalInitializerFacade))); + throw new SystemException($"The method {methodInfo} may only be called by the {typeof(GlobalInitializerFacade)}"); } } @@ -624,7 +619,7 @@ private static void LogErrors(IEnumerable packa private static void OnFlushEvent(FlushEventArgs args) { - using (GlobalInitializerFacade.CoreLockScope) + using (CoreLockScope) { _coreInitialized = false; } @@ -642,7 +637,7 @@ private static void OnFlushEvent(FlushEventArgs args) /// public static void RunInWriterLockScope(RunInWriterLockScopeDelegate runInWriterLockScopeDelegate) { - using (GlobalInitializerFacade.CoreLockScope) + using (CoreLockScope) { runInWriterLockScopeDelegate(); } @@ -657,9 +652,9 @@ internal static IDisposable CoreLockScope get { var stackTrace = new StackTrace(); - StackFrame stackFrame = stackTrace.GetFrame(1); - string lockSource = string.Format("{0}.{1}", stackFrame.GetMethod().DeclaringType.Name, stackFrame.GetMethod().Name); - return new LockerToken(true, lockSource); + var method = stackTrace.GetFrame(1).GetMethod(); + + return new LockerToken(true, $"{method.DeclaringType.Name}.{method.Name}"); } } @@ -688,13 +683,7 @@ public static IDisposable CoreIsInitializedScope /// Using this in a using-statement will ensure that the code is /// executed AFTER any existing locks has been released. /// - public static IDisposable CoreNotLockedScope - { - get - { - return new LockerToken(); - } - } + public static IDisposable CoreNotLockedScope => new LockerToken(); private static void AcquireReaderLock() @@ -746,8 +735,8 @@ private static void ReleaseWriterLock() { int threadId = Thread.CurrentThread.ManagedThreadId; - if ((_threadLocking.WriterLocksPerThreadId[threadId] == 1) && - (_threadLocking.LockCookiesPerThreadId.ContainsKey(threadId))) + if (_threadLocking.WriterLocksPerThreadId[threadId] == 1 && + _threadLocking.LockCookiesPerThreadId.ContainsKey(threadId)) { LockCookie lockCookie = _threadLocking.LockCookiesPerThreadId[threadId]; @@ -802,7 +791,7 @@ internal LockerToken(bool writerLock, string lockSource) return; } - Verify.ArgumentCondition(!lockSource.IsNullOrEmpty(), "lockSource", "Write locks must be obtained with a string identifying the source"); + Verify.ArgumentCondition(!lockSource.IsNullOrEmpty(), nameof(lockSource), "Write locks must be obtained with a string identifying the source"); #region Logging the action @@ -821,7 +810,7 @@ where sf.GetMethod().DeclaringType.Assembly.FullName.Contains("Composite.Test") methodInfo = ", Method:" + stackFrame.GetMethod().Name; } } - Log.LogVerbose(LogTitle, "Writer Lock Acquired (Managed Thread ID: {0}, Source: {1}{2})".FormatWith(Thread.CurrentThread.ManagedThreadId, lockSource, methodInfo)); + Log.LogVerbose(LogTitle, $"Writer Lock Acquired (Managed Thread ID: {Thread.CurrentThread.ManagedThreadId}, Source: {lockSource}{methodInfo})"); #endregion Logging the action @@ -859,7 +848,7 @@ where sf.GetMethod().DeclaringType.Assembly.FullName.Contains("Composite.Test") methodInfo = ", Method: " + stackFrame.GetMethod().Name; } } - Log.LogVerbose(LogTitle, "Writer Lock Releasing (Managed Thread ID: {0}, Source: {1}{2})".FormatWith(Thread.CurrentThread.ManagedThreadId, _lockSource, methodInfo)); + Log.LogVerbose(LogTitle, $"Writer Lock Releasing (Managed Thread ID: {Thread.CurrentThread.ManagedThreadId}, Source: {_lockSource}{methodInfo})"); #endregion diff --git a/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs b/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs index e544be056f..3e79480bfd 100644 --- a/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs +++ b/Composite/Plugins/Data/DataProviders/MSSqlServerDataProvider/Foundation/SqlDataProviderStoreManipulator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; @@ -411,9 +411,7 @@ private void AlterStore(UpdateDataTypeDescriptor updateDataTypeDescriptor, DataT if (!tables.Contains(originalTableName)) { throw new InvalidOperationException( - string.Format( - "Unable to alter data type store. The database does not contain expected table {0}", - originalTableName)); + $"Unable to alter data type store for type '{changeDescriptor.AlteredType.GetFullInterfaceName()}'. The database does not contain expected table '{originalTableName}'"); } @@ -429,7 +427,7 @@ private void AlterStore(UpdateDataTypeDescriptor updateDataTypeDescriptor, DataT { if (tables.Contains(alteredTableName)) throw new InvalidOperationException( - $"Can not rename table to {alteredTableName}. A table with that name already exists"); + $"Can not rename table '{originalTableName}' to '{alteredTableName}'. A table with that name already exists"); RenameTable(originalTableName, alteredTableName); } diff --git a/Composite/Plugins/Data/DataProviders/XmlDataProvider/XmlDataProvider_CRUD.cs b/Composite/Plugins/Data/DataProviders/XmlDataProvider/XmlDataProvider_CRUD.cs index 89d9b382f9..1356a06394 100644 --- a/Composite/Plugins/Data/DataProviders/XmlDataProvider/XmlDataProvider_CRUD.cs +++ b/Composite/Plugins/Data/DataProviders/XmlDataProvider/XmlDataProvider_CRUD.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -6,7 +6,6 @@ using System.Xml.Linq; using Composite.Core; using Composite.Core.Collections.Generic; -using Composite.Core.Extensions; using Composite.Core.Threading; using Composite.Data; using Composite.Data.Caching; @@ -116,16 +115,18 @@ public void Update(IEnumerable dataset) XElement element = index[dataId]; - Verify.ArgumentCondition(element != null, "dataset", "No data element corresponds to the given data id"); + if (element == null) + { + throw new ArgumentException($"Cannot update a data item, no data element corresponds to the given data id: '{dataId.Serialize(null)}'; Type: '{type}'; DataScope: '{dataScope}'; Culture: '{culture}'", nameof(dataset)); + } IXElementWrapper wrapper = data as IXElementWrapper; - Verify.ArgumentCondition(wrapper != null, "dataset", "The type of data was expected to be of type {0}".FormatWith(typeof(IXElementWrapper))); + Verify.ArgumentCondition(wrapper != null, nameof(dataset), $"The type of data was expected to be of type {typeof(IXElementWrapper)}"); XElement updatedElement = CreateUpdatedXElement(wrapper, element); validatedFileRecords.Add(data.DataSourceId, fileRecord); validatedElements.Add(data.DataSourceId, updatedElement); - } foreach (var key in validatedElements.Keys) @@ -133,7 +134,6 @@ public void Update(IEnumerable dataset) FileRecord fileRecord = validatedFileRecords[key]; fileRecord.Dirty = true; fileRecord.RecordSet.Index[key.DataId] = validatedElements[key]; - } XmlDataProviderDocumentCache.SaveChanges(); @@ -212,17 +212,18 @@ public void Delete(IEnumerable dataSourceIds) // verify phase foreach (DataSourceId dataSourceId in dataSourceIds) { - Verify.ArgumentCondition(dataSourceId != null, "dataSourceIds", "The enumeration may not contain null values"); + Verify.ArgumentCondition(dataSourceId != null, nameof(dataSourceIds), "The enumeration may not contain null values"); XmlDataTypeStore dataTypeStore = _xmlDataTypeStoresContainer.GetDataTypeStore(dataSourceId.InterfaceType); var dataScope = dataSourceId.DataScopeIdentifier; var culture = dataSourceId.LocaleScope; var type = dataSourceId.InterfaceType; + var dataId = dataSourceId.DataId; var dataTypeStoreScope = dataTypeStore.GetDataScope(dataScope, culture, type); - if (dataTypeStore.Helper._DataIdType != dataSourceId.DataId.GetType()) + if (dataTypeStore.Helper._DataIdType != dataId.GetType()) { throw new ArgumentException("Only data ids from this provider is allowed to be deleted on on the provider"); } @@ -231,7 +232,10 @@ public void Delete(IEnumerable dataSourceIds) var index = fileRecord.RecordSet.Index; - Verify.ArgumentCondition(index.ContainsKey(dataSourceId.DataId), "No data element corresponds to the given data id", "dataSourceIds"); + if (!index.ContainsKey(dataId)) + { + throw new ArgumentException($"Cannot delete a data item, no data element corresponds to the given data id: '{dataId.Serialize(null)}'; Type: '{type}'; DataScope: '{dataScope}'; Culture: '{culture}'", nameof(dataSourceIds)); + } validated.Add(dataSourceId, fileRecord); } diff --git a/Composite/Plugins/Elements/ElementProviders/PackageElementProvider/PackageElementProvider.cs b/Composite/Plugins/Elements/ElementProviders/PackageElementProvider/PackageElementProvider.cs index 1fc54d17b0..323a2e4dfc 100644 --- a/Composite/Plugins/Elements/ElementProviders/PackageElementProvider/PackageElementProvider.cs +++ b/Composite/Plugins/Elements/ElementProviders/PackageElementProvider/PackageElementProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Composite.Data; @@ -12,7 +12,6 @@ using Composite.C1Console.Workflow; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder; -using Composite.Core.Extensions; namespace Composite.Plugins.Elements.ElementProviders.PackageElementProvider { @@ -50,7 +49,7 @@ internal sealed class PackageElementProvider : IHooklessElementProvider, IAuxili private static ResourceHandle AddPackageSourceIcon = GetIconHandle("package-add-source"); private static ResourceHandle DeletePackageSourceIcon = GetIconHandle("package-delete-source"); - private static PermissionType[] ActionPermissions = new PermissionType[] { PermissionType.Administrate, PermissionType.Configure }; + private static PermissionType[] ActionPermissions = { PermissionType.Administrate, PermissionType.Configure }; private static readonly ActionGroup PrimaryActionGroup = new ActionGroup(ActionGroupPriority.PrimaryHigh); @@ -113,37 +112,33 @@ private static void AddInstallLocalPackageAction(Element element) public IEnumerable GetChildren(EntityToken entityToken, SearchToken seachToken) { - if ((entityToken is PackageElementProviderRootEntityToken)) + if (entityToken is PackageElementProviderRootEntityToken) { return GetRootChildren(seachToken); } - if ((entityToken is PackageElementProviderAvailablePackagesFolderEntityToken)) + if (entityToken is PackageElementProviderAvailablePackagesFolderEntityToken) { return GetAvailablePackagesFolderChildren(seachToken); } - if ((entityToken is PackageElementProviderAvailablePackagesGroupFolderEntityToken)) + if (entityToken is PackageElementProviderAvailablePackagesGroupFolderEntityToken availableGroupEntityToken) { - var castedToken = entityToken as PackageElementProviderAvailablePackagesGroupFolderEntityToken; - - return GetAvailablePackageGroupFolderChildren(castedToken.GroupName, seachToken); + return GetAvailablePackageGroupFolderChildren(availableGroupEntityToken.GroupName, seachToken); } - if ((entityToken is PackageElementProviderInstalledPackageFolderEntityToken)) + if (entityToken is PackageElementProviderInstalledPackageFolderEntityToken) { return GetInstalledPackageFolderChildren(seachToken); } - if ((entityToken is PackageElementProviderPackageSourcesFolderEntityToken)) + if (entityToken is PackageElementProviderPackageSourcesFolderEntityToken) { return GetPackageSourcesFolderChildren(seachToken); } - if ((entityToken is PackageElementProviderInstalledPackageLocalPackagesFolderEntityToken)) + if (entityToken is PackageElementProviderInstalledPackageLocalPackagesFolderEntityToken) { return GetInstalledLocalPackagesFolderChildren(seachToken); } - if ((entityToken is PackageElementProviderInstalledPackageGroupFolderEntityToken)) + if (entityToken is PackageElementProviderInstalledPackageGroupFolderEntityToken installedGroupEntityToken) { - var castedToken = entityToken as PackageElementProviderInstalledPackageGroupFolderEntityToken; - - return GetInstalledPackageGroupFolderChildren(castedToken.GroupName, seachToken); + return GetInstalledPackageGroupFolderChildren(installedGroupEntityToken.GroupName, seachToken); } throw new InvalidOperationException("Unexpected entity token type: " + entityToken.GetType()); @@ -153,16 +148,16 @@ public IEnumerable GetChildren(EntityToken entityToken, SearchToken sea public Dictionary> GetParents(IEnumerable entityTokens) { - Dictionary> result = new Dictionary>(); + var result = new Dictionary>(); foreach (EntityToken entityToken in entityTokens) { - DataEntityToken dataEntityToken = entityToken as DataEntityToken; + var dataEntityToken = (DataEntityToken) entityToken ; Type type = dataEntityToken.InterfaceType; if (type != typeof(IPackageServerSource)) continue; - PackageElementProviderPackageSourcesFolderEntityToken newEntityToken = new PackageElementProviderPackageSourcesFolderEntityToken(); + var newEntityToken = new PackageElementProviderPackageSourcesFolderEntityToken(); result.Add(entityToken, new EntityToken[] { newEntityToken }); } @@ -222,7 +217,7 @@ private IEnumerable GetRootChildren(SearchToken seachToken) { Label = StringResourceSystemFacade.GetString("Composite.Plugins.PackageElementProvider", "PackageSourcesFolderLabel"), ToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.PackageElementProvider", "PackageSourcesFolderToolTip"), - HasChildren = DataFacade.GetData().Count() > 0, + HasChildren = DataFacade.GetData().Any(), Icon = PackageSourcesClosedIcon, OpenedIcon = PackageSourcesOpenedIcon }; @@ -309,7 +304,7 @@ orderby description.Name { Label = StringResourceSystemFacade.GetString("Composite.Plugins.PackageElementProvider", "ViewAvailableInformationLabel"), ToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.PackageElementProvider", "ViewAvailableInformationToolTip"), - Icon = ViewInstalledInformationIcon, + Icon = ViewAvailableInformationIcon, Disabled = false, ActionLocation = new ActionLocation { @@ -402,13 +397,15 @@ orderby a.Url foreach (IPackageServerSource packageServerSource in packageServerSources) { - Element element = new Element(_context.CreateElementHandle(packageServerSource.GetDataEntityToken())); - element.VisualData = new ElementVisualizedData + var element = new Element(_context.CreateElementHandle(packageServerSource.GetDataEntityToken())) { - Label = packageServerSource.Url, - ToolTip = packageServerSource.Url, - HasChildren = false, - Icon = PackageSourceItemClosedIcon + VisualData = new ElementVisualizedData + { + Label = packageServerSource.Url, + ToolTip = packageServerSource.Url, + HasChildren = false, + Icon = PackageSourceItemClosedIcon + } }; element.AddAction(new ElementAction(new ActionHandle(new WorkflowActionToken(WorkflowFacade.GetWorkflowType("Composite.Plugins.Elements.ElementProviders.PackageElementProvider.DeletePackageSourceWorkflow"), new PermissionType[] { PermissionType.Administrate }))) @@ -435,30 +432,41 @@ orderby a.Url } - private IEnumerable GetInstalledLocalPackagesFolderChildren(SearchToken seachToken) + { + return GetInstalledPackagesElements(package => package.IsLocalInstalled); + } + + private IEnumerable GetInstalledPackageGroupFolderChildren(string groupName, SearchToken seachToken) + { + return GetInstalledPackagesElements(package => package.GroupName == groupName && !package.IsLocalInstalled); + } + + + private IEnumerable GetInstalledPackagesElements(Predicate filter) { IEnumerable installedPackageInformations = from info in PackageManager.GetInstalledPackages() - where info.IsLocalInstalled + where filter(info) orderby info.Name select info; - var allServerPackages = PackageSystemServices.GetAllAvailablePackages(); + var serverPackagesPreviewUrls = PackageSystemServices.GetAllAvailablePackages() + .Where(p => !string.IsNullOrEmpty(p.ConsoleBrowserUrl)) + .GroupBy(p => p.Id) + .ToDictionary(group => group.Key, group => group.First().ConsoleBrowserUrl); - foreach (InstalledPackageInformation installedPackageInformation in installedPackageInformations) + foreach (var installedPackageInformation in installedPackageInformations) { - Element element = new Element(_context.CreateElementHandle(new PackageElementProviderInstalledPackageItemEntityToken( + var element = new Element(_context.CreateElementHandle(new PackageElementProviderInstalledPackageItemEntityToken( installedPackageInformation.Id, installedPackageInformation.GroupName, installedPackageInformation.IsLocalInstalled, installedPackageInformation.CanBeUninstalled))); - PackageDescription serverPackageDescription = allServerPackages.Where(f => f.Id == installedPackageInformation.Id).FirstOrDefault(); - - if (serverPackageDescription != null && !string.IsNullOrEmpty(serverPackageDescription.ConsoleBrowserUrl)) + if (serverPackagesPreviewUrls.TryGetValue(installedPackageInformation.Id, out var previewUrl)) { - element.PropertyBag.Add("BrowserUrl", serverPackageDescription.ConsoleBrowserUrl); + element.PropertyBag.Add("BrowserUrl", previewUrl); element.PropertyBag.Add("BrowserToolingOn", "false"); } @@ -506,63 +514,6 @@ private ResourceHandle GetIconForPackageItem(Guid packageId) } - private IEnumerable GetInstalledPackageGroupFolderChildren(string groupName, SearchToken seachToken) - { - IEnumerable installedPackageInformations = - from info in PackageManager.GetInstalledPackages() - where info.GroupName == groupName && - info.IsLocalInstalled == false - orderby info.Name - select info; - - var allServerPackages = PackageSystemServices.GetAllAvailablePackages(); - - foreach (InstalledPackageInformation installedPackageInformation in installedPackageInformations) - { - Element element = new Element(_context.CreateElementHandle(new PackageElementProviderInstalledPackageItemEntityToken( - installedPackageInformation.Id, - installedPackageInformation.GroupName, - installedPackageInformation.IsLocalInstalled, - installedPackageInformation.CanBeUninstalled))); - - PackageDescription serverPackageDescription = allServerPackages.Where(f => f.Id == installedPackageInformation.Id).FirstOrDefault(); - - if (serverPackageDescription != null && !string.IsNullOrEmpty(serverPackageDescription.ConsoleBrowserUrl)) - { - element.PropertyBag.Add("BrowserUrl", serverPackageDescription.ConsoleBrowserUrl); - element.PropertyBag.Add("BrowserToolingOn", "false"); - } - - element.VisualData = new ElementVisualizedData - { - Label = installedPackageInformation.Name, - ToolTip = installedPackageInformation.Name, - HasChildren = false, - Icon = GetIconForPackageItem(installedPackageInformation.Id), - }; - - element.AddAction(new ElementAction(new ActionHandle(new WorkflowActionToken(WorkflowFacade.GetWorkflowType("Composite.Plugins.Elements.ElementProviders.PackageElementProvider.ViewInstalledPackageInfoWorkflow"), ActionPermissions))) - { - VisualData = new ActionVisualizedData - { - Label = StringResourceSystemFacade.GetString("Composite.Plugins.PackageElementProvider", "ViewInstalledInformationLabel"), - ToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.PackageElementProvider", "ViewInstalledInformationToolTip"), - Icon = ViewInstalledInformationIcon, - Disabled = false, - ActionLocation = new ActionLocation - { - ActionType = ActionType.Edit, - IsInFolder = false, - IsInToolbar = true, - ActionGroup = PrimaryActionGroup - } - - } - }); - - yield return element; - } - } diff --git a/Composite/Plugins/Forms/WebChannel/UiControlFactories/TemplatedSelectorUiControlFactory.cs b/Composite/Plugins/Forms/WebChannel/UiControlFactories/TemplatedSelectorUiControlFactory.cs index 7dcb4088c8..67993e959c 100644 --- a/Composite/Plugins/Forms/WebChannel/UiControlFactories/TemplatedSelectorUiControlFactory.cs +++ b/Composite/Plugins/Forms/WebChannel/UiControlFactories/TemplatedSelectorUiControlFactory.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Configuration; @@ -359,7 +359,7 @@ private object GetPropertyValue(object @object, string propertyName, ref Type la Verify.IsNotNull(lastUsedPropertyInfo, "Malformed Selection configuration. The Selected binding type '{0}' does not have a property named '{1}", @object.GetType().FullName, propertyName); } - return lastUsedPropertyInfo.GetValue(@object, null).ToString(); + return (lastUsedPropertyInfo.GetValue(@object, null) ?? "(null)").ToString(); } /// diff --git a/Composite/Plugins/Functions/WidgetFunctionProviders/StandardWidgetFunctionProvider/String/HierarchicalSelectorWidgetFunction.cs b/Composite/Plugins/Functions/WidgetFunctionProviders/StandardWidgetFunctionProvider/String/HierarchicalSelectorWidgetFunction.cs index 2a59f42d50..957dc6fa4a 100644 --- a/Composite/Plugins/Functions/WidgetFunctionProviders/StandardWidgetFunctionProvider/String/HierarchicalSelectorWidgetFunction.cs +++ b/Composite/Plugins/Functions/WidgetFunctionProviders/StandardWidgetFunctionProvider/String/HierarchicalSelectorWidgetFunction.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -60,7 +60,7 @@ private void SetParameterProfiles() new ConstantValueProvider(false), StandardWidgetFunctions.GetBoolSelectorWidget("Yes, auto select parents.", "No, only one selection on click."), null, - "Auto select children", new HelpDefinition("When true a selection will automatically select all ancestor elements in the hierarchy."))); + "Auto select parents", new HelpDefinition("When true a selection will automatically select all ancestor elements in the hierarchy."))); } diff --git a/Composite/Plugins/Routing/Pages/DefaultPageUrlProvider.cs b/Composite/Plugins/Routing/Pages/DefaultPageUrlProvider.cs index 03d982189c..3a0ec40b3a 100644 --- a/Composite/Plugins/Routing/Pages/DefaultPageUrlProvider.cs +++ b/Composite/Plugins/Routing/Pages/DefaultPageUrlProvider.cs @@ -301,33 +301,30 @@ public PageUrlData ParseUrl(string relativeUrl, UrlSpace urlSpace, out UrlKind u var urlBuilder = new UrlBuilder(relativeUrl); // Structure of a public url: - // http://[/ApplicationVirtualPath]{/languageCode}[/Path to a page][/c1mode(unpublished)][/c1mode(relative)][UrlSuffix]{/PathInfo} - + // http[s]://[/]{/}[/][/c1mode(unpublished)][/c1mode(relative)][][/] string filePathAndPathInfo = HttpUtility.UrlDecode(urlBuilder.FullPath); - filePathAndPathInfo = RemoveUrlMarkers(filePathAndPathInfo, urlSpace); + filePathAndPathInfo = RemoveForceRelativeUrlMarker(filePathAndPathInfo, urlSpace); + filePathAndPathInfo = ParseAndRemovePublicationScopeMarker(filePathAndPathInfo, out PublicationScope publicationScope); + + CultureInfo locale; string pathWithoutLanguageCode; IHostnameBinding hostnameBinding = urlSpace.ForceRelativeUrls ? null : GetHostnameBindings().FirstOrDefault(b => b.Hostname == urlSpace.Hostname); - CultureInfo locale = GetCultureInfo(filePathAndPathInfo, hostnameBinding, out pathWithoutLanguageCode); - if (locale == null) + if (hostnameBinding != null && filePathAndPathInfo == "/") { - urlKind = UrlKind.Undefined; - return null; + pathWithoutLanguageCode = "/"; + locale = CultureInfo.GetCultureInfo(hostnameBinding.Culture); } - - var publicationScope = PublicationScope.Published; - - if (filePathAndPathInfo.Contains(UrlMarker_Unpublished)) + else { - publicationScope = PublicationScope.Unpublished; - - pathWithoutLanguageCode = pathWithoutLanguageCode.Replace(UrlMarker_Unpublished, string.Empty); - if (pathWithoutLanguageCode == string.Empty) + locale = GetCultureInfo(filePathAndPathInfo, hostnameBinding, out pathWithoutLanguageCode); + if (locale == null) { - pathWithoutLanguageCode = "/"; + urlKind = UrlKind.Undefined; + return null; } } @@ -583,7 +580,7 @@ private static IEnumerable GetChildPages(Guid parentId) } - private static string RemoveUrlMarkers(string filePath, UrlSpace urlSpace) + private static string RemoveForceRelativeUrlMarker(string filePath, UrlSpace urlSpace) { if (urlSpace.ForceRelativeUrls && filePath.Contains(UrlMarker_RelativeUrl)) { @@ -598,6 +595,24 @@ private static string RemoveUrlMarkers(string filePath, UrlSpace urlSpace) return filePath; } + private static string ParseAndRemovePublicationScopeMarker(string filePath, out PublicationScope publicationScope) + { + publicationScope = PublicationScope.Published; + + if (filePath.Contains(UrlMarker_Unpublished)) + { + publicationScope = PublicationScope.Unpublished; + + filePath = filePath.Replace(UrlMarker_Unpublished, string.Empty); + if (filePath == string.Empty) + { + filePath = "/"; + } + } + + return filePath; + } + internal static CultureInfo GetCultureInfo(string requestPath, IHostnameBinding hostnameBinding, out string pathWithoutLanguageAndAppRoot) { int startIndex = requestPath.IndexOf('/', UrlUtils.PublicRootPath.Length) + 1; diff --git a/Composite/Plugins/Security/LoginSessionStores/WampContextBasedLoginSessionStore/WampContextBasedBasedLoginSessionStore.cs b/Composite/Plugins/Security/LoginSessionStores/WampContextBasedLoginSessionStore/WampContextBasedBasedLoginSessionStore.cs index f6f26a6b8d..3a55b0a7e2 100644 --- a/Composite/Plugins/Security/LoginSessionStores/WampContextBasedLoginSessionStore/WampContextBasedBasedLoginSessionStore.cs +++ b/Composite/Plugins/Security/LoginSessionStores/WampContextBasedLoginSessionStore/WampContextBasedBasedLoginSessionStore.cs @@ -31,7 +31,7 @@ public string StoredUsername { if (WampInvocationContext.Current != null) { - return WampInvocationContext.Current.InvocationDetails.AuthenticationId; + return WampInvocationContext.Current.InvocationDetails.CallerAuthenticationId; } return null; diff --git a/Composite/Properties/SharedAssemblyInfo.cs b/Composite/Properties/SharedAssemblyInfo.cs index 10265634b6..e58902ca8d 100644 --- a/Composite/Properties/SharedAssemblyInfo.cs +++ b/Composite/Properties/SharedAssemblyInfo.cs @@ -2,9 +2,9 @@ // General Information about the assemblies Composite and Composite.Workflows #if !InternalBuild -[assembly: AssemblyTitle("C1 CMS 6.4")] +[assembly: AssemblyTitle("C1 CMS 6.5")] #else -[assembly: AssemblyTitle("C1 CMS 6.4 (Internal Build)")] +[assembly: AssemblyTitle("C1 CMS 6.5 (Internal Build)")] #endif [assembly: AssemblyCompany("Orckestra Inc")] @@ -13,4 +13,4 @@ [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("6.4.*")] +[assembly: AssemblyVersion("6.5.*")] diff --git a/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs b/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs index b52d93c46a..55e19a40e4 100644 --- a/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs +++ b/Composite/Search/DocumentSources/MediaLibraryDocumentSource.cs @@ -1,11 +1,12 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using Composite.Search.Crawling; +using Composite.Core; using Composite.Core.Linq; using Composite.Data; using Composite.Data.Types; +using Composite.Search.Crawling; namespace Composite.Search.DocumentSources { @@ -58,7 +59,7 @@ public IEnumerable GetSearchDocuments(CultureInfo { Document = FromMediaFile(m), ContinuationToken = m.Id.ToString() - }); + }).Where(doc => doc.Document != null); } private SearchDocument FromMediaFile(IMediaFile mediaFile) @@ -69,14 +70,19 @@ private SearchDocument FromMediaFile(IMediaFile mediaFile) label = mediaFile.FileName; } - string documentId = mediaFile.Id.ToString(); + if(string.IsNullOrEmpty(label)) + { + Log.LogWarning(nameof(MediaLibraryDocumentSource), + $"A media file has neither FileName nor Label fields specified, Id: '{mediaFile.Id}', StoreId: '{mediaFile.StoreId}'."); + return null; + } var docBuilder = new SearchDocumentBuilder(_docBuilderExtensions); docBuilder.SetDataType(typeof(IMediaFile)); docBuilder.CrawlData(mediaFile); - return docBuilder.BuildDocument(Name, documentId, label, null, mediaFile.GetDataEntityToken()); + return docBuilder.BuildDocument(Name, mediaFile.Id.ToString(), label, null, mediaFile.GetDataEntityToken()); } } } diff --git a/Composite/packages.config b/Composite/packages.config index 47ee7dc78c..bc9f316aab 100644 --- a/Composite/packages.config +++ b/Composite/packages.config @@ -1,12 +1,11 @@ - + - @@ -15,8 +14,10 @@ - - - - + + + + + + \ No newline at end of file diff --git a/Website/App_Data/Composite/TreeDefinitions/PageType.xml b/Website/App_Data/Composite/TreeDefinitions/PageType.xml index 13b1d3a1a7..c3a25b74d6 100644 --- a/Website/App_Data/Composite/TreeDefinitions/PageType.xml +++ b/Website/App_Data/Composite/TreeDefinitions/PageType.xml @@ -2,7 +2,7 @@ - + diff --git a/Website/Composite/content/dialogs/treeselector/TreeSelectorDialogPageBinding.js b/Website/Composite/content/dialogs/treeselector/TreeSelectorDialogPageBinding.js index f5fdab68f3..271c16cd2f 100644 --- a/Website/Composite/content/dialogs/treeselector/TreeSelectorDialogPageBinding.js +++ b/Website/Composite/content/dialogs/treeselector/TreeSelectorDialogPageBinding.js @@ -223,6 +223,9 @@ TreeSelectorDialogPageBinding.prototype.handleBroadcast = function (broadcast, a if (this._parents.has(arg)) { this._treeBinding._handleCommandBroadcast(broadcast); return; + } else if (this._treeBinding.hasToken(arg)) { + this._treeBinding._handleCommandBroadcast(broadcast, arg); + return; } } break; @@ -348,7 +351,7 @@ TreeSelectorDialogPageBinding.prototype.setNode = function (node) { this._genericViewBinding.setNode(node); var generictab = this.bindingWindow.bindingMap.generictab; - generictab.containingTabBoxBinding.select(generictab); + generictab.containingTabBoxBinding.select(generictab, true); this._updateHistory(node ? node.getEntityToken() : null); this._updateBroadcasters(); this._updateAddressBar(node); diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecomponent/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecomponent/plugin.min.js index 9e80e6f8a3..283f5b15c8 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecomponent/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecomponent/plugin.min.js @@ -90,7 +90,7 @@ new function () { handler: { handleDialogResponse: function (response, result) { if (response == Dialog.RESPONSE_ACCEPT) { - var componentDocument = new DOMParser().parseFromString(result.FunctionMarkup, "text/xml"); + var componentDocument = self.parse(result.FunctionMarkup); var ffunction = self.resolver.resolve("/f:function", componentDocument); if (ffunction == null) { self._resolveParametersAndInsertHtml(componentDocument); @@ -118,12 +118,12 @@ new function () { if (ffunction != null) { - FunctionService.TryExecute(ffunction.outerHTML, function(functionExecutionResult) { + FunctionService.TryExecute(self.getMarkup(ffunction), function (functionExecutionResult) { if (functionExecutionResult.FunctionCallExecutable) { - self._insertImagTagAndContinue(ffunction, ffunction.outerHTML, componentDocument); + self._insertImagTagAndContinue(ffunction, self.getMarkup(ffunction), componentDocument); } else { self._launchUpdateDialog(ffunction, { - handleDialogResponse: function(response, result) { + handleDialogResponse: function (response, result) { if (response == Dialog.RESPONSE_ACCEPT) { self._insertImagTagAndContinue(ffunction, result, componentDocument); } else { @@ -135,19 +135,19 @@ new function () { }); } else { - self._insertResult(componentDocument.firstChild.outerHTML); + self._insertResult(self.getMarkup(componentDocument.lastChild)); } }, - + /** - * @param {string} markup + * @param {XMLElement} ffunction */ _resolveParametersAndInsertFunction: function (ffunction) { var self = this; - FunctionService.TryExecute(ffunction.outerHTML, function (functionExecutionResult) { + FunctionService.TryExecute(self.getMarkup(ffunction), function (functionExecutionResult) { if (functionExecutionResult.FunctionParamsExist) { self._launchUpdateDialog(ffunction, { handleDialogResponse: function (response, result) { @@ -182,7 +182,13 @@ new function () { if (ffunction.parentNode == componentDocument) { self._insertResult(functionhtml); } else { - ffunction.outerHTML = functionhtml; //TODO check + + if (ffunction.outerHTML) { + ffunction.outerHTML = functionhtml; + } else { + var imgfunction = self.parse(functionhtml); + ffunction.parentNode.replaceChild(imgfunction.lastChild, ffunction); + } self._resolveParametersAndInsertHtml(componentDocument); } }, @@ -197,12 +203,39 @@ new function () { /** * Launch update dialog. - * @param {string} markup + * @param {XmlElement} ffunction + * @param {DialogHandler} dialogHandler */ _launchUpdateDialog: function (ffunction, dialogHandler) { - EditorBinding.invokeFunctionEditorDialog(ffunction.outerHTML, dialogHandler, "Composite.Core.Xml.XhtmlDocument, Composite", this.editor.theme.editorBinding) + EditorBinding.invokeFunctionEditorDialog(this.getMarkup(ffunction), dialogHandler, "Composite.Core.Xml.XhtmlDocument, Composite", this.editor.theme.editorBinding) + }, + + /** + * Parse XML string into DOM document. + * @param {String} markup + * @return {XmlDocument} + */ + parse: function (markup) { + + var result = null; + if (window.DOMParser != null && window.XPathResult != null) { + result = new DOMParser().parseFromString(markup, 'text/xml'); + } else { + result = new ActiveXObject('Msxml2.DOMDocument.3.0'); + result.setProperty('SelectionLanguage', 'XPath'); + result.loadXML(markup); + } + return result; + }, + + /** + * @param {XMLElement} element + */ + getMarkup: function(element) { + return element.xml || element.outerHTML; // IE11 || Others browser } + }); // Register plugin diff --git a/Website/Composite/login.inc b/Website/Composite/login.inc index d3815a3d2c..82d4e99781 100644 --- a/Website/Composite/login.inc +++ b/Website/Composite/login.inc @@ -1,7 +1,7 @@
- + @@ -77,7 +77,7 @@

Shutting down...

- +
diff --git a/Website/Composite/scripts/source/top/core/MessageQueue.js b/Website/Composite/scripts/source/top/core/MessageQueue.js index f9b63793b8..5e0d69b35c 100644 --- a/Website/Composite/scripts/source/top/core/MessageQueue.js +++ b/Website/Composite/scripts/source/top/core/MessageQueue.js @@ -1,4 +1,4 @@ -/** +/** * MessageQueue! */ window.MessageQueue = new function () { @@ -332,13 +332,11 @@ window.MessageQueue = new function () { StageBinding.select(perspectiveElementKey) .then( function () { - StageBinding.selectBrowserTab(); EventBroadcaster.broadcast( BroadcastMessages.SYSTEMTREEBINDING_FOCUS, entityToken ); - } - ) + }); this._nextAction(); break; diff --git a/Website/Composite/scripts/source/top/ui/bindings/Binding.js b/Website/Composite/scripts/source/top/ui/bindings/Binding.js index c8b1811c4b..7199a6eb77 100644 --- a/Website/Composite/scripts/source/top/ui/bindings/Binding.js +++ b/Website/Composite/scripts/source/top/ui/bindings/Binding.js @@ -941,7 +941,8 @@ Binding.prototype.subTreeFromString = function ( markup ) { */ Binding.prototype.getProperty = function ( attname ) { - var value = this.bindingElement.getAttribute ( attname ); + var value = this.bindingElement.getAttribute ( attname.toLowerCase() ); + if ( value ) { value = Types.castFromString ( value ); } @@ -957,7 +958,7 @@ Binding.prototype.getProperty = function ( attname ) { * @param {string} attname The name of the attribute * @param {object} value The attribute value. */ -Binding.prototype.setProperty = function ( prop, value ) { +Binding.prototype.setProperty = function (attname, value ) { if ( value != null ) { @@ -969,20 +970,20 @@ Binding.prototype.setProperty = function ( prop, value ) { * This will prevent recursive calls to methods which in turn * modifies the properties of the binding. */ - if ( String ( this.bindingElement.getAttribute ( prop )) != value ) { + if ( String ( this.bindingElement.getAttribute ( attname.toLowerCase() )) != value ) { - this.bindingElement.setAttribute ( prop, value ); + this.bindingElement.setAttribute ( attname.toLowerCase(), value ); if ( this.isAttached == true ) { /* * Handle persistance. */ if ( Persistance.isEnabled && value != null ) { - if ( this._persist != null && this._persist [ prop ]) { - this._persist [ prop ] = value; + if ( this._persist != null && this._persist [ attname ]) { + this._persist [ attname ] = value; Persistance.setPersistedProperty ( this.bindingElement.id, - prop, + attname, value ); } @@ -991,14 +992,14 @@ Binding.prototype.setProperty = function ( prop, value ) { /* * Handle "setters" (methods invoked when setting the property). */ - var method = this.propertyMethodMap [ prop ]; + var method = this.propertyMethodMap [ attname ]; if ( method ) { - method.call ( this, this.getProperty ( prop )); + method.call ( this, this.getProperty ( attname )); } } } } else { - this.deleteProperty ( prop ); + this.deleteProperty ( attname ); } } @@ -1006,9 +1007,9 @@ Binding.prototype.setProperty = function ( prop, value ) { * Remove bound element attribute. * @param {string} prop The name of the attribute */ -Binding.prototype.deleteProperty = function ( prop ) { +Binding.prototype.deleteProperty = function ( attname ) { - this.bindingElement.removeAttribute ( prop ); + this.bindingElement.removeAttribute ( attname.toLowerCase() ); } /** diff --git a/Website/Composite/scripts/source/top/ui/bindings/branding/BrandSnippetBinding.js b/Website/Composite/scripts/source/top/ui/bindings/branding/BrandSnippetBinding.js index 0eb61b4868..7c114e7835 100644 --- a/Website/Composite/scripts/source/top/ui/bindings/branding/BrandSnippetBinding.js +++ b/Website/Composite/scripts/source/top/ui/bindings/branding/BrandSnippetBinding.js @@ -91,7 +91,7 @@ BrandSnippetBinding.prototype.onBindingAttach = function () { */ BrandSnippetBinding.prototype.getSnippetBrandedUrl = function () { - return BrandSnippetBinding.SHIPPETBRANDED_URL.replace("{0}", this.getProperty("snippetName")); + return BrandSnippetBinding.SHIPPETBRANDED_URL.replace("{0}", this.getProperty("snippetname")); } /** @@ -99,7 +99,7 @@ BrandSnippetBinding.prototype.getSnippetBrandedUrl = function () { */ BrandSnippetBinding.prototype.getSnippetUrl = function () { - return BrandSnippetBinding.SHIPPET_URL.replace("{0}", this.getProperty("snippetName")); + return BrandSnippetBinding.SHIPPET_URL.replace("{0}", this.getProperty("snippetname")); } /** diff --git a/Website/Composite/scripts/source/top/ui/bindings/editors/visualeditor/VisualEditorBinding.js b/Website/Composite/scripts/source/top/ui/bindings/editors/visualeditor/VisualEditorBinding.js index 07273434c2..222285487f 100644 --- a/Website/Composite/scripts/source/top/ui/bindings/editors/visualeditor/VisualEditorBinding.js +++ b/Website/Composite/scripts/source/top/ui/bindings/editors/visualeditor/VisualEditorBinding.js @@ -328,7 +328,7 @@ VisualEditorBinding.prototype.handleBroadcast = function ( broadcast, arg ) { VisualEditorBinding.superclass.handleBroadcast.call ( this, broadcast, arg ); - var windowBinding = this.getContentWindow ().bindingMap.tinywindow; + var windowBinding = this.getContentWindow().bindingMap.tinywindow; var contentWindow = windowBinding.getContentWindow (); switch ( broadcast ) { diff --git a/Website/Composite/scripts/source/top/ui/bindings/stage/StageBinding.js b/Website/Composite/scripts/source/top/ui/bindings/stage/StageBinding.js index ac1a8969f2..e36e3e9621 100644 --- a/Website/Composite/scripts/source/top/ui/bindings/stage/StageBinding.js +++ b/Website/Composite/scripts/source/top/ui/bindings/stage/StageBinding.js @@ -1,4 +1,4 @@ -StageBinding.prototype = new FocusBinding; +StageBinding.prototype = new FocusBinding; StageBinding.prototype.constructor = StageBinding; StageBinding.superclass = FocusBinding.prototype; @@ -118,6 +118,7 @@ StageBinding.select = function (perspectiveElementKey) { case BroadcastMessages.STAGEDECK_CHANGED: if (arg == perspectiveElementKey) { EventBroadcaster.unsubscribe(BroadcastMessages.STAGEDECK_CHANGED, this); + StageBinding.selectBrowserTab(); resolve(); } break; diff --git a/Website/Composite/scripts/source/top/ui/bindings/system/SystemTreeBinding.js b/Website/Composite/scripts/source/top/ui/bindings/system/SystemTreeBinding.js index 9d2e41ea3b..3eb9ed3ad9 100644 --- a/Website/Composite/scripts/source/top/ui/bindings/system/SystemTreeBinding.js +++ b/Website/Composite/scripts/source/top/ui/bindings/system/SystemTreeBinding.js @@ -114,6 +114,12 @@ function SystemTreeBinding() { * @type {string} */ this._restorableFocusHandle = null; + + /** + * Points to the parent of last treenode that was blurred + * @type {string} + */ + this._restorableFocusParentHandle = null; } @@ -217,7 +223,7 @@ SystemTreeBinding.prototype.handleAction = function (action) { case TreeNodeBinding.ACTION_ONFOCUS: case TreeNodeBinding.ACTION_ONMULTIFOCUS: this._restorableFocusHandle = null; - //this._handleSystemTreeFocus(); //Dublicate with parent + this._restorableFocusParentHandle = null; break; /** @@ -257,6 +263,10 @@ SystemTreeBinding.prototype.handleAction = function (action) { */ if (action.type == TreeNodeBinding.ACTION_BLUR) { this._restorableFocusHandle = binding.getHandle(); + var parent = binding.getParent(); + if (parent) { + this._restorableFocusParentHandle = parent.getHandle(); + } } break; @@ -314,8 +324,12 @@ SystemTreeBinding.prototype._attemptRestorableFocus = function () { if (this._treeNodeBindings.has(this._restorableFocusHandle)) { var treenode = this._treeNodeBindings.get(this._restorableFocusHandle); this.focusSingleTreeNodeBinding(treenode); + } else if (this._treeNodeBindings.has(this._restorableFocusParentHandle)) { // focused item removed + var treenode = this._treeNodeBindings.get(this._restorableFocusParentHandle); + this.focusSingleTreeNodeBinding(treenode); } this._restorableFocusHandle = null; + this._restorableFocusParentHandle = null; } /** @@ -925,6 +939,14 @@ SystemTreeBinding.prototype._invokeServerRefresh = function (token) { } } +/** + * @param {string} token + */ +SystemTreeBinding.prototype.hasToken = function (token) { + + return this._entityTokenRegistry.has(token) +} + /** * Invoke manual refresh. This was probably caused diff --git a/Website/Composite/scripts/source/top/ui/bindings/trees/TreeNodeBinding.js b/Website/Composite/scripts/source/top/ui/bindings/trees/TreeNodeBinding.js index 299c17d3ef..e167ebf6ba 100644 --- a/Website/Composite/scripts/source/top/ui/bindings/trees/TreeNodeBinding.js +++ b/Website/Composite/scripts/source/top/ui/bindings/trees/TreeNodeBinding.js @@ -970,6 +970,11 @@ TreeNodeBinding.prototype.handleElement = function ( element ) { return false; // continue updates as normally! } +TreeNodeBinding.prototype.getParent = function () { + + return this.getAncestorBindingByLocalName("treenode"); +} + /** * TreeNodeBinding factory. * @param {DOMDocument} ownerDocument diff --git a/Website/Composite/scripts/source/top/ui/bindings/views/ViewBinding.js b/Website/Composite/scripts/source/top/ui/bindings/views/ViewBinding.js index fbd1b8464d..2b096a187a 100644 --- a/Website/Composite/scripts/source/top/ui/bindings/views/ViewBinding.js +++ b/Website/Composite/scripts/source/top/ui/bindings/views/ViewBinding.js @@ -725,8 +725,14 @@ ViewBinding.prototype.show = function () { if (this._type == ViewBinding.TYPE_DOCKVIEW && this.windowBinding != null) { this.windowBinding.getBindingElement ().style.position = "static"; } - this.updatePositionDimension (); - this.isVisible = true; + + var self = this; + + setTimeout(function () { //Edge require timeout #522 + self.updatePositionDimension(); + self.isVisible = true; + }, 0); + } else { ViewBinding.superclass.show.call ( this ); } diff --git a/Website/Composite/scripts/source/top/ui/bindings/windows/PreviewWindowBinding.js b/Website/Composite/scripts/source/top/ui/bindings/windows/PreviewWindowBinding.js index 5d4aa99b08..7034042203 100644 --- a/Website/Composite/scripts/source/top/ui/bindings/windows/PreviewWindowBinding.js +++ b/Website/Composite/scripts/source/top/ui/bindings/windows/PreviewWindowBinding.js @@ -283,9 +283,10 @@ PreviewWindowBinding.prototype.reset = function () { if ( this._loadhandler != null ) { if (this.getURL() != WindowBinding.DEFAULT_URL) { - if (this.hasAccess(this._windowBinding)) { + var win = this.getContentWindow(); + if (this.hasAccess(win)) { DOMEvents.removeEventListener( - this.getContentWindow(), + win, DOMEvents.BEFOREUNLOAD, this._loadhandler ); diff --git a/Website/Composite/services/Admin/DownloadFile.ashx b/Website/Composite/services/Admin/DownloadFile.ashx index b3c8117065..ff957eff70 100644 --- a/Website/Composite/services/Admin/DownloadFile.ashx +++ b/Website/Composite/services/Admin/DownloadFile.ashx @@ -56,24 +56,30 @@ public class DownloadFile : IHttpHandler Verify.IsNotNull(fullFilePath, "Unexpected exception"); - bool isDllPreview = false; - if (isPreview) { - var extension = Path.GetExtension(fullFilePath); - string mimeType = MimeTypeInfo.GetCanonicalFromExtension(extension); + var fileInfo = new FileInfo(fullFilePath); + string mimeType = MimeTypeInfo.GetCanonicalFromExtension(fileInfo.Extension); if (!MimeTypeInfo.IsBrowserPreviewableFile(mimeType)) { - if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase)) + if (fileInfo.Extension.Equals(".dll", StringComparison.OrdinalIgnoreCase)) { - isDllPreview = true; + OutputDllPreviewInformation(context, fullFilePath); + return; } - else if (!MimeTypeInfo.IsTextFile(mimeType)) + + if (!MimeTypeInfo.IsTextFile(mimeType)) { return; } + if (fileInfo.Length < 100*1024 && mimeType != "text/plain") + { + PreviewWithCodeHighlight(context, fullFilePath); + return; + } + mimeType = "text/plain"; } @@ -85,15 +91,7 @@ public class DownloadFile : IHttpHandler context.Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName); } - if (isDllPreview) - { - OutputDllPreviewInformation(context, fullFilePath); - } - else - { - context.Response.TransmitFile(fullFilePath); - } - + context.Response.TransmitFile(fullFilePath); context.ApplicationInstance.CompleteRequest(); } @@ -213,9 +211,31 @@ public class DownloadFile : IHttpHandler var text = string.Join(Environment.NewLine, lines); + context.Response.ContentType = "text/plain"; context.Response.Write(text); } + private void PreviewWithCodeHighlight(HttpContext context, string fullFilePath) + { + context.Response.ContentType = "text/html"; + context.Response.Write(@" + + + + + + +
");
+
+        var lines = File.ReadAllLines(fullFilePath);
+        foreach (var line in lines)
+        {
+            context.Response.Write(context.Server.HtmlEncode(line));
+            context.Response.Write(Environment.NewLine);
+        }
+
+        context.Response.Write(@"
");} + private bool UserHasRightToDownload(EntityToken file) { diff --git a/Website/Composite/services/Admin/HighlightJs/LICENSE b/Website/Composite/services/Admin/HighlightJs/LICENSE new file mode 100644 index 0000000000..422deb7350 --- /dev/null +++ b/Website/Composite/services/Admin/HighlightJs/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2006, Ivan Sagalaev +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of highlight.js nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Website/Composite/services/Admin/HighlightJs/highlight.pack.js b/Website/Composite/services/Admin/HighlightJs/highlight.pack.js new file mode 100644 index 0000000000..b4a9208f20 --- /dev/null +++ b/Website/Composite/services/Admin/HighlightJs/highlight.pack.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){s+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"
":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("cs",function(e){var i={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},t={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},r=e.inherit(t,{i:/\n/}),a={cN:"subst",b:"{",e:"}",k:i},c=e.inherit(a,{i:/\n/}),n={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,c]},s={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},a]},o=e.inherit(s,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},c]});a.c=[s,n,t,e.ASM,e.QSM,e.CNM,e.CBCM],c.c=[o,n,r,e.ASM,e.QSM,e.CNM,e.inherit(e.CBCM,{i:/\n/})];var l={v:[s,n,t,e.ASM,e.QSM]},b=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp"],k:i,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},l,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{cN:"meta",b:"^\\s*\\[",eB:!0,e:"\\]",eE:!0,c:[{cN:"meta-string",b:/"/,e:/"/}]},{bK:"new return throw await else",r:0},{cN:"function",b:"("+b+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:i,r:0,c:[l,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("typescript",function(e){var r={keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract as from extends async await",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void Promise"};return{aliases:["ts"],k:r,c:[{cN:"meta",b:/^\s*['"]use strict['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+e.IR+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:e.IR},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:["self",e.CLCM,e.CBCM]}]}]}],r:0},{cN:"function",b:"function",e:/[\{;]/,eE:!0,k:r,c:["self",e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/%/,r:0},{bK:"constructor",e:/\{/,eE:!0,c:["self",{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}]},{b:/module\./,k:{built_in:"module"},r:0},{bK:"module",e:/\{/,eE:!0},{bK:"interface",e:/\{/,eE:!0,k:"interface extends"},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("less",function(e){var r="[\\w-]+",t="("+r+"|@{"+r+"})",a=[],c=[],s=function(e){return{cN:"string",b:"~?"+e+".*?"+e}},b=function(e,r,t){return{cN:e,b:r,r:t}},n={b:"\\(",e:"\\)",c:c,r:0};c.push(e.CLCM,e.CBCM,s("'"),s('"'),e.CSSNM,{b:"(url|data-uri)\\(",starts:{cN:"string",e:"[\\)\\n]",eE:!0}},b("number","#[0-9A-Fa-f]+\\b"),n,b("variable","@@?"+r,10),b("variable","@{"+r+"}"),b("built_in","~?`[^`]*?`"),{cN:"attribute",b:r+"\\s*:",e:":",rB:!0,eE:!0},{cN:"meta",b:"!important"});var i=c.concat({b:"{",e:"}",c:a}),o={bK:"when",eW:!0,c:[{bK:"and not"}].concat(c)},u={b:t+"\\s*:",rB:!0,e:"[;}]",r:0,c:[{cN:"attribute",b:t,e:":",eE:!0,starts:{eW:!0,i:"[<=$]",r:0,c:c}}]},l={cN:"keyword",b:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{e:"[;{}]",rE:!0,c:c,r:0}},C={cN:"variable",v:[{b:"@"+r+"\\s*:",r:15},{b:"@"+r}],starts:{e:"[;}]",rE:!0,c:i}},p={v:[{b:"[\\.#:&\\[>]",e:"[;{}]"},{b:t,e:"{"}],rB:!0,rE:!0,i:"[<='$\"]",r:0,c:[e.CLCM,e.CBCM,o,b("keyword","all\\b"),b("variable","@{"+r+"}"),b("selector-tag",t+"%?",0),b("selector-id","#"+t),b("selector-class","\\."+t,0),b("selector-tag","&",0),{cN:"selector-attr",b:"\\[",e:"\\]"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"\\(",e:"\\)",c:i},{b:"!important"}]};return a.push(e.CLCM,e.CBCM,l,C,u,p),{cI:!0,i:"[=>'/<($\"]",c:a}}); \ No newline at end of file diff --git a/Website/Composite/services/Admin/HighlightJs/readme.txt b/Website/Composite/services/Admin/HighlightJs/readme.txt new file mode 100644 index 0000000000..f9d0cd8364 --- /dev/null +++ b/Website/Composite/services/Admin/HighlightJs/readme.txt @@ -0,0 +1,3 @@ +Packaged with https://highlightjs.org/download/ with the following language options selected: + +HTML/XML,HTTP,CSS,LESS,JavaScript,JSON,TypeScript,C#,Markdown \ No newline at end of file diff --git a/Website/Composite/services/Admin/HighlightJs/vs.css b/Website/Composite/services/Admin/HighlightJs/vs.css new file mode 100644 index 0000000000..c5d07d3115 --- /dev/null +++ b/Website/Composite/services/Admin/HighlightJs/vs.css @@ -0,0 +1,68 @@ +/* + +Visual Studio-like style based on original C# coloring by Jason Diamond + +*/ +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: white; + color: black; +} + +.hljs-comment, +.hljs-quote, +.hljs-variable { + color: #008000; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-built_in, +.hljs-name, +.hljs-tag { + color: #00f; +} + +.hljs-string, +.hljs-title, +.hljs-section, +.hljs-attribute, +.hljs-literal, +.hljs-template-tag, +.hljs-template-variable, +.hljs-type, +.hljs-addition { + color: #a31515; +} + +.hljs-deletion, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-meta { + color: #2b91af; +} + +.hljs-doctag { + color: #808080; +} + +.hljs-attr { + color: #f00; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link { + color: #00b0e8; +} + + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/Website/Composite/services/Installation/InstallationService.asmx b/Website/Composite/services/Installation/InstallationService.asmx index 29935bf760..b09a63b345 100644 --- a/Website/Composite/services/Installation/InstallationService.asmx +++ b/Website/Composite/services/Installation/InstallationService.asmx @@ -69,8 +69,8 @@ namespace Composite.Services }, new KeyValuePair { - Key = "QA, Documentation & Support", - Value = "Vitaly Vysotskyi;Pavlo Kuzminskiy" + Key = "QA, Documentation", + Value = "Vitaly Vysotskyi" }, new KeyValuePair { diff --git a/Website/Composite/services/Setup/SetupService.asmx b/Website/Composite/services/Setup/SetupService.asmx index 1fe90f9807..547a3e88e3 100644 --- a/Website/Composite/services/Setup/SetupService.asmx +++ b/Website/Composite/services/Setup/SetupService.asmx @@ -1,4 +1,4 @@ -<%@ WebService Language="C#" Class="Composite.Core.WebClient.Setup.SetupService" %> +<%@ WebService Language="C#" Class="Composite.Core.WebClient.Setup.SetupService" %> using System; using System.IO; @@ -146,20 +146,23 @@ namespace Composite.Core.WebClient.Setup [WebMethod] public bool SetUp(string setupDescriptionXML, string username, string email, string password, string language, string consolelanguage, bool newsletter) { - if (SystemSetupFacade.IsSystemFirstTimeInitialized) return true; + if (SystemSetupFacade.IsSystemFirstTimeInitialized || SystemSetupFacade.SetupIsRunning) return true; SystemSetupFacade.SetupIsRunning = true; - SystemSetupFacade.IsSystemFirstTimeInitialized = true; try { return SetupServiceFacade.SetUp(setupDescriptionXML, username, password, email, language, consolelanguage, newsletter); } - catch(Exception ex) + catch (Exception ex) { Log.LogError(LogTitle, ex); throw; } + finally + { + SystemSetupFacade.IsSystemFirstTimeInitialized = true; + } } diff --git a/Website/Composite/services/Tree/TreeServices.asmx b/Website/Composite/services/Tree/TreeServices.asmx index 7802c2b50b..112fb43ac5 100644 --- a/Website/Composite/services/Tree/TreeServices.asmx +++ b/Website/Composite/services/Tree/TreeServices.asmx @@ -1,4 +1,4 @@ -<%@ WebService Language="C#" Class="Composite.Services.TreeServices" %> +<%@ WebService Language="C#" Class="Composite.Services.TreeServices" %> using System; using System.Linq; @@ -332,21 +332,31 @@ namespace Composite.Services [WebMethod] public ClientBrowserViewSettings GetBrowserUrlByEntityToken(string serializedEntityToken, bool showPublished) { - - var entityToken = EntityTokenSerializer.Deserialize(serializedEntityToken); - - using (new DataScope(showPublished ? PublicationScope.Published : PublicationScope.Unpublished)) + try { - var browserViewSettings = UrlToEntityTokenFacade.TryGetBrowserViewSettings(entityToken, showPublished); + var entityToken = EntityTokenSerializer.Deserialize(serializedEntityToken); - if (browserViewSettings != null) + using (new DataScope(showPublished ? PublicationScope.Published : PublicationScope.Unpublished)) { - return new ClientBrowserViewSettings { Url = browserViewSettings.Url, ToolingOn = browserViewSettings.ToolingOn }; + var browserViewSettings = UrlToEntityTokenFacade.TryGetBrowserViewSettings(entityToken, showPublished); + + if (browserViewSettings != null) + { + return new ClientBrowserViewSettings + { + Url = browserViewSettings.Url, + ToolingOn = browserViewSettings.ToolingOn + }; + } } + return null; + } + catch (Exception ex) + { + Log.LogError("GetBrowserUrlByEntityToken", ex); + throw; } - - return null; } diff --git a/Website/Composite/styles/default/dialogs/dialogs.less b/Website/Composite/styles/default/dialogs/dialogs.less index 2f423ca322..88116f3b1e 100644 --- a/Website/Composite/styles/default/dialogs/dialogs.less +++ b/Website/Composite/styles/default/dialogs/dialogs.less @@ -199,6 +199,7 @@ ui|dialogpage.functionview-basic { .dialogsubpage { height: auto; min-height: 100%; /* IE relies on flexibility instead */ + max-height: 100%; &.with-top-toolbar { ui|toolbar { padding-top: 0; diff --git a/Website/Composite/styles/default/explorer.less b/Website/Composite/styles/default/explorer.less index a96f2e1c8a..52b65c52e1 100644 --- a/Website/Composite/styles/default/explorer.less +++ b/Website/Composite/styles/default/explorer.less @@ -54,6 +54,8 @@ ui|explorermenu { overflow-y: auto; box-sizing: content-box; padding-right: 16px; + position: relative; + z-index: 1; ui|toolbarbutton { background: none !important; diff --git a/Website/Renderers/ShowMedia.ashx b/Website/Renderers/ShowMedia.ashx index 92deb0b205..8014a415b7 100644 --- a/Website/Renderers/ShowMedia.ashx +++ b/Website/Renderers/ShowMedia.ashx @@ -529,7 +529,7 @@ public class ShowMedia : IHttpHandler, IReadOnlySessionState private static FileOrStream ProcessImageResizing(HttpContext context, IMediaFile file) { - var resizingOptions = ResizingOptions.Parse(context.Server, context.Request.QueryString); + var resizingOptions = ResizingOptions.Parse(context.Request.QueryString); if (resizingOptions == null || resizingOptions.IsEmpty) { diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index 3f8d4aeeda..2667746362 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -53,9 +53,8 @@ false - - ..\packages\Castle.Core.3.3.1\lib\net45\Castle.Core.dll - True + + ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll False @@ -111,6 +110,9 @@ False ..\Packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll + + ..\packages\System.Threading.Tasks.Dataflow.4.7.0\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll + diff --git a/Website/packages.config b/Website/packages.config index 889fa78b98..9da15a9e51 100644 --- a/Website/packages.config +++ b/Website/packages.config @@ -1,19 +1,19 @@ - + + + + + + - - - - - - + \ No newline at end of file diff --git a/readme.now.txt b/readme.now.txt deleted file mode 100644 index b6e3f94a58..0000000000 --- a/readme.now.txt +++ /dev/null @@ -1,7 +0,0 @@ - -Please note that Firefox, Safari and Chrome can be extremely slow when working -with Visual Studio’s built-in development Web server (a.k.a. Cassini). This is -related to an issue with IPv6 and DNS. - -For resolutions, please see: -http://codepolice.net/2009/02/19/slow-iis-on-vista-with-firefox-chrome-or-safari/