From 15fd75f7e3a4ad09be0d214470a440209ae2b620 Mon Sep 17 00:00:00 2001 From: pgregorynz Date: Thu, 8 Aug 2019 18:14:23 +1000 Subject: [PATCH 1/4] Update Builder.cs Ignores types that are of type PublishedElementModel when applying a custom base class attribute --- src/Umbraco.ModelsBuilder/Building/Builder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.ModelsBuilder/Building/Builder.cs b/src/Umbraco.ModelsBuilder/Building/Builder.cs index bd6bef8c..cf9f6a84 100644 --- a/src/Umbraco.ModelsBuilder/Building/Builder.cs +++ b/src/Umbraco.ModelsBuilder/Building/Builder.cs @@ -329,7 +329,7 @@ public string GetModelsNamespace() protected string GetModelsBaseClassName(TypeModel type) { // code attribute overrides everything - if (ParseResult.HasModelsBaseClassName) + if (ParseResult.HasModelsBaseClassName && !type.IsElement) return ParseResult.ModelsBaseClassName; // default From bbb30deda08f10d6ef512493d2913e3e6f2759f2 Mon Sep 17 00:00:00 2001 From: pgregorynz Date: Thu, 8 Aug 2019 18:38:22 +1000 Subject: [PATCH 2/4] Fixes issue #205 - allow elements to have a base class Adds the ability to create a Element base class --- src/._SolutionInfo.cs | Bin 0 -> 4096 bytes src/Umbraco.ModelsBuilder/Building/Builder.cs | 3 +++ .../Building/CodeParser.cs | 7 +++++++ .../Building/ParseResult.cs | 11 +++++++++++ .../ElementModelsBaseClassAttribute.cs | 16 ++++++++++++++++ .../Umbraco.ModelsBuilder.csproj | 1 + 6 files changed, 38 insertions(+) create mode 100644 src/._SolutionInfo.cs create mode 100644 src/Umbraco.ModelsBuilder/ElementModelsBaseClassAttribute.cs diff --git a/src/._SolutionInfo.cs b/src/._SolutionInfo.cs new file mode 100644 index 0000000000000000000000000000000000000000..b3cbed0cae2328088c5e22736d964ff2ea55f826 GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIUt(=a103vVtCWL z5Tb)&0Z_RBnifVNA1W@DoS&i z3Zh5BXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeD;0ggyXA^|MKrSRBvsj@h zwK%`DC^=OjEx#yRAv3QeHLoNyKQA#Sr&1v&HLXM;DJL;68`u|y>Kf7%s{i3$kztVg G{~rLr-z)zB literal 0 HcmV?d00001 diff --git a/src/Umbraco.ModelsBuilder/Building/Builder.cs b/src/Umbraco.ModelsBuilder/Building/Builder.cs index cf9f6a84..22dea964 100644 --- a/src/Umbraco.ModelsBuilder/Building/Builder.cs +++ b/src/Umbraco.ModelsBuilder/Building/Builder.cs @@ -332,6 +332,9 @@ protected string GetModelsBaseClassName(TypeModel type) if (ParseResult.HasModelsBaseClassName && !type.IsElement) return ParseResult.ModelsBaseClassName; + if (ParseResult.HasElementModelsBaseClassName && type.IsElement) + return ParseResult.ElementModelsBaseClassName; + // default return type.IsElement ? "PublishedElementModel" : "PublishedContentModel"; } diff --git a/src/Umbraco.ModelsBuilder/Building/CodeParser.cs b/src/Umbraco.ModelsBuilder/Building/CodeParser.cs index 30fcbf1f..40199214 100644 --- a/src/Umbraco.ModelsBuilder/Building/CodeParser.cs +++ b/src/Umbraco.ModelsBuilder/Building/CodeParser.cs @@ -196,6 +196,13 @@ private static void ParseAssemblySymbols(ParseResult disco, ISymbol symbol) disco.SetModelsBaseClassName(SymbolDisplay.ToDisplayString(modelsBaseClass)); break; + case "Umbraco.ModelsBuilder.ElementModelsBaseClassAttribute": + var elementModelsBaseClass = (INamedTypeSymbol)attrData.ConstructorArguments[0].Value; + if (elementModelsBaseClass is IErrorTypeSymbol) + throw new Exception($"Invalid base class type \"{elementModelsBaseClass.Name}\"."); + disco.SetElementModelsBaseClassName(SymbolDisplay.ToDisplayString(elementModelsBaseClass)); + break; + case "Umbraco.ModelsBuilder.ModelsNamespaceAttribute": var modelsNamespace= (string) attrData.ConstructorArguments[0].Value; disco.SetModelsNamespace(modelsNamespace); diff --git a/src/Umbraco.ModelsBuilder/Building/ParseResult.cs b/src/Umbraco.ModelsBuilder/Building/ParseResult.cs index d1f61363..8ff90df7 100644 --- a/src/Umbraco.ModelsBuilder/Building/ParseResult.cs +++ b/src/Umbraco.ModelsBuilder/Building/ParseResult.cs @@ -129,6 +129,11 @@ public void SetModelsBaseClassName(string modelsBaseClassName) ModelsBaseClassName = modelsBaseClassName; } + public void SetElementModelsBaseClassName(string elementModelsBaseClassName) + { + ElementModelsBaseClassName = elementModelsBaseClassName; + } + public void SetModelsNamespace(string modelsNamespace) { ModelsNamespace = modelsNamespace; @@ -244,7 +249,13 @@ public bool HasModelsBaseClassName get { return !string.IsNullOrWhiteSpace(ModelsBaseClassName); } } + public bool HasElementModelsBaseClassName + { + get { return !string.IsNullOrWhiteSpace(ElementModelsBaseClassName); } + } + public string ModelsBaseClassName { get; private set; } + public string ElementModelsBaseClassName { get; private set; } public bool HasModelsNamespace { diff --git a/src/Umbraco.ModelsBuilder/ElementModelsBaseClassAttribute.cs b/src/Umbraco.ModelsBuilder/ElementModelsBaseClassAttribute.cs new file mode 100644 index 00000000..94e1fa3b --- /dev/null +++ b/src/Umbraco.ModelsBuilder/ElementModelsBaseClassAttribute.cs @@ -0,0 +1,16 @@ +using System; + +namespace Umbraco.ModelsBuilder +{ + /// + /// Indicates the default base class for element models. + /// + /// Otherwise it is PublishedElementModel. Would make sense to inherit from PublishedElementModel. + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] + public sealed class ElementModelsBaseClassAttribute : Attribute + { + public ElementModelsBaseClassAttribute(Type type) + {} + } +} + diff --git a/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj b/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj index 2ff90a27..729d2b20 100644 --- a/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj +++ b/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj @@ -53,6 +53,7 @@ + From f9124dc56ba103311c5fd973e0764923067f6565 Mon Sep 17 00:00:00 2001 From: pgregorynz Date: Tue, 20 Aug 2019 19:59:31 +1000 Subject: [PATCH 3/4] Allows for selective base models --- src/Umbraco.ModelsBuilder/Building/Builder.cs | 10 ++- .../Building/CodeParser.cs | 8 +++ .../Building/ParseResult.cs | 68 ++++++++++++++++++- .../SelectiveModelsBaseClassAttribute.cs | 16 +++++ .../Umbraco.ModelsBuilder.csproj | 1 + 5 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.ModelsBuilder/SelectiveModelsBaseClassAttribute.cs diff --git a/src/Umbraco.ModelsBuilder/Building/Builder.cs b/src/Umbraco.ModelsBuilder/Building/Builder.cs index 22dea964..80239c69 100644 --- a/src/Umbraco.ModelsBuilder/Building/Builder.cs +++ b/src/Umbraco.ModelsBuilder/Building/Builder.cs @@ -329,12 +329,18 @@ public string GetModelsNamespace() protected string GetModelsBaseClassName(TypeModel type) { // code attribute overrides everything - if (ParseResult.HasModelsBaseClassName && !type.IsElement) + if (ParseResult.HasModelsBaseClassName && !type.IsElement && !ParseResult.HasSelectiveModelsBaseClassName(type.Alias)) return ParseResult.ModelsBaseClassName; - if (ParseResult.HasElementModelsBaseClassName && type.IsElement) + if (ParseResult.HasElementModelsBaseClassName && type.IsElement && !ParseResult.HasSelectiveModelsBaseClassName(type.Alias)) return ParseResult.ElementModelsBaseClassName; + if (ParseResult.HasSelectiveModelsBaseClassName(type.Alias) && !type.IsElement) { + var selectiveBaseClass = ParseResult.GetSelectiveModelsBaseClassName(type.Alias); + if (!string.IsNullOrEmpty(selectiveBaseClass)) + return selectiveBaseClass; + } + // default return type.IsElement ? "PublishedElementModel" : "PublishedContentModel"; } diff --git a/src/Umbraco.ModelsBuilder/Building/CodeParser.cs b/src/Umbraco.ModelsBuilder/Building/CodeParser.cs index 40199214..bf411926 100644 --- a/src/Umbraco.ModelsBuilder/Building/CodeParser.cs +++ b/src/Umbraco.ModelsBuilder/Building/CodeParser.cs @@ -212,6 +212,14 @@ private static void ParseAssemblySymbols(ParseResult disco, ISymbol symbol) var usingNamespace = (string)attrData.ConstructorArguments[0].Value; disco.SetUsingNamespace(usingNamespace); break; + case "Umbraco.ModelsBuilder.SelectiveModelsBaseClassAttribute": + var selectiveModelsBaseClass = (INamedTypeSymbol)attrData.ConstructorArguments[0].Value; + if (selectiveModelsBaseClass is IErrorTypeSymbol) + throw new Exception($"Invalid base class type \"{selectiveModelsBaseClass.Name}\"."); + var contentAliasToInclude = (string)attrData.ConstructorArguments[1].Value; + disco.SetSelectiveContent(contentAliasToInclude, SymbolDisplay.ToDisplayString(selectiveModelsBaseClass)); + break; + } } } diff --git a/src/Umbraco.ModelsBuilder/Building/ParseResult.cs b/src/Umbraco.ModelsBuilder/Building/ParseResult.cs index 8ff90df7..ffc169a3 100644 --- a/src/Umbraco.ModelsBuilder/Building/ParseResult.cs +++ b/src/Umbraco.ModelsBuilder/Building/ParseResult.cs @@ -40,6 +40,8 @@ private readonly Dictionary> _staticMixins private readonly HashSet _withCtor = new HashSet(StringComparer.InvariantCultureIgnoreCase); + private Dictionary _selectiveModelsBaseClassNameOverides = new Dictionary(); + public static readonly ParseResult Empty = new ParseResult(); private class StaticMixinMethodInfo @@ -80,6 +82,14 @@ public void SetIgnoredContent(string contentAlias /*, bool ignoreContent, bool i // _ignoredMixinProperties.Add(contentAlias); } + // content with that alias should included to be generated + // alias can end with a * (wildcard) + public void SetSelectiveContent(string contentAlias, string baseClassName) + { + if (!_selectiveModelsBaseClassNameOverides.ContainsKey(contentAlias)) + _selectiveModelsBaseClassNameOverides.Add(contentAlias, baseClassName); + } + // content with that alias should be generated with a different name public void SetRenamedContent(string contentAlias, string contentName, bool withImplement) { @@ -166,11 +176,16 @@ public bool IsIgnored(string contentAlias) return IsContentOrMixinIgnored(contentAlias, _ignoredContent); } + public bool IsIncluded(string contentAlias) + { + return IsContentOrMixinIncluded(contentAlias, _ignoredContent); + } + //public bool IsMixinIgnored(string contentAlias) //{ // return IsContentOrMixinIgnored(contentAlias, _ignoredMixin); //} - + //public bool IsMixinPropertiesIgnored(string contentAlias) //{ // return IsContentOrMixinIgnored(contentAlias, _ignoredMixinProperties); @@ -185,6 +200,15 @@ private static bool IsContentOrMixinIgnored(string contentAlias, HashSet .Any(x => contentAlias.StartsWith(x, StringComparison.InvariantCultureIgnoreCase)); } + private static bool IsContentOrMixinIncluded(string contentAlias, HashSet included) + { + if (included.Contains(contentAlias)) return true; + return included + .Where(x => x.EndsWith("*")) + .Select(x => x.Substring(0, x.Length - 1)) + .Any(x => contentAlias.StartsWith(x, StringComparison.InvariantCultureIgnoreCase)); + } + public bool HasContentBase(string contentName) { return _contentBase.ContainsKey(contentName); @@ -249,14 +273,56 @@ public bool HasModelsBaseClassName get { return !string.IsNullOrWhiteSpace(ModelsBaseClassName); } } + public bool HasSelectiveModelsBaseClassName(string key) + { + if (_selectiveModelsBaseClassNameOverides.ContainsKey(key)) + return true; + + return _selectiveModelsBaseClassNameOverides.Keys.Any(x => + { + if (x.StartsWith("*")) + { + return key.EndsWith(x.Replace("*", string.Empty)); + } + return key.StartsWith(x.Replace("*", string.Empty)); + }); + } + + public string GetSelectiveModelsBaseClassName(string key) + { + if (_selectiveModelsBaseClassNameOverides.ContainsKey(key)) + { + return _selectiveModelsBaseClassNameOverides[key]; + } + + var retVal = _selectiveModelsBaseClassNameOverides.SingleOrDefault(x => + { + if (x.Key.StartsWith("*")) + { + return key.EndsWith(x.Key.Replace("*", string.Empty)); + } + return key.StartsWith(x.Key.Replace("*", string.Empty)); + }); + + if(!retVal.Equals(new KeyValuePair())) + { + return retVal.Value; + } + + return null; + } + public bool HasElementModelsBaseClassName { get { return !string.IsNullOrWhiteSpace(ElementModelsBaseClassName); } } + public string ModelsBaseClassName { get; private set; } public string ElementModelsBaseClassName { get; private set; } + + public bool HasModelsNamespace { get { return !string.IsNullOrWhiteSpace(ModelsNamespace); } diff --git a/src/Umbraco.ModelsBuilder/SelectiveModelsBaseClassAttribute.cs b/src/Umbraco.ModelsBuilder/SelectiveModelsBaseClassAttribute.cs new file mode 100644 index 00000000..920acb0c --- /dev/null +++ b/src/Umbraco.ModelsBuilder/SelectiveModelsBaseClassAttribute.cs @@ -0,0 +1,16 @@ +using System; + +namespace Umbraco.ModelsBuilder +{ + /// + /// Indicates the default base class for models. + /// + /// Otherwise it is PublishedContentModel. Would make sense to inherit from PublishedContentModel. + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] + public sealed class SelectiveModelsBaseClassAttribute : Attribute + { + public SelectiveModelsBaseClassAttribute(Type type, string alias) + {} + } +} + diff --git a/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj b/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj index 729d2b20..4fe5ab87 100644 --- a/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj +++ b/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj @@ -54,6 +54,7 @@ + From f7a00c7b963b19002d6692cee4a5943bab835089 Mon Sep 17 00:00:00 2001 From: Peter Gregory Date: Fri, 31 Jan 2020 14:40:53 +1000 Subject: [PATCH 4/4] Allows for selective element models --- src/Umbraco.ModelsBuilder/Building/Builder.cs | 13 +++- .../Building/CodeParser.cs | 10 ++- .../Building/ParseResult.cs | 62 +++++++++++++++++-- ...electiveElementModelsBaseClassAttribute.cs | 16 +++++ .../Umbraco.ModelsBuilder.csproj | 1 + 5 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 src/Umbraco.ModelsBuilder/SelectiveElementModelsBaseClassAttribute.cs diff --git a/src/Umbraco.ModelsBuilder/Building/Builder.cs b/src/Umbraco.ModelsBuilder/Building/Builder.cs index 80239c69..7ec34bfd 100644 --- a/src/Umbraco.ModelsBuilder/Building/Builder.cs +++ b/src/Umbraco.ModelsBuilder/Building/Builder.cs @@ -332,7 +332,7 @@ protected string GetModelsBaseClassName(TypeModel type) if (ParseResult.HasModelsBaseClassName && !type.IsElement && !ParseResult.HasSelectiveModelsBaseClassName(type.Alias)) return ParseResult.ModelsBaseClassName; - if (ParseResult.HasElementModelsBaseClassName && type.IsElement && !ParseResult.HasSelectiveModelsBaseClassName(type.Alias)) + if (ParseResult.HasElementModelsBaseClassName && type.IsElement && !ParseResult.HasSelectiveElementsModelsBaseClassName(type.Alias)) return ParseResult.ElementModelsBaseClassName; if (ParseResult.HasSelectiveModelsBaseClassName(type.Alias) && !type.IsElement) { @@ -341,8 +341,15 @@ protected string GetModelsBaseClassName(TypeModel type) return selectiveBaseClass; } - // default - return type.IsElement ? "PublishedElementModel" : "PublishedContentModel"; + if (ParseResult.HasSelectiveElementsModelsBaseClassName(type.Alias) && type.IsElement) + { + var selectiveBaseClass = ParseResult.GetSelectiveElementsModelsBaseClassName(type.Alias); + if (!string.IsNullOrEmpty(selectiveBaseClass)) + return selectiveBaseClass; + } + + // default + return type.IsElement ? "PublishedElementModel" : "PublishedContentModel"; } } } diff --git a/src/Umbraco.ModelsBuilder/Building/CodeParser.cs b/src/Umbraco.ModelsBuilder/Building/CodeParser.cs index bf411926..15cc3eff 100644 --- a/src/Umbraco.ModelsBuilder/Building/CodeParser.cs +++ b/src/Umbraco.ModelsBuilder/Building/CodeParser.cs @@ -203,7 +203,15 @@ private static void ParseAssemblySymbols(ParseResult disco, ISymbol symbol) disco.SetElementModelsBaseClassName(SymbolDisplay.ToDisplayString(elementModelsBaseClass)); break; - case "Umbraco.ModelsBuilder.ModelsNamespaceAttribute": + case "Umbraco.ModelsBuilder.SelectiveElementModelsBaseClassAttribute": + var selectiveElementModelsBaseClass = (INamedTypeSymbol)attrData.ConstructorArguments[0].Value; + if (selectiveElementModelsBaseClass is IErrorTypeSymbol) + throw new Exception($"Invalid base class type \"{selectiveElementModelsBaseClass.Name}\"."); + var elementAliasToInclude = (string)attrData.ConstructorArguments[1].Value; + disco.SetSelectiveElement(elementAliasToInclude, SymbolDisplay.ToDisplayString(selectiveElementModelsBaseClass)); + break; + + case "Umbraco.ModelsBuilder.ModelsNamespaceAttribute": var modelsNamespace= (string) attrData.ConstructorArguments[0].Value; disco.SetModelsNamespace(modelsNamespace); break; diff --git a/src/Umbraco.ModelsBuilder/Building/ParseResult.cs b/src/Umbraco.ModelsBuilder/Building/ParseResult.cs index ffc169a3..633fbd44 100644 --- a/src/Umbraco.ModelsBuilder/Building/ParseResult.cs +++ b/src/Umbraco.ModelsBuilder/Building/ParseResult.cs @@ -41,6 +41,7 @@ private readonly HashSet _withCtor = new HashSet(StringComparer.InvariantCultureIgnoreCase); private Dictionary _selectiveModelsBaseClassNameOverides = new Dictionary(); + private Dictionary _selectiveElementsModelsBaseClassNameOverides = new Dictionary(); public static readonly ParseResult Empty = new ParseResult(); @@ -90,8 +91,16 @@ public void SetSelectiveContent(string contentAlias, string baseClassName) _selectiveModelsBaseClassNameOverides.Add(contentAlias, baseClassName); } - // content with that alias should be generated with a different name - public void SetRenamedContent(string contentAlias, string contentName, bool withImplement) + // element with that alias should included to be generated + // alias can end with a * (wildcard) + public void SetSelectiveElement(string contentAlias, string baseClassName) + { + if (!_selectiveElementsModelsBaseClassNameOverides.ContainsKey(contentAlias)) + _selectiveElementsModelsBaseClassNameOverides.Add(contentAlias, baseClassName); + } + + // content with that alias should be generated with a different name + public void SetRenamedContent(string contentAlias, string contentName, bool withImplement) { _renamedContent[contentAlias] = contentName; if (withImplement) @@ -144,7 +153,8 @@ public void SetElementModelsBaseClassName(string elementModelsBaseClassName) ElementModelsBaseClassName = elementModelsBaseClassName; } - public void SetModelsNamespace(string modelsNamespace) + + public void SetModelsNamespace(string modelsNamespace) { ModelsNamespace = modelsNamespace; } @@ -288,7 +298,9 @@ public bool HasSelectiveModelsBaseClassName(string key) }); } - public string GetSelectiveModelsBaseClassName(string key) + + + public string GetSelectiveModelsBaseClassName(string key) { if (_selectiveModelsBaseClassNameOverides.ContainsKey(key)) { @@ -312,7 +324,47 @@ public string GetSelectiveModelsBaseClassName(string key) return null; } - public bool HasElementModelsBaseClassName + public bool HasSelectiveElementsModelsBaseClassName(string key) + { + if (_selectiveElementsModelsBaseClassNameOverides.ContainsKey(key)) + return true; + + return _selectiveElementsModelsBaseClassNameOverides.Keys.Any(x => + { + if (x.StartsWith("*")) + { + return key.EndsWith(x.Replace("*", string.Empty)); + } + return key.StartsWith(x.Replace("*", string.Empty)); + }); + } + + + public string GetSelectiveElementsModelsBaseClassName(string key) + { + if (_selectiveElementsModelsBaseClassNameOverides.ContainsKey(key)) + { + return _selectiveElementsModelsBaseClassNameOverides[key]; + } + + var retVal = _selectiveElementsModelsBaseClassNameOverides.SingleOrDefault(x => + { + if (x.Key.StartsWith("*")) + { + return key.EndsWith(x.Key.Replace("*", string.Empty)); + } + return key.StartsWith(x.Key.Replace("*", string.Empty)); + }); + + if (!retVal.Equals(new KeyValuePair())) + { + return retVal.Value; + } + + return null; + } + + public bool HasElementModelsBaseClassName { get { return !string.IsNullOrWhiteSpace(ElementModelsBaseClassName); } } diff --git a/src/Umbraco.ModelsBuilder/SelectiveElementModelsBaseClassAttribute.cs b/src/Umbraco.ModelsBuilder/SelectiveElementModelsBaseClassAttribute.cs new file mode 100644 index 00000000..c2c9953c --- /dev/null +++ b/src/Umbraco.ModelsBuilder/SelectiveElementModelsBaseClassAttribute.cs @@ -0,0 +1,16 @@ +using System; + +namespace Umbraco.ModelsBuilder +{ + /// + /// Indicates the default base class for element models. + /// + /// Otherwise it is PublishedElementModel. Would make sense to inherit from PublishedElementModel. + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] + public sealed class SelectiveElementModelsBaseClassAttribute : Attribute + { + public SelectiveElementModelsBaseClassAttribute(Type type, string alias) + {} + } +} + diff --git a/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj b/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj index 4fe5ab87..efce08a2 100644 --- a/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj +++ b/src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj @@ -53,6 +53,7 @@ +