Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/v8/8.16' into v9/feature/merge_v…
Browse files Browse the repository at this point in the history
…8_11082021

# Conflicts:
#	.github/CONTRIBUTING.md
#	build/NuSpecs/UmbracoCms.Core.nuspec
#	build/NuSpecs/UmbracoCms.Web.nuspec
#	build/NuSpecs/UmbracoCms.nuspec
#	src/SolutionInfo.cs
#	src/Umbraco.Core/Cache/AppCaches.cs
#	src/Umbraco.Core/Cache/AppPolicedCacheDictionary.cs
#	src/Umbraco.Core/Cache/DeepCloneAppCache.cs
#	src/Umbraco.Core/Cache/WebCachingAppCache.cs
#	src/Umbraco.Core/CompositionExtensions.cs
#	src/Umbraco.Core/Models/Identity/BackOfficeIdentityUser.cs
#	src/Umbraco.Core/Models/PropertyGroupCollection.cs
#	src/Umbraco.Core/Models/PropertyTypeCollection.cs
#	src/Umbraco.Core/Persistence/Repositories/Implement/ExternalLoginRepository.cs
#	src/Umbraco.Core/ReadLock.cs
#	src/Umbraco.Core/Routing/SiteDomainMapper.cs
#	src/Umbraco.Core/UpgradeableReadLock.cs
#	src/Umbraco.Core/WriteLock.cs
#	src/Umbraco.Examine/ExamineExtensions.cs
#	src/Umbraco.Infrastructure/Examine/UmbracoFieldDefinitionCollection.cs
#	src/Umbraco.Infrastructure/Persistence/Dtos/ContentTypeDto.cs
#	src/Umbraco.Infrastructure/Persistence/Dtos/DictionaryDto.cs
#	src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberGroupRepository.cs
#	src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TemplateRepository.cs
#	src/Umbraco.Infrastructure/Persistence/Repositories/Implement/UserRepository.cs
#	src/Umbraco.Infrastructure/Services/IdKeyMap.cs
#	src/Umbraco.Infrastructure/Services/Implement/ContentService.cs
#	src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs
#	src/Umbraco.Tests/App.config
#	src/Umbraco.Web.BackOffice/Controllers/EntityController.cs
#	src/Umbraco.Web.UI.Client/package.json
#	src/Umbraco.Web.UI.NetCore/umbraco/config/lang/da.xml
#	src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml
#	src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml
#	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
#	src/Umbraco.Web.UI/Umbraco/config/lang/cy.xml
#	src/Umbraco.Web.UI/web.Template.config
#	src/Umbraco.Web/CacheHelperExtensions.cs
#	src/Umbraco.Web/Editors/RelationTypeController.cs
#	src/Umbraco.Web/Logging/WebProfilerProvider.cs
#	src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs
#	src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs
#	src/Umbraco.Web/Routing/ContentFinderByConfigured404.cs
#	src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs
#	src/Umbraco.Web/Security/BackOfficeUserManager.cs
#	src/Umbraco.Web/Umbraco.Web.csproj
  • Loading branch information
bergmania committed Aug 11, 2021
2 parents c5e8826 + 9b93a8f commit 2baa1ab
Show file tree
Hide file tree
Showing 138 changed files with 1,192 additions and 1,076 deletions.
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ You can get in touch with [the core contributors team](#the-core-contributors-te

In order to build the Umbraco source code locally, first make sure you have the following installed.

* [Visual Studio 2019 v16.3+ (with .NET Core 3.0)](https://visualstudio.microsoft.com/vs/)
* [Visual Studio 2019 v16.8+ (with .NET Core 3.0)](https://visualstudio.microsoft.com/vs/)
* [Node.js v10+](https://nodejs.org/en/download/)
* npm v6.4.1+ (installed with Node.js)
* [Git command line](https://git-scm.com/download/)
Expand Down
17 changes: 16 additions & 1 deletion build/NuSpecs/tools/Web.config.install.xdt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.ValueTuple')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http.Formatting')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Collections.Immutable')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Buffers')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Memory')" xdt:Transform="Remove" />
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Numerics.Vectors')" xdt:Transform="Remove" />
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
Expand All @@ -153,7 +156,7 @@
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.3.0" newVersion="1.2.3.0" />
<bindingRedirect oldVersion="0.0.0.0-1.2.5.0" newVersion="1.2.5.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
Expand All @@ -171,6 +174,18 @@
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" />
<bindingRedirect oldVersion="4.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" />
<bindingRedirect oldVersion="4.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

Expand Down
26 changes: 25 additions & 1 deletion src/Umbraco.Core/Cache/AppCaches.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using System;
using Umbraco.Extensions;

namespace Umbraco.Cms.Core.Cache
{
/// <summary>
/// Represents the application caches.
/// </summary>
public class AppCaches
public class AppCaches : IDisposable
{
private bool _disposedValue;

/// <summary>
/// Initializes a new instance of the <see cref="AppCaches"/> with cache providers.
/// </summary>
Expand Down Expand Up @@ -72,5 +75,26 @@ public static AppCaches Create(IRequestCache requestCache)
requestCache,
new IsolatedCaches(type => new DeepCloneAppCache(new ObjectCacheAppCache())));
}

protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
RuntimeCache.DisposeIfDisposable();
RequestCache.DisposeIfDisposable();
IsolatedCaches.Dispose();
}

_disposedValue = true;
}
}

public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
}
}
}
26 changes: 25 additions & 1 deletion src/Umbraco.Core/Cache/AppPolicedCacheDictionary.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System;
using System.Collections.Concurrent;
using Umbraco.Extensions;

namespace Umbraco.Cms.Core.Cache
{
/// <summary>
/// Provides a base class for implementing a dictionary of <see cref="IAppPolicyCache"/>.
/// </summary>
/// <typeparam name="TKey">The type of the dictionary key.</typeparam>
public abstract class AppPolicedCacheDictionary<TKey>
public abstract class AppPolicedCacheDictionary<TKey> : IDisposable
{
private readonly ConcurrentDictionary<TKey, IAppPolicyCache> _caches = new ConcurrentDictionary<TKey, IAppPolicyCache>();

Expand All @@ -24,6 +25,7 @@ protected AppPolicedCacheDictionary(Func<TKey, IAppPolicyCache> cacheFactory)
/// Gets the internal cache factory, for tests only!
/// </summary>
private readonly Func<TKey, IAppPolicyCache> _cacheFactory;
private bool _disposedValue;

/// <summary>
/// Gets or creates a cache.
Expand Down Expand Up @@ -70,5 +72,27 @@ public void ClearAllCaches()
foreach (var cache in _caches.Values)
cache.Clear();
}

protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
foreach(var value in _caches.Values)
{
value.DisposeIfDisposable();
}
}

_disposedValue = true;
}
}

public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
}
}
}
24 changes: 23 additions & 1 deletion src/Umbraco.Core/Cache/DeepCloneAppCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Extensions;

namespace Umbraco.Cms.Core.Cache
{
Expand All @@ -11,8 +12,10 @@ namespace Umbraco.Cms.Core.Cache
/// instance, and ensuring that all inserts and returns are deep cloned copies of the cache item,
/// when the item is deep-cloneable.
/// </summary>
public class DeepCloneAppCache : IAppPolicyCache
public class DeepCloneAppCache : IAppPolicyCache, IDisposable
{
private bool _disposedValue;

/// <summary>
/// Initializes a new instance of the <see cref="DeepCloneAppCache"/> class.
/// </summary>
Expand Down Expand Up @@ -152,5 +155,24 @@ private static object CheckCloneableAndTracksChanges(object input)

return input;
}

protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
InnerCache.DisposeIfDisposable();
}

_disposedValue = true;
}
}

public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
}
}
}
21 changes: 20 additions & 1 deletion src/Umbraco.Core/Cache/ObjectCacheAppCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ namespace Umbraco.Cms.Core.Cache
/// <summary>
/// Implements <see cref="IAppPolicyCache"/> on top of a <see cref="ObjectCache"/>.
/// </summary>
public class ObjectCacheAppCache : IAppPolicyCache
public class ObjectCacheAppCache : IAppPolicyCache, IDisposable
{
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private bool _disposedValue;

/// <summary>
/// Initializes a new instance of the <see cref="ObjectCacheAppCache"/>.
Expand Down Expand Up @@ -344,5 +345,23 @@ private static CacheItemPolicy GetPolicy(TimeSpan? timeout = null, bool isSlidin

return policy;
}

protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
_locker.Dispose();
}
_disposedValue = true;
}
}

public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Umbraco.Cms.Core.HealthChecks;
using Umbraco.Cms.Core.HealthChecks.NotificationMethods;
using Umbraco.Cms.Core.Manifest;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Media.EmbedProviders;
using Umbraco.Cms.Core.Packaging;
using Umbraco.Cms.Core.PropertyEditors;
Expand Down Expand Up @@ -204,6 +205,13 @@ public static DashboardCollectionBuilder Dashboards(this IUmbracoBuilder builder
public static CacheRefresherCollectionBuilder CacheRefreshers(this IUmbracoBuilder builder)
=> builder.WithCollectionBuilder<CacheRefresherCollectionBuilder>();

/// <summary>
/// Gets the map definitions collection builder.
/// </summary>
/// <param name="builder">The builder.</param>
public static MapDefinitionCollectionBuilder MapDefinitions(this IUmbracoBuilder builder)
=> builder.WithCollectionBuilder<MapDefinitionCollectionBuilder>();

/// <summary>
/// Gets the data editor collection builder.
/// </summary>
Expand Down
55 changes: 21 additions & 34 deletions src/Umbraco.Core/Models/PropertyGroupCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;

namespace Umbraco.Cms.Core.Models
{
Expand All @@ -17,8 +16,6 @@ namespace Umbraco.Cms.Core.Models
// TODO: Change this to ObservableDictionary so we can reduce the INotifyCollectionChanged implementation details
public class PropertyGroupCollection : KeyedCollection<string, PropertyGroup>, INotifyCollectionChanged, IDeepCloneable
{
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();

public PropertyGroupCollection()
{ }

Expand Down Expand Up @@ -70,47 +67,37 @@ protected override void ClearItems()

public new void Add(PropertyGroup item)
{
try
//Note this is done to ensure existing groups can be renamed
if (item.HasIdentity && item.Id > 0)
{
_addLocker.EnterWriteLock();
var exists = Contains(item.Id);
if (exists)
{
var keyExists = Contains(item.Name);
if (keyExists)
throw new Exception($"Naming conflict: Changing the name of PropertyGroup '{item.Name}' would result in duplicates");

//Note this is done to ensure existing groups can be renamed
if (item.HasIdentity && item.Id > 0)
//collection events will be raised in SetItem
SetItem(IndexOfKey(item.Id), item);
return;
}
}
else
{
var key = GetKeyForItem(item);
if (key != null)
{
var exists = Contains(item.Id);
var exists = Contains(key);
if (exists)
{
var keyExists = Contains(item.Name);
if (keyExists)
throw new Exception($"Naming conflict: Changing the name of PropertyGroup '{item.Name}' would result in duplicates");

//collection events will be raised in SetItem
SetItem(IndexOfKey(item.Id), item);
SetItem(IndexOfKey(key), item);
return;
}
}
else
{
var key = GetKeyForItem(item);
if (key != null)
{
var exists = Contains(key);
if (exists)
{
//collection events will be raised in SetItem
SetItem(IndexOfKey(key), item);
return;
}
}
}
//collection events will be raised in InsertItem
base.Add(item);
}
finally
{
if (_addLocker.IsWriteLockHeld)
_addLocker.ExitWriteLock();
}
//collection events will be raised in InsertItem
base.Add(item);
}

/// <summary>
Expand Down
44 changes: 16 additions & 28 deletions src/Umbraco.Core/Models/PropertyTypeCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ namespace Umbraco.Cms.Core.Models
// TODO: Change this to ObservableDictionary so we can reduce the INotifyCollectionChanged implementation details
public class PropertyTypeCollection : KeyedCollection<string, IPropertyType>, INotifyCollectionChanged, IDeepCloneable, ICollection<IPropertyType>
{
[IgnoreDataMember]
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();


public PropertyTypeCollection(bool supportsPublishing)
{
SupportsPublishing = supportsPublishing;
Expand Down Expand Up @@ -90,36 +86,28 @@ protected override void ClearItems()
item.SupportsPublishing = SupportsPublishing;

// TODO: this is not pretty and should be refactored
try
{
_addLocker.EnterWriteLock();
var key = GetKeyForItem(item);
if (key != null)
{
var exists = Contains(key);
if (exists)
{
//collection events will be raised in SetItem
SetItem(IndexOfKey(key), item);
return;
}
}

//check if the item's sort order is already in use
if (this.Any(x => x.SortOrder == item.SortOrder))
var key = GetKeyForItem(item);
if (key != null)
{
var exists = Contains(key);
if (exists)
{
//make it the next iteration
item.SortOrder = this.Max(x => x.SortOrder) + 1;
//collection events will be raised in SetItem
SetItem(IndexOfKey(key), item);
return;
}

//collection events will be raised in InsertItem
base.Add(item);
}
finally

//check if the item's sort order is already in use
if (this.Any(x => x.SortOrder == item.SortOrder))
{
if (_addLocker.IsWriteLockHeld)
_addLocker.ExitWriteLock();
//make it the next iteration
item.SortOrder = this.Max(x => x.SortOrder) + 1;
}

//collection events will be raised in InsertItem
base.Add(item);
}

/// <summary>
Expand Down
Loading

0 comments on commit 2baa1ab

Please sign in to comment.