diff --git a/.gitignore b/.gitignore
index 848fce32ff..a7f7bec4ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,3 +91,6 @@ src/Umbraco.Web.UI/App_Plugins/*
src/*.psess
src/*.vspx
src/Umbraco.Web.UI/umbraco/js/routes.js.*
+NDependOut/*
+*.ndproj
+QueryResult.htm
diff --git a/src/Umbraco.Core/DictionaryExtensions.cs b/src/Umbraco.Core/DictionaryExtensions.cs
index 73866f2c9b..de12e0b3b1 100644
--- a/src/Umbraco.Core/DictionaryExtensions.cs
+++ b/src/Umbraco.Core/DictionaryExtensions.cs
@@ -187,6 +187,25 @@ namespace Umbraco.Core
return String.Empty;
}
+ ///
+ /// Returns the value of the key value based on the key as it's string value, if the key is not found or is an empty string, then the provided default value is returned
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static string GetValueAsString(this IDictionary d, TKey key, string defaultValue)
+ {
+ if (d.ContainsKey(key))
+ {
+ var value = d[key].ToString();
+ if (value != string.Empty)
+ return value;
+ }
+
+ return defaultValue;
+ }
+
/// contains key ignore case.
/// The dictionary.
/// The key.
diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs
index b50102396a..a2963343e3 100644
--- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs
+++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs
@@ -146,7 +146,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
private void CreateUmbracoUserTypeData()
{
- _database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 1, Alias = "admin", Name = "Administrators", DefaultPermissions = "CADMOSKTPIURZ:5F" });
+ _database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 1, Alias = "admin", Name = "Administrators", DefaultPermissions = "CADMOSKTPIURZ:5F7" });
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 2, Alias = "writer", Name = "Writer", DefaultPermissions = "CAH:F" });
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 3, Alias = "editor", Name = "Editors", DefaultPermissions = "CADMOSKTPUZ:5F" });
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 4, Alias = "translator", Name = "Translator", DefaultPermissions = "AF" });
diff --git a/src/Umbraco.Core/PublishedContentHelper.cs b/src/Umbraco.Core/PublishedContentHelper.cs
index 1e7fc1ef18..86513ede02 100644
--- a/src/Umbraco.Core/PublishedContentHelper.cs
+++ b/src/Umbraco.Core/PublishedContentHelper.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Dynamics;
+using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
@@ -35,7 +36,7 @@ namespace Umbraco.Core
///
internal static Func GetDataTypeCallback = null;
- private static readonly ConcurrentDictionary, Guid> PropertyTypeCache = new ConcurrentDictionary, Guid>();
+ private static readonly ConcurrentDictionary, Guid> PropertyTypeCache = new ConcurrentDictionary, Guid>();
///
/// Return the GUID Id for the data type assigned to the document type with the property alias
@@ -43,16 +44,29 @@ namespace Umbraco.Core
///
///
///
+ ///
///
- internal static Guid GetDataType(ApplicationContext applicationContext, string docTypeAlias, string propertyAlias)
+ internal static Guid GetDataType(ApplicationContext applicationContext, string docTypeAlias, string propertyAlias, PublishedItemType itemType)
{
if (GetDataTypeCallback != null)
return GetDataTypeCallback(docTypeAlias, propertyAlias);
- var key = new Tuple(docTypeAlias, propertyAlias);
+ var key = new Tuple(docTypeAlias, propertyAlias, itemType);
return PropertyTypeCache.GetOrAdd(key, tuple =>
{
- var result = applicationContext.Services.ContentTypeService.GetContentType(docTypeAlias);
+ IContentTypeComposition result = null;
+ switch (itemType)
+ {
+ case PublishedItemType.Content:
+ result = applicationContext.Services.ContentTypeService.GetContentType(docTypeAlias);
+ break;
+ case PublishedItemType.Media:
+ result = applicationContext.Services.ContentTypeService.GetMediaType(docTypeAlias);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException("itemType");
+ }
+
if (result == null) return Guid.Empty;
//SD: we need to check for 'any' here because the collection is backed by KeyValuePair which is a struct
diff --git a/src/Umbraco.Core/TypeFinder.cs b/src/Umbraco.Core/TypeFinder.cs
index e327b3df00..9a1478ff38 100644
--- a/src/Umbraco.Core/TypeFinder.cs
+++ b/src/Umbraco.Core/TypeFinder.cs
@@ -19,54 +19,56 @@ using Umbraco.Core.IO;
namespace Umbraco.Core
{
- ///
- /// A utility class to find all classes of a certain type by reflection in the current bin folder
- /// of the web application.
- ///
- public static class TypeFinder
- {
-
- private static readonly ConcurrentBag LocalFilteredAssemblyCache = new ConcurrentBag();
- private static readonly ReaderWriterLockSlim LocalFilteredAssemblyCacheLocker = new ReaderWriterLockSlim();
- private static ReadOnlyCollection _allAssemblies = null;
- private static ReadOnlyCollection _binFolderAssemblies = null;
- private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
+ ///
+ /// A utility class to find all classes of a certain type by reflection in the current bin folder
+ /// of the web application.
+ ///
+ public static class TypeFinder
+ {
+ private static readonly HashSet LocalFilteredAssemblyCache = new HashSet();
+ private static readonly ReaderWriterLockSlim LocalFilteredAssemblyCacheLocker = new ReaderWriterLockSlim();
+ private static HashSet _allAssemblies = null;
+ private static HashSet _binFolderAssemblies = null;
+ private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
- ///
- /// lazily load a reference to all assemblies and only local assemblies.
- /// This is a modified version of: http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder
- ///
- ///
- /// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
- /// loaded in the CLR, not all assemblies.
- /// See these threads:
- /// http://issues.umbraco.org/issue/U5-198
- /// http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app
- /// http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl
- ///
- internal static IEnumerable GetAllAssemblies()
- {
- if (_allAssemblies == null)
- {
- using (new WriteLock(Locker))
- {
- List assemblies = null;
- try
- {
- var isHosted = HttpContext.Current != null;
+ ///
+ /// lazily load a reference to all assemblies and only local assemblies.
+ /// This is a modified version of: http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder
+ ///
+ ///
+ /// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
+ /// loaded in the CLR, not all assemblies.
+ /// See these threads:
+ /// http://issues.umbraco.org/issue/U5-198
+ /// http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app
+ /// http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl
+ ///
+ internal static HashSet GetAllAssemblies()
+ {
+ using (var lck = new UpgradeableReadLock(Locker))
+ {
+ if (_allAssemblies == null)
+ {
- try
- {
- if (isHosted)
- {
- assemblies = new List(BuildManager.GetReferencedAssemblies().Cast());
- }
- }
- catch (InvalidOperationException e)
- {
- if (!(e.InnerException is SecurityException))
- throw;
- }
+ lck.UpgradeToWriteLock();
+
+ HashSet assemblies = null;
+ try
+ {
+ var isHosted = HttpContext.Current != null;
+
+ try
+ {
+ if (isHosted)
+ {
+ assemblies = new HashSet(BuildManager.GetReferencedAssemblies().Cast());
+ }
+ }
+ catch (InvalidOperationException e)
+ {
+ if (!(e.InnerException is SecurityException))
+ throw;
+ }
if (assemblies == null)
@@ -77,7 +79,7 @@ namespace Umbraco.Core
var binAssemblyFiles = Directory.GetFiles(binFolder, "*.dll", SearchOption.TopDirectoryOnly).ToList();
//var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
//var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
- assemblies = new List();
+ assemblies = new HashSet();
foreach (var a in binAssemblyFiles)
{
try
@@ -99,151 +101,161 @@ namespace Umbraco.Core
}
}
}
-
+
//if for some reason they are still no assemblies, then use the AppDomain to load in already loaded assemblies.
- if (!assemblies.Any())
- {
- assemblies.AddRange(AppDomain.CurrentDomain.GetAssemblies().ToList());
- }
+ if (!assemblies.Any())
+ {
+ foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
+ {
+ assemblies.Add(a);
+ }
+ }
- //here we are trying to get the App_Code assembly
- var fileExtensions = new[] {".cs", ".vb"}; //only vb and cs files are supported
- var appCodeFolder = new DirectoryInfo(IOHelper.MapPath(IOHelper.ResolveUrl("~/App_code")));
- //check if the folder exists and if there are any files in it with the supported file extensions
- if (appCodeFolder.Exists && (fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any())))
- {
- var appCodeAssembly = Assembly.Load("App_Code");
- if (!assemblies.Contains(appCodeAssembly)) // BuildManager will find App_Code already
- assemblies.Add(appCodeAssembly);
- }
+ //here we are trying to get the App_Code assembly
+ var fileExtensions = new[] { ".cs", ".vb" }; //only vb and cs files are supported
+ var appCodeFolder = new DirectoryInfo(IOHelper.MapPath(IOHelper.ResolveUrl("~/App_code")));
+ //check if the folder exists and if there are any files in it with the supported file extensions
+ if (appCodeFolder.Exists && (fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any())))
+ {
+ var appCodeAssembly = Assembly.Load("App_Code");
+ if (!assemblies.Contains(appCodeAssembly)) // BuildManager will find App_Code already
+ assemblies.Add(appCodeAssembly);
+ }
- //now set the _allAssemblies
- _allAssemblies = new ReadOnlyCollection(assemblies);
+ //now set the _allAssemblies
+ _allAssemblies = new HashSet(assemblies);
- }
- catch (InvalidOperationException e)
- {
- if (!(e.InnerException is SecurityException))
- throw;
+ }
+ catch (InvalidOperationException e)
+ {
+ if (!(e.InnerException is SecurityException))
+ throw;
- _binFolderAssemblies = _allAssemblies;
- }
- }
- }
+ _binFolderAssemblies = _allAssemblies;
+ }
+ }
- return _allAssemblies;
- }
-
- ///
- /// Returns only assemblies found in the bin folder that have been loaded into the app domain.
- ///
- ///
- ///
- /// This will be used if we implement App_Plugins from Umbraco v5 but currently it is not used.
- ///
- internal static IEnumerable GetBinAssemblies()
- {
+ return _allAssemblies;
+ }
+ }
- if (_binFolderAssemblies == null)
- {
- using (new WriteLock(Locker))
- {
- var assemblies = GetAssembliesWithKnownExclusions().ToArray();
- var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
- var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
- var domainAssemblyNames = binAssemblyFiles.Select(AssemblyName.GetAssemblyName);
- var safeDomainAssemblies = new List();
- var binFolderAssemblies = new List();
+ ///
+ /// Returns only assemblies found in the bin folder that have been loaded into the app domain.
+ ///
+ ///
+ ///
+ /// This will be used if we implement App_Plugins from Umbraco v5 but currently it is not used.
+ ///
+ internal static HashSet GetBinAssemblies()
+ {
- foreach (var a in assemblies)
- {
- try
- {
- //do a test to see if its queryable in med trust
- var assemblyFile = a.GetAssemblyFile();
- safeDomainAssemblies.Add(a);
- }
- catch (SecurityException)
- {
- //we will just ignore this because this will fail
- //in medium trust for system assemblies, we get an exception but we just want to continue until we get to
- //an assembly that is ok.
- }
- }
+ if (_binFolderAssemblies == null)
+ {
+ using (new WriteLock(Locker))
+ {
+ var assemblies = GetAssembliesWithKnownExclusions().ToArray();
+ var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
+ var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
+ var domainAssemblyNames = binAssemblyFiles.Select(AssemblyName.GetAssemblyName);
+ var safeDomainAssemblies = new HashSet();
+ var binFolderAssemblies = new HashSet();
- foreach (var assemblyName in domainAssemblyNames)
- {
- try
- {
- var foundAssembly =
- safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
- if (foundAssembly != null)
- {
- binFolderAssemblies.Add(foundAssembly);
- }
- }
- catch (SecurityException)
- {
- //we will just ignore this because if we are trying to do a call to:
- // AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName)))
- //in medium trust for system assemblies, we get an exception but we just want to continue until we get to
- //an assembly that is ok.
- }
- }
+ foreach (var a in assemblies)
+ {
+ try
+ {
+ //do a test to see if its queryable in med trust
+ var assemblyFile = a.GetAssemblyFile();
+ safeDomainAssemblies.Add(a);
+ }
+ catch (SecurityException)
+ {
+ //we will just ignore this because this will fail
+ //in medium trust for system assemblies, we get an exception but we just want to continue until we get to
+ //an assembly that is ok.
+ }
+ }
- _binFolderAssemblies = new ReadOnlyCollection(binFolderAssemblies);
- }
- }
- return _binFolderAssemblies;
- }
+ foreach (var assemblyName in domainAssemblyNames)
+ {
+ try
+ {
+ var foundAssembly =
+ safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
+ if (foundAssembly != null)
+ {
+ binFolderAssemblies.Add(foundAssembly);
+ }
+ }
+ catch (SecurityException)
+ {
+ //we will just ignore this because if we are trying to do a call to:
+ // AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName)))
+ //in medium trust for system assemblies, we get an exception but we just want to continue until we get to
+ //an assembly that is ok.
+ }
+ }
- ///
- /// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
- /// and exluding the ones passed in and excluding the exclusion list filter, the results of this are
- /// cached for perforance reasons.
- ///
- ///
- ///
- internal static IEnumerable GetAssembliesWithKnownExclusions(
- IEnumerable excludeFromResults = null)
- {
- if (LocalFilteredAssemblyCache.Any()) return LocalFilteredAssemblyCache;
- using (new WriteLock(LocalFilteredAssemblyCacheLocker))
- {
- var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter);
- assemblies.ForEach(LocalFilteredAssemblyCache.Add);
- }
- return LocalFilteredAssemblyCache;
- }
+ _binFolderAssemblies = new HashSet(binFolderAssemblies);
+ }
+ }
+ return _binFolderAssemblies;
+ }
- ///
- /// Return a list of found local Assemblies and exluding the ones passed in and excluding the exclusion list filter
- ///
- ///
- ///
- ///
- private static IEnumerable GetFilteredAssemblies(
- IEnumerable excludeFromResults = null,
- string[] exclusionFilter = null)
- {
- if (excludeFromResults == null)
- excludeFromResults = new List();
- if (exclusionFilter == null)
- exclusionFilter = new string[] { };
+ ///
+ /// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
+ /// and exluding the ones passed in and excluding the exclusion list filter, the results of this are
+ /// cached for perforance reasons.
+ ///
+ ///
+ ///
+ internal static HashSet GetAssembliesWithKnownExclusions(
+ IEnumerable excludeFromResults = null)
+ {
+ using (var lck = new UpgradeableReadLock(LocalFilteredAssemblyCacheLocker))
+ {
+ if (LocalFilteredAssemblyCache.Any()) return LocalFilteredAssemblyCache;
- return GetAllAssemblies()
- .Where(x => !excludeFromResults.Contains(x)
- && !x.GlobalAssemblyCache
- && !exclusionFilter.Any(f => x.FullName.StartsWith(f)));
- }
+ lck.UpgradeToWriteLock();
- ///
- /// this is our assembly filter to filter out known types that def dont contain types we'd like to find or plugins
- ///
- ///
- /// NOTE the comma vs period... comma delimits the name in an Assembly FullName property so if it ends with comma then its an exact name match
- ///
- internal static readonly string[] KnownAssemblyExclusionFilter = new[]
+ var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter);
+ foreach (var a in assemblies)
+ {
+ LocalFilteredAssemblyCache.Add(a);
+ }
+
+ return LocalFilteredAssemblyCache;
+ }
+ }
+
+ ///
+ /// Return a distinct list of found local Assemblies and exluding the ones passed in and excluding the exclusion list filter
+ ///
+ ///
+ ///
+ ///
+ private static IEnumerable GetFilteredAssemblies(
+ IEnumerable excludeFromResults = null,
+ string[] exclusionFilter = null)
+ {
+ if (excludeFromResults == null)
+ excludeFromResults = new HashSet();
+ if (exclusionFilter == null)
+ exclusionFilter = new string[] { };
+
+ return GetAllAssemblies()
+ .Where(x => !excludeFromResults.Contains(x)
+ && !x.GlobalAssemblyCache
+ && !exclusionFilter.Any(f => x.FullName.StartsWith(f)));
+ }
+
+ ///
+ /// this is our assembly filter to filter out known types that def dont contain types we'd like to find or plugins
+ ///
+ ///
+ /// NOTE the comma vs period... comma delimits the name in an Assembly FullName property so if it ends with comma then its an exact name match
+ ///
+ internal static readonly string[] KnownAssemblyExclusionFilter = new[]
{
"mscorlib,",
"System.",
@@ -287,11 +299,11 @@ namespace Umbraco.Core
///
///
///
- public static IEnumerable FindClassesOfTypeWithAttribute()
- where TAttribute : Attribute
- {
- return FindClassesOfTypeWithAttribute(GetAssembliesWithKnownExclusions(), true);
- }
+ public static IEnumerable FindClassesOfTypeWithAttribute()
+ where TAttribute : Attribute
+ {
+ return FindClassesOfTypeWithAttribute(GetAssembliesWithKnownExclusions(), true);
+ }
///
/// Finds any classes derived from the type T that contain the attribute TAttribute
@@ -300,11 +312,11 @@ namespace Umbraco.Core
///
///
///
- public static IEnumerable FindClassesOfTypeWithAttribute(IEnumerable assemblies)
- where TAttribute : Attribute
- {
- return FindClassesOfTypeWithAttribute(assemblies, true);
- }
+ public static IEnumerable FindClassesOfTypeWithAttribute(IEnumerable assemblies)
+ where TAttribute : Attribute
+ {
+ return FindClassesOfTypeWithAttribute(assemblies, true);
+ }
///
/// Finds any classes derived from the type T that contain the attribute TAttribute
@@ -314,13 +326,13 @@ namespace Umbraco.Core
///
///
///
- public static IEnumerable FindClassesOfTypeWithAttribute(
- IEnumerable assemblies,
- bool onlyConcreteClasses)
- where TAttribute : Attribute
- {
- return FindClassesOfTypeWithAttribute(typeof (T), assemblies, onlyConcreteClasses);
- }
+ public static IEnumerable FindClassesOfTypeWithAttribute(
+ IEnumerable assemblies,
+ bool onlyConcreteClasses)
+ where TAttribute : Attribute
+ {
+ return FindClassesOfTypeWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
+ }
///
/// Finds any classes derived from the assignTypeFrom Type that contain the attribute TAttribute
@@ -330,85 +342,85 @@ namespace Umbraco.Core
///
///
///
- public static IEnumerable FindClassesOfTypeWithAttribute(
- Type assignTypeFrom,
- IEnumerable assemblies,
+ public static IEnumerable FindClassesOfTypeWithAttribute(
+ Type assignTypeFrom,
+ IEnumerable assemblies,
bool onlyConcreteClasses)
where TAttribute : Attribute
- {
- if (assemblies == null) throw new ArgumentNullException("assemblies");
-
- return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
+ {
+ if (assemblies == null) throw new ArgumentNullException("assemblies");
+
+ return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
//the additional filter will ensure that any found types also have the attribute applied.
- t => t.GetCustomAttributes(false).Any());
- }
+ t => t.GetCustomAttributes(false).Any());
+ }
- ///
- /// Searches all filtered local assemblies specified for classes of the type passed in.
- ///
- ///
- ///
- public static IEnumerable FindClassesOfType()
- {
- return FindClassesOfType(GetAssembliesWithKnownExclusions(), true);
- }
+ ///
+ /// Searches all filtered local assemblies specified for classes of the type passed in.
+ ///
+ ///
+ ///
+ public static IEnumerable FindClassesOfType()
+ {
+ return FindClassesOfType(GetAssembliesWithKnownExclusions(), true);
+ }
- ///
- /// Returns all types found of in the assemblies specified of type T
- ///
- ///
- ///
- ///
- ///
- public static IEnumerable FindClassesOfType(IEnumerable assemblies, bool onlyConcreteClasses)
- {
- if (assemblies == null) throw new ArgumentNullException("assemblies");
+ ///
+ /// Returns all types found of in the assemblies specified of type T
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static IEnumerable FindClassesOfType(IEnumerable assemblies, bool onlyConcreteClasses)
+ {
+ if (assemblies == null) throw new ArgumentNullException("assemblies");
return GetClasses(typeof(T), assemblies, onlyConcreteClasses);
- }
+ }
- ///
- /// Returns all types found of in the assemblies specified of type T
- ///
- ///
- ///
- ///
- public static IEnumerable FindClassesOfType(IEnumerable assemblies)
- {
- return FindClassesOfType(assemblies, true);
- }
+ ///
+ /// Returns all types found of in the assemblies specified of type T
+ ///
+ ///
+ ///
+ ///
+ public static IEnumerable FindClassesOfType(IEnumerable assemblies)
+ {
+ return FindClassesOfType(assemblies, true);
+ }
- ///
- /// Finds the classes with attribute.
- ///
- ///
- /// The assemblies.
- /// if set to true only concrete classes.
- ///
- public static IEnumerable FindClassesWithAttribute(IEnumerable assemblies, bool onlyConcreteClasses)
- where T : Attribute
- {
- return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
- }
+ ///
+ /// Finds the classes with attribute.
+ ///
+ ///
+ /// The assemblies.
+ /// if set to true only concrete classes.
+ ///
+ public static IEnumerable FindClassesWithAttribute(IEnumerable assemblies, bool onlyConcreteClasses)
+ where T : Attribute
+ {
+ return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
+ }
- ///
- /// Finds any classes with the attribute.
- ///
- /// The attribute type
- /// The assemblies.
- /// if set to true only concrete classes.
- ///
- public static IEnumerable FindClassesWithAttribute(
- Type attributeType,
- IEnumerable assemblies,
- bool onlyConcreteClasses)
- {
- if (assemblies == null) throw new ArgumentNullException("assemblies");
+ ///
+ /// Finds any classes with the attribute.
+ ///
+ /// The attribute type
+ /// The assemblies.
+ /// if set to true only concrete classes.
+ ///
+ public static IEnumerable FindClassesWithAttribute(
+ Type attributeType,
+ IEnumerable assemblies,
+ bool onlyConcreteClasses)
+ {
+ if (assemblies == null) throw new ArgumentNullException("assemblies");
- if (TypeHelper.IsTypeAssignableFrom(attributeType) == false)
- throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
+ if (TypeHelper.IsTypeAssignableFrom(attributeType) == false)
+ throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
- var foundAssignableTypes = new List();
+ var foundAssignableTypes = new HashSet();
var assemblyList = assemblies.ToArray();
@@ -418,71 +430,74 @@ namespace Umbraco.Core
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(attributeType, assemblyList);
foreach (var a in referencedAssemblies)
- {
+ {
//get all types in the assembly that are sub types of the current type
var allTypes = GetTypesWithFormattedException(a).ToArray();
-
- var types = allTypes.Where(t => TypeHelper.IsNonStaticClass(t)
- && (onlyConcreteClasses == false || t.IsAbstract == false)
- //the type must have this attribute
+
+ var types = allTypes.Where(t => TypeHelper.IsNonStaticClass(t)
+ && (onlyConcreteClasses == false || t.IsAbstract == false)
+ //the type must have this attribute
&& t.GetCustomAttributes(attributeType, false).Any());
- foundAssignableTypes.AddRange(types);
- }
+ foreach (var t in types)
+ {
+ foundAssignableTypes.Add(t);
+ }
+ }
- return foundAssignableTypes;
- }
+ return foundAssignableTypes;
+ }
- ///
- /// Finds the classes with attribute.
- ///
- ///
- /// The assemblies.
- ///
- public static IEnumerable FindClassesWithAttribute(IEnumerable assemblies)
- where T : Attribute
- {
- return FindClassesWithAttribute(assemblies, true);
- }
+ ///
+ /// Finds the classes with attribute.
+ ///
+ ///
+ /// The assemblies.
+ ///
+ public static IEnumerable FindClassesWithAttribute(IEnumerable assemblies)
+ where T : Attribute
+ {
+ return FindClassesWithAttribute(assemblies, true);
+ }
- ///
- /// Finds the classes with attribute in filtered local assemblies
- ///
- ///
- ///
- public static IEnumerable FindClassesWithAttribute()
- where T : Attribute
- {
- return FindClassesWithAttribute(GetAssembliesWithKnownExclusions());
- }
+ ///
+ /// Finds the classes with attribute in filtered local assemblies
+ ///
+ ///
+ ///
+ public static IEnumerable FindClassesWithAttribute()
+ where T : Attribute
+ {
+ return FindClassesWithAttribute(GetAssembliesWithKnownExclusions());
+ }
- #region Private methods
-
- ///
- /// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
- /// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
- /// deriving from the base type.
- ///
- ///
- ///
- ///
- /// An additional filter to apply for what types will actually be included in the return value
- ///
- private static IEnumerable GetClasses(
- Type assignTypeFrom,
- IEnumerable assemblies,
+ #region Private methods
+
+ ///
+ /// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
+ /// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
+ /// deriving from the base type.
+ ///
+ ///
+ ///
+ ///
+ /// An additional filter to apply for what types will actually be included in the return value
+ ///
+ private static IEnumerable GetClasses(
+ Type assignTypeFrom,
+ IEnumerable assemblies,
bool onlyConcreteClasses,
Func additionalFilter = null)
- {
+ {
//the default filter will always return true.
if (additionalFilter == null)
{
additionalFilter = type => true;
}
- var foundAssignableTypes = new List();
+ var foundAssignableTypes = new HashSet();
var assemblyList = assemblies.ToArray();
@@ -510,8 +525,11 @@ namespace Umbraco.Core
.ToArray();
//add the types to our list to return
- foundAssignableTypes.AddRange(filteredTypes);
-
+ foreach (var t in filteredTypes)
+ {
+ foundAssignableTypes.Add(t);
+ }
+
//now we need to include types that may be inheriting from sub classes of the type being searched for
//so we will search in assemblies that reference those types too.
foreach (var subTypesInAssembly in allSubTypes.GroupBy(x => x.Assembly))
@@ -529,55 +547,62 @@ namespace Umbraco.Core
//if there's a base class amongst the types then we'll only search for that type.
//otherwise we'll have to search for all of them.
- var subTypesToSearch = new List();
+ var subTypesToSearch = new HashSet();
if (baseClassAttempt.Success)
{
subTypesToSearch.Add(baseClassAttempt.Result);
}
else
{
- subTypesToSearch.AddRange(subTypeList);
+ foreach (var t in subTypeList)
+ {
+ subTypesToSearch.Add(t);
+ }
}
-
+
foreach (var typeToSearch in subTypesToSearch)
{
//recursively find the types inheriting from this sub type in the other non-scanned assemblies.
var foundTypes = GetClasses(typeToSearch, otherAssemblies, onlyConcreteClasses, additionalFilter);
- foundAssignableTypes.AddRange(foundTypes);
+
+ foreach (var f in foundTypes)
+ {
+ foundAssignableTypes.Add(f);
+ }
}
-
+
}
- }
- return foundAssignableTypes;
- }
+ }
+ return foundAssignableTypes;
+ }
- private static IEnumerable GetTypesWithFormattedException(Assembly a)
- {
- //if the assembly is dynamic, do not try to scan it
- if (a.IsDynamic)
- return Enumerable.Empty();
+ private static IEnumerable GetTypesWithFormattedException(Assembly a)
+ {
+ //if the assembly is dynamic, do not try to scan it
+ if (a.IsDynamic)
+ return Enumerable.Empty();
- try
- {
+ try
+ {
//return a.GetExportedTypes();
return a.GetTypes();
- }
- catch (ReflectionTypeLoadException ex)
- {
- var sb = new StringBuilder();
- sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
- foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
- {
- sb.AppendLine("Exception: " + loaderException);
- }
- throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
- }
- }
+ }
+ catch (ReflectionTypeLoadException ex)
+ {
+ var sb = new StringBuilder();
+ sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
+ foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
+ {
+ sb.AppendLine("Exception: " + loaderException);
+ }
+ throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
+ }
+ }
- #endregion
+ #endregion
-
- }
+
+ }
}
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs
index 2086b9b5d0..efa50075bf 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
+using System.Web;
using System.Xml.Linq;
using System.Xml.XPath;
using Examine;
@@ -16,6 +17,7 @@ using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Tests.TestHelpers;
+using Umbraco.Tests.TestHelpers.Entities;
using Umbraco.Tests.UmbracoExamine;
using Umbraco.Web;
using Umbraco.Web.PublishedCache;
@@ -68,6 +70,38 @@ namespace Umbraco.Tests.PublishedContent
return GetNode(id, GetUmbracoContext("/test", 1234));
}
+ [Test]
+ public void Get_Property_Value_Uses_Converter()
+ {
+ var mType = MockedContentTypes.CreateImageMediaType();
+ //lets add an RTE to this
+ mType.PropertyGroups.First().PropertyTypes.Add(
+ new PropertyType(new Guid(), DataTypeDatabaseType.Nvarchar)
+ {
+ Alias = "content",
+ Name = "Rich Text",
+ DataTypeDefinitionId = -87 //tiny mce
+ });
+ ServiceContext.ContentTypeService.Save(mType);
+ var media = MockedMedia.CreateMediaImage(mType, -1);
+ media.Properties["content"].Value = "
This is some content
";
+ ServiceContext.MediaService.Save(media);
+
+ var publishedMedia = GetNode(media.Id);
+
+ var propVal = publishedMedia.GetPropertyValue("content");
+ Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(propVal.GetType()));
+ Assert.AreEqual("