Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allows for base classing of Element types #211

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file added src/._SolutionInfo.cs
Binary file not shown.
11 changes: 10 additions & 1 deletion src/Umbraco.ModelsBuilder/Building/Builder.cs
Expand Up @@ -329,9 +329,18 @@ public string GetModelsNamespace()
protected string GetModelsBaseClassName(TypeModel type)
{
// code attribute overrides everything
if (ParseResult.HasModelsBaseClassName)
if (ParseResult.HasModelsBaseClassName && !type.IsElement && !ParseResult.HasSelectiveModelsBaseClassName(type.Alias))
return ParseResult.ModelsBaseClassName;

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";
}
Expand Down
15 changes: 15 additions & 0 deletions src/Umbraco.ModelsBuilder/Building/CodeParser.cs
Expand Up @@ -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);
Expand All @@ -205,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;

}
}
}
Expand Down
79 changes: 78 additions & 1 deletion src/Umbraco.ModelsBuilder/Building/ParseResult.cs
Expand Up @@ -40,6 +40,8 @@ internal class ParseResult
private readonly HashSet<string> _withCtor
= new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);

private Dictionary<string, string> _selectiveModelsBaseClassNameOverides = new Dictionary<string, string>();

public static readonly ParseResult Empty = new ParseResult();

private class StaticMixinMethodInfo
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -129,6 +139,11 @@ public void SetModelsBaseClassName(string modelsBaseClassName)
ModelsBaseClassName = modelsBaseClassName;
}

public void SetElementModelsBaseClassName(string elementModelsBaseClassName)
{
ElementModelsBaseClassName = elementModelsBaseClassName;
}

public void SetModelsNamespace(string modelsNamespace)
{
ModelsNamespace = modelsNamespace;
Expand Down Expand Up @@ -161,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);
Expand All @@ -180,6 +200,15 @@ private static bool IsContentOrMixinIgnored(string contentAlias, HashSet<string>
.Any(x => contentAlias.StartsWith(x, StringComparison.InvariantCultureIgnoreCase));
}

private static bool IsContentOrMixinIncluded(string contentAlias, HashSet<string> 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);
Expand Down Expand Up @@ -244,7 +273,55 @@ 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<string,string>()))
{
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
{
Expand Down
16 changes: 16 additions & 0 deletions src/Umbraco.ModelsBuilder/ElementModelsBaseClassAttribute.cs
@@ -0,0 +1,16 @@
using System;

namespace Umbraco.ModelsBuilder
{
/// <summary>
/// Indicates the default base class for element models.
/// </summary>
/// <remarks>Otherwise it is PublishedElementModel. Would make sense to inherit from PublishedElementModel.</remarks>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
public sealed class ElementModelsBaseClassAttribute : Attribute
{
public ElementModelsBaseClassAttribute(Type type)
{}
}
}

16 changes: 16 additions & 0 deletions src/Umbraco.ModelsBuilder/SelectiveModelsBaseClassAttribute.cs
@@ -0,0 +1,16 @@
using System;

namespace Umbraco.ModelsBuilder
{
/// <summary>
/// Indicates the default base class for models.
/// </summary>
/// <remarks>Otherwise it is PublishedContentModel. Would make sense to inherit from PublishedContentModel.</remarks>
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
public sealed class SelectiveModelsBaseClassAttribute : Attribute
{
public SelectiveModelsBaseClassAttribute(Type type, string alias)
{}
}
}

2 changes: 2 additions & 0 deletions src/Umbraco.ModelsBuilder/Umbraco.ModelsBuilder.csproj
Expand Up @@ -53,6 +53,8 @@
<Compile Include="Building\TextHeaderWriter.cs" />
<Compile Include="Configuration\ClrNameSource.cs" />
<Compile Include="Dashboard\BuilderDashboardHelper.cs" />
<Compile Include="ElementModelsBaseClassAttribute.cs" />
<Compile Include="SelectiveModelsBaseClassAttribute.cs" />
<Compile Include="ModelsBuilderAssemblyAttribute.cs" />
<Compile Include="PublishedElementExtensions.cs" />
<Compile Include="PureLiveAssemblyAttribute.cs" />
Expand Down