Moved more abstractions of models

This commit is contained in:
Bjarke Berg
2019-05-27 11:54:17 +02:00
parent dcf022ffaa
commit 00a121188a
24 changed files with 33 additions and 56 deletions

View File

@@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Umbraco.Core.Dictionary
{
/// <summary>
/// Represents a dictionary based on a specific culture
/// </summary>
public interface ICultureDictionary
{
/// <summary>
/// Returns the dictionary value based on the key supplied
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
string this[string key] { get; }
/// <summary>
/// Returns the current culture
/// </summary>
CultureInfo Culture { get; }
/// <summary>
/// Returns the child dictionary entries for a given key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
IDictionary<string, string> GetChildren(string key);
}
}

View File

@@ -1,7 +0,0 @@
namespace Umbraco.Core.Dictionary
{
public interface ICultureDictionaryFactory
{
ICultureDictionary CreateDictionary();
}
}

View File

@@ -1,46 +0,0 @@
using System;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models
{
/// <summary>
/// Describes the states of a document, with regard to (schedule) publishing.
/// </summary>
[Serializable]
[DataContract]
public enum ContentStatus
{
// typical flow:
// Unpublished (add release date)-> AwaitingRelease (release)-> Published (expire)-> Expired
/// <summary>
/// The document is not trashed, and not published.
/// </summary>
[EnumMember]
Unpublished,
/// <summary>
/// The document is published.
/// </summary>
[EnumMember]
Published,
/// <summary>
/// The document is not trashed, not published, after being unpublished by a scheduled action.
/// </summary>
[EnumMember]
Expired,
/// <summary>
/// The document is trashed.
/// </summary>
[EnumMember]
Trashed,
/// <summary>
/// The document is not trashed, not published, and pending publication by a scheduled action.
/// </summary>
[EnumMember]
AwaitingRelease
}
}

View File

@@ -1,75 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Manages the built-in fallback policies.
/// </summary>
public struct Fallback : IEnumerable<int>
{
private readonly int[] _values;
/// <summary>
/// Initializes a new instance of the <see cref="Fallback"/> struct with values.
/// </summary>
private Fallback(int[] values)
{
_values = values;
}
/// <summary>
/// Gets an ordered set of fallback policies.
/// </summary>
/// <param name="values"></param>
public static Fallback To(params int[] values) => new Fallback(values);
/// <summary>
/// Do not fallback.
/// </summary>
public const int None = 0;
/// <summary>
/// Fallback to default value.
/// </summary>
public const int DefaultValue = 1;
/// <summary>
/// Gets the fallback to default value policy.
/// </summary>
public static Fallback ToDefaultValue => new Fallback(new[] { DefaultValue });
/// <summary>
/// Fallback to other languages.
/// </summary>
public const int Language = 2;
/// <summary>
/// Gets the fallback to language policy.
/// </summary>
public static Fallback ToLanguage => new Fallback(new[] { Language });
/// <summary>
/// Fallback to tree ancestors.
/// </summary>
public const int Ancestors = 3;
/// <summary>
/// Gets the fallback to tree ancestors policy.
/// </summary>
public static Fallback ToAncestors => new Fallback(new[] { Ancestors });
/// <inheritdoc />
public IEnumerator<int> GetEnumerator()
{
return ((IEnumerable<int>)_values ?? Array.Empty<int>()).GetEnumerator();
}
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@@ -1,13 +0,0 @@
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Gives access to the current <see cref="VariationContext"/>.
/// </summary>
public interface IVariationContextAccessor
{
/// <summary>
/// Gets or sets the current <see cref="VariationContext"/>.
/// </summary>
VariationContext VariationContext { get; set; }
}
}

View File

@@ -1,411 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Umbraco.Core.Exceptions;
namespace Umbraco.Core.Models.PublishedContent
{
/// <inheritdoc />
/// <summary>
/// Represents the CLR type of a model.
/// </summary>
/// <example>
/// ModelType.For("alias")
/// typeof (IEnumerable{}).MakeGenericType(ModelType.For("alias"))
/// Model.For("alias").MakeArrayType()
/// </example>
public class ModelType : Type
{
private ModelType(string contentTypeAlias)
{
if (string.IsNullOrWhiteSpace(contentTypeAlias)) throw new ArgumentNullOrEmptyException(nameof(contentTypeAlias));
ContentTypeAlias = contentTypeAlias;
Name = "{" + ContentTypeAlias + "}";
}
/// <summary>
/// Gets the content type alias.
/// </summary>
public string ContentTypeAlias { get; }
/// <inheritdoc />
public override string ToString()
=> Name;
/// <summary>
/// Gets the model type for a published element type.
/// </summary>
/// <param name="alias">The published element type alias.</param>
/// <returns>The model type for the published element type.</returns>
public static ModelType For(string alias)
=> new ModelType(alias);
/// <summary>
/// Gets the actual CLR type by replacing model types, if any.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="modelTypes">The model types map.</param>
/// <returns>The actual CLR type.</returns>
public static Type Map(Type type, Dictionary<string, Type> modelTypes)
=> Map(type, modelTypes, false);
public static Type Map(Type type, Dictionary<string, Type> modelTypes, bool dictionaryIsInvariant)
{
// it may be that senders forgot to send an invariant dictionary (garbage-in)
if (!dictionaryIsInvariant)
modelTypes = new Dictionary<string, Type>(modelTypes, StringComparer.InvariantCultureIgnoreCase);
if (type is ModelType modelType)
{
if (modelTypes.TryGetValue(modelType.ContentTypeAlias, out var actualType))
return actualType;
throw new InvalidOperationException($"Don't know how to map ModelType with content type alias \"{modelType.ContentTypeAlias}\".");
}
if (type is ModelTypeArrayType arrayType)
{
if (modelTypes.TryGetValue(arrayType.ContentTypeAlias, out var actualType))
return actualType.MakeArrayType();
throw new InvalidOperationException($"Don't know how to map ModelType with content type alias \"{arrayType.ContentTypeAlias}\".");
}
if (type.IsGenericType == false)
return type;
var def = type.GetGenericTypeDefinition();
if (def == null)
throw new InvalidOperationException("panic");
var args = type.GetGenericArguments().Select(x => Map(x, modelTypes, true)).ToArray();
return def.MakeGenericType(args);
}
/// <summary>
/// Gets the actual CLR type name by replacing model types, if any.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="map">The model types map.</param>
/// <returns>The actual CLR type name.</returns>
public static string MapToName(Type type, Dictionary<string, string> map)
=> MapToName(type, map, false);
private static string MapToName(Type type, Dictionary<string, string> map, bool dictionaryIsInvariant)
{
// it may be that senders forgot to send an invariant dictionary (garbage-in)
if (!dictionaryIsInvariant)
map = new Dictionary<string, string>(map, StringComparer.InvariantCultureIgnoreCase);
if (type is ModelType modelType)
{
if (map.TryGetValue(modelType.ContentTypeAlias, out var actualTypeName))
return actualTypeName;
throw new InvalidOperationException($"Don't know how to map ModelType with content type alias \"{modelType.ContentTypeAlias}\".");
}
if (type is ModelTypeArrayType arrayType)
{
if (map.TryGetValue(arrayType.ContentTypeAlias, out var actualTypeName))
return actualTypeName + "[]";
throw new InvalidOperationException($"Don't know how to map ModelType with content type alias \"{arrayType.ContentTypeAlias}\".");
}
if (type.IsGenericType == false)
return type.FullName;
var def = type.GetGenericTypeDefinition();
if (def == null)
throw new InvalidOperationException("panic");
var args = type.GetGenericArguments().Select(x => MapToName(x, map, true)).ToArray();
var defFullName = def.FullName.Substring(0, def.FullName.IndexOf('`'));
return defFullName + "<" + string.Join(", ", args) + ">";
}
/// <summary>
/// Gets a value indicating whether two <see cref="Type"/> instances are equal.
/// </summary>
/// <param name="t1">The first instance.</param>
/// <param name="t2">The second instance.</param>
/// <returns>A value indicating whether the two instances are equal.</returns>
/// <remarks>Knows how to compare <see cref="ModelType"/> instances.</remarks>
public static bool Equals(Type t1, Type t2)
{
if (t1 == t2)
return true;
if (t1 is ModelType m1 && t2 is ModelType m2)
return m1.ContentTypeAlias == m2.ContentTypeAlias;
if (t1 is ModelTypeArrayType a1 && t2 is ModelTypeArrayType a2)
return a1.ContentTypeAlias == a2.ContentTypeAlias;
if (t1.IsGenericType == false || t2.IsGenericType == false)
return false;
var args1 = t1.GetGenericArguments();
var args2 = t2.GetGenericArguments();
if (args1.Length != args2.Length) return false;
for (var i = 0; i < args1.Length; i++)
{
// ReSharper disable once CheckForReferenceEqualityInstead.2
if (Equals(args1[i], args2[i]) == false) return false;
}
return true;
}
/// <inheritdoc />
protected override TypeAttributes GetAttributeFlagsImpl()
=> TypeAttributes.Class;
/// <inheritdoc />
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
=> Array.Empty<ConstructorInfo>();
/// <inheritdoc />
protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
=> null;
/// <inheritdoc />
public override Type[] GetInterfaces()
=> Array.Empty<Type>();
/// <inheritdoc />
public override Type GetInterface(string name, bool ignoreCase)
=> null;
/// <inheritdoc />
public override EventInfo[] GetEvents(BindingFlags bindingAttr)
=> Array.Empty<EventInfo>();
/// <inheritdoc />
public override EventInfo GetEvent(string name, BindingFlags bindingAttr)
=> null;
/// <inheritdoc />
public override Type[] GetNestedTypes(BindingFlags bindingAttr)
=> Array.Empty<Type>();
/// <inheritdoc />
public override Type GetNestedType(string name, BindingFlags bindingAttr)
=> null;
/// <inheritdoc />
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
=> Array.Empty<PropertyInfo>();
/// <inheritdoc />
protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
=> null;
/// <inheritdoc />
public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
=> Array.Empty<MethodInfo>();
/// <inheritdoc />
protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
=> null;
/// <inheritdoc />
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
=> Array.Empty<FieldInfo>();
/// <inheritdoc />
public override FieldInfo GetField(string name, BindingFlags bindingAttr)
=> null;
/// <inheritdoc />
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
=> Array.Empty<MemberInfo>();
/// <inheritdoc />
public override object[] GetCustomAttributes(Type attributeType, bool inherit)
=> Array.Empty<object>();
/// <inheritdoc />
public override object[] GetCustomAttributes(bool inherit)
=> Array.Empty<object>();
/// <inheritdoc />
public override bool IsDefined(Type attributeType, bool inherit)
=> false;
/// <inheritdoc />
public override Type GetElementType()
=> null;
/// <inheritdoc />
protected override bool HasElementTypeImpl()
=> false;
/// <inheritdoc />
protected override bool IsArrayImpl()
=> false;
/// <inheritdoc />
protected override bool IsByRefImpl()
=> false;
/// <inheritdoc />
protected override bool IsPointerImpl()
=> false;
/// <inheritdoc />
protected override bool IsPrimitiveImpl()
=> false;
/// <inheritdoc />
protected override bool IsCOMObjectImpl()
=> false;
/// <inheritdoc />
public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
=> throw new NotSupportedException();
/// <inheritdoc />
public override Type UnderlyingSystemType => this;
/// <inheritdoc />
public override Type BaseType => null;
/// <inheritdoc />
public override string Name { get; }
/// <inheritdoc />
public override Guid GUID { get; } = Guid.NewGuid();
/// <inheritdoc />
public override Module Module => GetType().Module; // hackish but FullName requires something
/// <inheritdoc />
public override Assembly Assembly => GetType().Assembly; // hackish but FullName requires something
/// <inheritdoc />
public override string FullName => Name;
/// <inheritdoc />
public override string Namespace => string.Empty;
/// <inheritdoc />
public override string AssemblyQualifiedName => Name;
/// <inheritdoc />
public override Type MakeArrayType()
=> new ModelTypeArrayType(this);
}
internal class ModelTypeArrayType : Type
{
private readonly Type _elementType;
public ModelTypeArrayType(ModelType type)
{
_elementType = type;
ContentTypeAlias = type.ContentTypeAlias;
Name = "{" + type.ContentTypeAlias + "}[*]";
}
public string ContentTypeAlias { get; }
public override string ToString()
=> Name;
protected override TypeAttributes GetAttributeFlagsImpl()
=> TypeAttributes.Class;
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
=> Array.Empty<ConstructorInfo>();
protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
=> null;
public override Type[] GetInterfaces()
=> Array.Empty<Type>();
public override Type GetInterface(string name, bool ignoreCase)
=> null;
public override EventInfo[] GetEvents(BindingFlags bindingAttr)
=> Array.Empty<EventInfo>();
public override EventInfo GetEvent(string name, BindingFlags bindingAttr)
=> null;
public override Type[] GetNestedTypes(BindingFlags bindingAttr)
=> Array.Empty<Type>();
public override Type GetNestedType(string name, BindingFlags bindingAttr)
=> null;
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
=> Array.Empty<PropertyInfo>();
protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
=> null;
public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
=> Array.Empty<MethodInfo>();
protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
=> null;
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
=> Array.Empty<FieldInfo>();
public override FieldInfo GetField(string name, BindingFlags bindingAttr)
=> null;
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
=> Array.Empty<MemberInfo>();
public override object[] GetCustomAttributes(Type attributeType, bool inherit)
=> Array.Empty<object>();
public override object[] GetCustomAttributes(bool inherit)
=> Array.Empty<object>();
public override bool IsDefined(Type attributeType, bool inherit)
=> false;
public override Type GetElementType()
=> _elementType;
protected override bool HasElementTypeImpl()
=> true;
protected override bool IsArrayImpl()
=> true;
protected override bool IsByRefImpl()
=> false;
protected override bool IsPointerImpl()
=> false;
protected override bool IsPrimitiveImpl()
=> false;
protected override bool IsCOMObjectImpl()
=> false;
public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
{
throw new NotSupportedException();
}
public override Type UnderlyingSystemType => this;
public override Type BaseType => null;
public override string Name { get; }
public override Guid GUID { get; } = Guid.NewGuid();
public override Module Module =>GetType().Module; // hackish but FullName requires something
public override Assembly Assembly => GetType().Assembly; // hackish but FullName requires something
public override string FullName => Name;
public override string Namespace => string.Empty;
public override string AssemblyQualifiedName => Name;
public override int GetArrayRank()
=> 1;
}
}

View File

@@ -1,50 +0,0 @@
using System;
using Umbraco.Core.Exceptions;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Contains culture specific values for <see cref="IPublishedContent"/>.
/// </summary>
public class PublishedCultureInfo
{
/// <summary>
/// Initializes a new instance of the <see cref="PublishedCultureInfo"/> class.
/// </summary>
public PublishedCultureInfo(string culture, string name, string urlSegment, DateTime date)
{
if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentNullOrEmptyException(nameof(culture));
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
Culture = culture;
Name = name;
UrlSegment = urlSegment;
Date = date;
}
/// <summary>
/// Gets the culture.
/// </summary>
public string Culture { get; }
/// <summary>
/// Gets the name of the item.
/// </summary>
public string Name { get; }
/// <summary>
/// Gets the url segment of the item.
/// </summary>
public string UrlSegment { get; }
/// <summary>
/// Gets the date associated with the culture.
/// </summary>
/// <remarks>
/// <para>For published culture, this is the date the culture was published. For draft
/// cultures, this is the date the culture was made available, ie the last time its
/// name changed.</para>
/// </remarks>
public DateTime Date { get; }
}
}

View File

@@ -1,62 +0,0 @@
using System;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Represents a published data type.
/// </summary>
/// <remarks>
/// <para>Instances of the <see cref="PublishedDataType"/> class are immutable, ie
/// if the data type changes, then a new class needs to be created.</para>
/// <para>These instances should be created by an <see cref="IPublishedContentTypeFactory"/>.</para>
/// </remarks>
public class PublishedDataType
{
private readonly Lazy<object> _lazyConfiguration;
/// <summary>
/// Initializes a new instance of the <see cref="PublishedDataType"/> class.
/// </summary>
internal PublishedDataType(int id, string editorAlias, Lazy<object> lazyConfiguration)
{
_lazyConfiguration = lazyConfiguration;
Id = id;
EditorAlias = editorAlias;
}
/// <summary>
/// Gets the datatype identifier.
/// </summary>
public int Id { get; }
/// <summary>
/// Gets the data type editor alias.
/// </summary>
public string EditorAlias { get; }
/// <summary>
/// Gets the data type configuration.
/// </summary>
public object Configuration => _lazyConfiguration.Value;
/// <summary>
/// Gets the configuration object.
/// </summary>
/// <typeparam name="T">The expected type of the configuration object.</typeparam>
/// <exception cref="InvalidCastException">When the datatype configuration is not of the expected type.</exception>
public T ConfigurationAs<T>()
where T : class
{
switch (Configuration)
{
case null:
return null;
case T configurationAsT:
return configurationAsT;
}
throw new InvalidCastException($"Cannot cast dataType configuration, of type {Configuration.GetType().Name}, to {typeof(T).Name}.");
}
}
}

View File

@@ -1,34 +0,0 @@
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// The type of published element.
/// </summary>
/// <remarks>Can be a simple element, or a document, a media, a member.</remarks>
public enum PublishedItemType
{
/// <summary>
/// Unknown.
/// </summary>
Unknown = 0,
/// <summary>
/// An element.
/// </summary>
Element,
/// <summary>
/// A document.
/// </summary>
Content,
/// <summary>
/// A media.
/// </summary>
Media,
/// <summary>
/// A member.
/// </summary>
Member
}
}

View File

@@ -1,23 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Provides a CurrentUICulture-based implementation of <see cref="IVariationContextAccessor"/>.
/// </summary>
/// <remarks>
/// <para>This accessor does not support segments. There is no need to set the current context.</para>
/// </remarks>
public class ThreadCultureVariationContextAccessor : IVariationContextAccessor
{
private readonly ConcurrentDictionary<string, VariationContext> _contexts = new ConcurrentDictionary<string, VariationContext>();
public VariationContext VariationContext
{
get => _contexts.GetOrAdd(Thread.CurrentThread.CurrentUICulture.Name, culture => new VariationContext(culture));
set => throw new NotSupportedException();
}
}
}

View File

@@ -1,27 +0,0 @@
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Represents the variation context.
/// </summary>
public class VariationContext
{
/// <summary>
/// Initializes a new instance of the <see cref="VariationContext"/> class.
/// </summary>
public VariationContext(string culture = null, string segment = null)
{
Culture = culture ?? ""; // cannot be null, default to invariant
Segment = segment ?? ""; // cannot be null, default to neutral
}
/// <summary>
/// Gets the culture.
/// </summary>
public string Culture { get; }
/// <summary>
/// Gets the segment.
/// </summary>
public string Segment { get; }
}
}

View File

@@ -1,74 +0,0 @@
using System;
using System.Runtime.Serialization;
using Umbraco.Core.Models.Entities;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a Relation between two items
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public class Relation : EntityBase, IRelation
{
//NOTE: The datetime column from umbracoRelation is set on CreateDate on the Entity
private int _parentId;
private int _childId;
private IRelationType _relationType;
private string _comment;
public Relation(int parentId, int childId, IRelationType relationType)
{
_parentId = parentId;
_childId = childId;
_relationType = relationType;
}
/// <summary>
/// Gets or sets the Parent Id of the Relation (Source)
/// </summary>
[DataMember]
public int ParentId
{
get => _parentId;
set => SetPropertyValueAndDetectChanges(value, ref _parentId, nameof(ParentId));
}
/// <summary>
/// Gets or sets the Child Id of the Relation (Destination)
/// </summary>
[DataMember]
public int ChildId
{
get => _childId;
set => SetPropertyValueAndDetectChanges(value, ref _childId, nameof(ChildId));
}
/// <summary>
/// Gets or sets the <see cref="RelationType"/> for the Relation
/// </summary>
[DataMember]
public IRelationType RelationType
{
get => _relationType;
set => SetPropertyValueAndDetectChanges(value, ref _relationType, nameof(RelationType));
}
/// <summary>
/// Gets or sets a comment for the Relation
/// </summary>
[DataMember]
public string Comment
{
get => _comment;
set => SetPropertyValueAndDetectChanges(value, ref _comment, nameof(Comment));
}
/// <summary>
/// Gets the Id of the <see cref="RelationType"/> that this Relation is based on.
/// </summary>
[IgnoreDataMember]
public int RelationTypeId => _relationType.Id;
}
}

View File

@@ -1,90 +0,0 @@
using System;
using System.Runtime.Serialization;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Models.Entities;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a RelationType
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public class RelationType : EntityBase, IRelationType
{
private string _name;
private string _alias;
private bool _isBidrectional;
private Guid _parentObjectType;
private Guid _childObjectType;
public RelationType(Guid childObjectType, Guid parentObjectType, string alias)
{
if (string.IsNullOrWhiteSpace(alias)) throw new ArgumentNullOrEmptyException(nameof(alias));
_childObjectType = childObjectType;
_parentObjectType = parentObjectType;
_alias = alias;
Name = _alias;
}
public RelationType(Guid childObjectType, Guid parentObjectType, string alias, string name)
: this(childObjectType, parentObjectType, alias)
{
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
Name = name;
}
/// <summary>
/// Gets or sets the Name of the RelationType
/// </summary>
[DataMember]
public string Name
{
get => _name;
set => SetPropertyValueAndDetectChanges(value, ref _name, nameof(Name));
}
/// <summary>
/// Gets or sets the Alias of the RelationType
/// </summary>
[DataMember]
public string Alias
{
get => _alias;
set => SetPropertyValueAndDetectChanges(value, ref _alias, nameof(Alias));
}
/// <summary>
/// Gets or sets a boolean indicating whether the RelationType is Bidirectional (true) or Parent to Child (false)
/// </summary>
[DataMember]
public bool IsBidirectional
{
get => _isBidrectional;
set => SetPropertyValueAndDetectChanges(value, ref _isBidrectional, nameof(IsBidirectional));
}
/// <summary>
/// Gets or sets the Parents object type id
/// </summary>
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
[DataMember]
public Guid ParentObjectType
{
get => _parentObjectType;
set => SetPropertyValueAndDetectChanges(value, ref _parentObjectType, nameof(ParentObjectType));
}
/// <summary>
/// Gets or sets the Childs object type id
/// </summary>
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
[DataMember]
public Guid ChildObjectType
{
get => _childObjectType;
set => SetPropertyValueAndDetectChanges(value, ref _childObjectType, nameof(ChildObjectType));
}
}
}

View File

@@ -1,174 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Runtime.Serialization;
using Umbraco.Core.Strings.Css;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a Stylesheet file
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public class Stylesheet : File
{
public Stylesheet(string path)
: this(path, null)
{ }
internal Stylesheet(string path, Func<File, string> getFileContent)
: base(string.IsNullOrEmpty(path) ? path : path.EnsureEndsWith(".css"), getFileContent)
{
InitializeProperties();
}
private Lazy<List<StylesheetProperty>> _properties;
private void InitializeProperties()
{
//if the value is already created, we need to be created and update the collection according to
//what is now in the content
if (_properties != null && _properties.IsValueCreated)
{
//re-parse it so we can check what properties are different and adjust the event handlers
var parsed = StylesheetHelper.ParseRules(Content).ToArray();
var names = parsed.Select(x => x.Name).ToArray();
var existing = _properties.Value.Where(x => names.InvariantContains(x.Name)).ToArray();
//update existing
foreach (var stylesheetProperty in existing)
{
var updateFrom = parsed.Single(x => x.Name.InvariantEquals(stylesheetProperty.Name));
//remove current event handler while we update, we'll reset it after
stylesheetProperty.PropertyChanged -= Property_PropertyChanged;
stylesheetProperty.Alias = updateFrom.Selector;
stylesheetProperty.Value = updateFrom.Styles;
//re-add
stylesheetProperty.PropertyChanged += Property_PropertyChanged;
}
//remove no longer existing
var nonExisting = _properties.Value.Where(x => names.InvariantContains(x.Name) == false).ToArray();
foreach (var stylesheetProperty in nonExisting)
{
stylesheetProperty.PropertyChanged -= Property_PropertyChanged;
_properties.Value.Remove(stylesheetProperty);
}
//add new ones
var newItems = parsed.Where(x => _properties.Value.Select(p => p.Name).InvariantContains(x.Name) == false);
foreach (var stylesheetRule in newItems)
{
var prop = new StylesheetProperty(stylesheetRule.Name, stylesheetRule.Selector, stylesheetRule.Styles);
prop.PropertyChanged += Property_PropertyChanged;
_properties.Value.Add(prop);
}
}
//we haven't read the properties yet so create the lazy delegate
_properties = new Lazy<List<StylesheetProperty>>(() =>
{
var parsed = StylesheetHelper.ParseRules(Content);
return parsed.Select(statement =>
{
var property = new StylesheetProperty(statement.Name, statement.Selector, statement.Styles);
property.PropertyChanged += Property_PropertyChanged;
return property;
}).ToList();
});
}
/// <summary>
/// If the property has changed then we need to update the content
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Property_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
var prop = (StylesheetProperty) sender;
//Ensure we are setting base.Content here so that the properties don't get reset and thus any event handlers would get reset too
base.Content = StylesheetHelper.ReplaceRule(Content, prop.Name, new StylesheetRule
{
Name = prop.Name,
Selector = prop.Alias,
Styles = prop.Value
});
}
/// <summary>
/// Gets or sets the Content of a File
/// </summary>
public override string Content
{
get { return base.Content; }
set
{
base.Content = value;
//re-set the properties so they are re-read from the content
InitializeProperties();
}
}
/// <summary>
/// Returns a list of umbraco back office enabled stylesheet properties
/// </summary>
/// <remarks>
/// An umbraco back office enabled stylesheet property has a special prefix, for example:
///
/// /** umb_name: MyPropertyName */ p { font-size: 1em; }
/// </remarks>
[IgnoreDataMember]
public IEnumerable<StylesheetProperty> Properties
{
get { return _properties.Value; }
}
/// <summary>
/// Adds an Umbraco stylesheet property for use in the back office
/// </summary>
/// <param name="property"></param>
public void AddProperty(StylesheetProperty property)
{
if (Properties.Any(x => x.Name.InvariantEquals(property.Name)))
{
throw new DuplicateNameException("The property with the name " + property.Name + " already exists in the collection");
}
//now we need to serialize out the new property collection over-top of the string Content.
Content = StylesheetHelper.AppendRule(Content, new StylesheetRule
{
Name = property.Name,
Selector = property.Alias,
Styles = property.Value
});
//re-set lazy collection
InitializeProperties();
}
/// <summary>
/// Removes an Umbraco stylesheet property
/// </summary>
/// <param name="name"></param>
public void RemoveProperty(string name)
{
if (Properties.Any(x => x.Name.InvariantEquals(name)))
{
Content = StylesheetHelper.ReplaceRule(Content, name, null);
}
}
/// <summary>
/// Indicates whether the current entity has an identity, which in this case is a path/name.
/// </summary>
/// <remarks>
/// Overrides the default Entity identity check.
/// </remarks>
public override bool HasIdentity
{
get { return string.IsNullOrEmpty(Path) == false; }
}
}
}

View File

@@ -1,51 +0,0 @@
using System;
using System.Runtime.Serialization;
using Umbraco.Core.Models.Entities;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a Stylesheet Property
/// </summary>
/// <remarks>
/// Properties are always formatted to have a single selector, so it can be used in the backoffice
/// </remarks>
[Serializable]
[DataContract(IsReference = true)]
public class StylesheetProperty : BeingDirtyBase, IValueObject
{
private string _alias;
private string _value;
public StylesheetProperty(string name, string @alias, string value)
{
Name = name;
_alias = alias;
_value = value;
}
/// <summary>
/// The CSS rule name that can be used by Umbraco in the back office
/// </summary>
public string Name { get; private set; }
/// <summary>
/// This is the CSS Selector
/// </summary>
public string Alias
{
get => _alias;
set => SetPropertyValueAndDetectChanges(value, ref _alias, nameof(Alias));
}
/// <summary>
/// The CSS value for the selector
/// </summary>
public string Value
{
get => _value;
set => SetPropertyValueAndDetectChanges(value, ref _value, nameof(Value));
}
}
}

View File

@@ -1,59 +0,0 @@
using System;
using System.Runtime.Serialization;
using Umbraco.Core.Models.Entities;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a tag entity.
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
public class Tag : EntityBase, ITag
{
private string _group;
private string _text;
private int? _languageId;
/// <summary>
/// Initializes a new instance of the <see cref="Tag"/> class.
/// </summary>
public Tag()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="Tag"/> class.
/// </summary>
public Tag(int id, string group, string text, int? languageId = null)
{
Id = id;
Text = text;
Group = group;
LanguageId = languageId;
}
/// <inheritdoc />
public string Group
{
get => _group;
set => SetPropertyValueAndDetectChanges(value, ref _group, nameof(Group));
}
/// <inheritdoc />
public string Text
{
get => _text;
set => SetPropertyValueAndDetectChanges(value, ref _text, nameof(Text));
}
/// <inheritdoc />
public int? LanguageId
{
get => _languageId;
set => SetPropertyValueAndDetectChanges(value, ref _languageId, nameof(LanguageId));
}
/// <inheritdoc />
public int NodeCount { get; internal set; }
}
}

View File

@@ -1,13 +0,0 @@
namespace Umbraco.Core.Models
{
/// <summary>
/// Enum representing the taggable object types
/// </summary>
public enum TaggableObjectTypes
{
All,
Content,
Media,
Member
}
}

View File

@@ -1,31 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a tagged entity.
/// </summary>
/// <remarks>Note that it is the properties of an entity (like Content, Media, Members, etc.) that are tagged,
/// which is why this class is composed of a list of tagged properties and the identifier the actual entity.</remarks>
public class TaggedEntity
{
/// <summary>
/// Initializes a new instance of the <see cref="TaggedEntity"/> class.
/// </summary>
public TaggedEntity(int entityId, IEnumerable<TaggedProperty> taggedProperties)
{
EntityId = entityId;
TaggedProperties = taggedProperties;
}
/// <summary>
/// Gets the identifier of the entity.
/// </summary>
public int EntityId { get; }
/// <summary>
/// Gets the tagged properties.
/// </summary>
public IEnumerable<TaggedProperty> TaggedProperties { get; }
}
}

View File

@@ -1,35 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a tagged property on an entity.
/// </summary>
public class TaggedProperty
{
/// <summary>
/// Initializes a new instance of the <see cref="TaggedProperty"/> class.
/// </summary>
public TaggedProperty(int propertyTypeId, string propertyTypeAlias, IEnumerable<ITag> tags)
{
PropertyTypeId = propertyTypeId;
PropertyTypeAlias = propertyTypeAlias;
Tags = tags;
}
/// <summary>
/// Gets the identifier of the property type.
/// </summary>
public int PropertyTypeId { get; }
/// <summary>
/// Gets the alias of the property type.
/// </summary>
public string PropertyTypeAlias { get; }
/// <summary>
/// Gets the tags.
/// </summary>
public IEnumerable<ITag> Tags { get; }
}
}

View File

@@ -1,20 +0,0 @@
namespace Umbraco.Core.Models
{
/// <summary>
/// Defines how tags are stored.
/// </summary>
/// <remarks>Tags are always stored as a string, but the string can
/// either be a delimited string, or a serialized Json array.</remarks>
public enum TagsStorageType
{
/// <summary>
/// Store tags as a delimited string.
/// </summary>
Csv,
/// <summary>
/// Store tags as serialized Json.
/// </summary>
Json
}
}

View File

@@ -1,34 +0,0 @@
using System.Collections.Generic;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a template in a template tree
/// </summary>
public class TemplateNode
{
public TemplateNode(ITemplate template)
{
Template = template;
Children = new List<TemplateNode>();
}
/// <summary>
/// The current template
/// </summary>
public ITemplate Template { get; set; }
/// <summary>
/// The children of the current template
/// </summary>
public IEnumerable<TemplateNode> Children { get; set; }
/// <summary>
/// The parent template to the current template
/// </summary>
/// <remarks>
/// Will be null if there is no parent
/// </remarks>
public TemplateNode Parent { get; set; }
}
}

View File

@@ -1,15 +0,0 @@
using System;
namespace Umbraco.Core.Scoping
{
/// <summary>
/// Exposes an instance unique identifier.
/// </summary>
public interface IInstanceIdentifiable
{
/// <summary>
/// Gets the instance unique identifier.
/// </summary>
Guid InstanceId { get; }
}
}

View File

@@ -1,50 +0,0 @@
using System;
namespace Umbraco.Core.Scoping
{
/// <summary>
/// Represents a scope context.
/// </summary>
/// <remarks>A scope context can enlist objects that will be attached to the scope, and available
/// for the duration of the scope. In addition, it can enlist actions, that will run when the
/// scope is exiting, and after the database transaction has been committed.</remarks>
public interface IScopeContext
{
/// <summary>
/// Enlists an action.
/// </summary>
/// <param name="key">The action unique identifier.</param>
/// <param name="action">The action.</param>
/// <param name="priority">The optional action priority (default is 100, lower runs first).</param>
/// <remarks>
/// <para>It is ok to enlist multiple action with the same key but only the first one will run.</para>
/// <para>The action boolean parameter indicates whether the scope completed or not.</para>
/// </remarks>
void Enlist(string key, Action<bool> action, int priority = 100);
/// <summary>
/// Enlists an object and action.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="key">The object unique identifier.</param>
/// <param name="creator">A function providing the object.</param>
/// <param name="action">The optional action.</param>
/// <param name="priority">The optional action priority (default is 100, lower runs first).</param>
/// <returns>The object.</returns>
/// <remarks>
/// <para>On the first time an object is enlisted with a given key, the object is actually
/// created. Next calls just return the existing object. It is ok to enlist multiple objects
/// and action with the same key but only the first one is used, the others are ignored.</para>
/// <para>The action boolean parameter indicates whether the scope completed or not.</para>
/// </remarks>
T Enlist<T>(string key, Func<T> creator, Action<bool, T> action = null, int priority = 100);
/// <summary>
/// Gets an enlisted object.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="key">The object unique identifier.</param>
/// <returns>The enlisted object, if any, else the default value.</returns>
T GetEnlisted<T>(string key);
}
}

View File

@@ -176,6 +176,23 @@
<Compile Include="CompositionExtensions_FileSystems.cs" />
<Compile Include="CompositionExtensions_Uniques.cs" />
<Compile Include="Configuration\UmbracoVersion.cs" />
<Compile Include="Constants-Applications.cs" />
<Compile Include="Constants-AppSettings.cs" />
<Compile Include="Constants-Composing.cs" />
<Compile Include="Constants-Conventions.cs" />
<Compile Include="Constants-DatabaseProviders.cs" />
<Compile Include="Constants-DataTypes.cs" />
<Compile Include="Constants-DeploySelector.cs" />
<Compile Include="Constants-Icons.cs" />
<Compile Include="Constants-Indexes.cs" />
<Compile Include="Constants-ObjectTypes.cs" />
<Compile Include="Constants-PackageRepository.cs" />
<Compile Include="Constants-PropertyEditors.cs" />
<Compile Include="Constants-PropertyTypeGroups.cs" />
<Compile Include="Constants-Security.cs" />
<Compile Include="Constants-System.cs" />
<Compile Include="Constants-Web.cs" />
<Compile Include="Constants.cs" />
<Compile Include="FactoryExtensions.cs" />
<Compile Include="Composing\RegisterFactory.cs" />
<Compile Include="Composing\Current.cs" />
@@ -222,6 +239,19 @@
<Compile Include="Models\PropertyCollection.cs" />
<Compile Include="Models\PublicAccessEntry.cs" />
<Compile Include="Models\PublishedContent\ILivePublishedModelFactory.cs" />
<Compile Include="Models\PublishedContent\IndexedArrayItem.cs" />
<Compile Include="Models\PublishedContent\IPublishedContent.cs" />
<Compile Include="Models\PublishedContent\IPublishedContentTypeFactory.cs" />
<Compile Include="Models\PublishedContent\IPublishedElement.cs" />
<Compile Include="Models\PublishedContent\IPublishedModelFactory.cs" />
<Compile Include="Models\PublishedContent\IPublishedProperty.cs" />
<Compile Include="Models\PublishedContent\IPublishedValueFallback.cs" />
<Compile Include="Models\PublishedContent\PublishedContentType.cs" />
<Compile Include="Models\PublishedContent\PublishedElementModel.cs" />
<Compile Include="Models\PublishedContent\PublishedElementWrapped.cs" />
<Compile Include="Models\PublishedContent\VariationContextAccessorExtensions.cs" />
<Compile Include="Models\Template.cs" />
<Compile Include="Models\TemplateOnDisk.cs" />
<Compile Include="Persistence\Dtos\PropertyTypeCommonDto.cs" />
<Compile Include="Persistence\Factories\MacroFactory.cs" />
<Compile Include="Persistence\Repositories\Implement\ContentTypeCommonRepository.cs" />
@@ -284,23 +314,6 @@
<Compile Include="Configuration\UmbracoSettings\UmbracoSettingsSection.cs" />
<Compile Include="Configuration\UmbracoSettings\UrlReplacingElement.cs" />
<Compile Include="Configuration\UmbracoSettings\WebRoutingElement.cs" />
<Compile Include="Constants-Applications.cs" />
<Compile Include="Constants-Conventions.cs" />
<Compile Include="Constants-DatabaseProviders.cs" />
<Compile Include="Constants-DataTypes.cs" />
<Compile Include="Constants-Composing.cs" />
<Compile Include="Constants-DeploySelector.cs" />
<Compile Include="Constants-Icons.cs" />
<Compile Include="Constants-ObjectTypes.cs" />
<Compile Include="Constants-PackageRepository.cs" />
<Compile Include="Constants-PropertyEditors.cs" />
<Compile Include="Constants-PropertyTypeGroups.cs" />
<Compile Include="Constants-Security.cs" />
<Compile Include="Constants-System.cs" />
<Compile Include="Constants-Indexes.cs" />
<Compile Include="Constants-AppSettings.cs" />
<Compile Include="Constants-Web.cs" />
<Compile Include="Constants.cs" />
<Compile Include="RegisterExtensions.cs" />
<Compile Include="ContentVariationExtensions.cs" />
<Compile Include="Deploy\IDataTypeConfigurationConnector.cs" />
@@ -413,14 +426,7 @@
<Compile Include="Models\Packaging\CompiledPackageFile.cs" />
<Compile Include="Models\PathValidationExtensions.cs" />
<Compile Include="Models\PropertyTagsExtensions.cs" />
<Compile Include="Models\PublishedContent\Fallback.cs" />
<Compile Include="Models\PublishedContent\NoopPublishedValueFallback.cs" />
<Compile Include="Models\PublishedContent\PublishedCultureInfos.cs" />
<Compile Include="Models\PublishedContent\IVariationContextAccessor.cs" />
<Compile Include="Models\PublishedContent\IPublishedValueFallback.cs" />
<Compile Include="Models\PublishedContent\VariationContext.cs" />
<Compile Include="Models\PublishedContent\ThreadCultureVariationContextAccessor.cs" />
<Compile Include="Models\PublishedContent\VariationContextAccessorExtensions.cs" />
<Compile Include="Models\SimpleContentType.cs" />
<Compile Include="PackageActions\AllowDoctype.cs" />
<Compile Include="PackageActions\PublishRootDocument.cs" />
@@ -519,8 +525,6 @@
<Compile Include="Deploy\IUniqueIdentifyingServiceConnector.cs" />
<Compile Include="Deploy\IValueConnector.cs" />
<Compile Include="Diagnostics\MiniDump.cs" />
<Compile Include="Dictionary\ICultureDictionary.cs" />
<Compile Include="Dictionary\ICultureDictionaryFactory.cs" />
<Compile Include="EmailSender.cs" />
<Compile Include="Events\CancellableEventArgs.cs" />
<Compile Include="Events\CancellableObjectEventArgs.cs" />
@@ -607,7 +611,6 @@
<Compile Include="Models\Content.cs" />
<Compile Include="Models\ContentBase.cs" />
<Compile Include="ContentExtensions.cs" />
<Compile Include="Models\ContentStatus.cs" />
<Compile Include="Models\ContentType.cs" />
<Compile Include="Models\ContentTypeAvailableCompositionsResult.cs" />
<Compile Include="Models\ContentTypeAvailableCompositionsResults.cs" />
@@ -643,26 +646,14 @@
<Compile Include="Models\PropertyGroupCollection.cs" />
<Compile Include="Models\PropertyType.cs" />
<Compile Include="Models\PropertyTypeCollection.cs" />
<Compile Include="Models\PublishedContent\IndexedArrayItem.cs" />
<Compile Include="Models\PublishedContent\IPublishedContent.cs" />
<Compile Include="Models\PublishedContent\IPublishedContentTypeFactory.cs" />
<Compile Include="Models\PublishedContent\IPublishedModelFactory.cs" />
<Compile Include="Models\PublishedContent\IPublishedElement.cs" />
<Compile Include="Models\PublishedContent\IPublishedProperty.cs" />
<Compile Include="Models\PublishedContent\ModelType.cs" />
<Compile Include="Models\PublishedContent\NoopPublishedModelFactory.cs" />
<Compile Include="Models\PublishedContent\PublishedContentTypeFactory.cs" />
<Compile Include="Models\PublishedContent\PublishedDataType.cs" />
<Compile Include="Models\PublishedContent\PublishedElementModel.cs" />
<Compile Include="Models\PublishedContent\PublishedElementWrapped.cs" />
<Compile Include="Models\PublishedContent\PublishedContentExtensionsForModels.cs" />
<Compile Include="Models\PublishedContent\PublishedContentModel.cs" />
<Compile Include="Models\PublishedContent\PublishedModelAttribute.cs" />
<Compile Include="Models\PublishedContent\PublishedModelFactory.cs" />
<Compile Include="Models\PublishedContent\PublishedContentType.cs" />
<Compile Include="Models\PublishedContent\PublishedContentTypeConverter.cs" />
<Compile Include="Models\PublishedContent\PublishedContentWrapped.cs" />
<Compile Include="Models\PublishedContent\PublishedItemType.cs" />
<Compile Include="Models\PublishedContent\PublishedPropertyBase.cs" />
<Compile Include="Models\PublishedContent\PublishedPropertyType.cs" />
<Compile Include="Models\PublishedContent\PublishedSearchResult.cs" />
@@ -714,19 +705,7 @@
<Compile Include="Persistence\Dtos\UserGroup2NodePermissionDto.cs" />
<Compile Include="Persistence\Dtos\UserGroupDto.cs" />
<Compile Include="Persistence\Dtos\UserStartNodeDto.cs" />
<Compile Include="Models\Relation.cs" />
<Compile Include="Models\RelationType.cs" />
<Compile Include="Models\ServerRegistration.cs" />
<Compile Include="Models\Stylesheet.cs" />
<Compile Include="Models\StylesheetProperty.cs" />
<Compile Include="Models\Tag.cs" />
<Compile Include="Models\TagsStorageType.cs" />
<Compile Include="Models\TaggableObjectTypes.cs" />
<Compile Include="Models\TaggedEntity.cs" />
<Compile Include="Models\TaggedProperty.cs" />
<Compile Include="Models\Template.cs" />
<Compile Include="Models\TemplateNode.cs" />
<Compile Include="Models\TemplateOnDisk.cs" />
<Compile Include="Models\UmbracoDomain.cs" />
<Compile Include="Models\UmbracoObjectTypes.cs" />
<Compile Include="Models\ObjectTypes.cs" />
@@ -1142,10 +1121,8 @@
<Compile Include="ReflectionUtilities.cs" />
<Compile Include="RuntimeState.cs" />
<Compile Include="Runtime\CoreInitialComposer.cs" />
<Compile Include="Scoping\IInstanceIdentifiable.cs" />
<Compile Include="Scoping\IScope.cs" />
<Compile Include="Scoping\IScopeAccessor.cs" />
<Compile Include="Scoping\IScopeContext.cs" />
<Compile Include="Scoping\IScopeProvider.cs" />
<Compile Include="Scoping\RepositoryCacheMode.cs" />
<Compile Include="Scoping\Scope.cs" />