Skip to content

Commit

Permalink
[JPA] Big Bang : simplification et séparation des générateurs (pour f…
Browse files Browse the repository at this point in the history
…aciliter les futures évols)
  • Loading branch information
gideruette committed Nov 28, 2024
1 parent 4b47708 commit 27f4466
Show file tree
Hide file tree
Showing 40 changed files with 1,473 additions and 1,058 deletions.
15 changes: 3 additions & 12 deletions TopModel.Generator.Core/GeneratorConfigBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,14 @@ public IEnumerable<string> GetDecoratorImports(Endpoint endpoint, string tag)
.Distinct();
}

public IEnumerable<string> GetDomainAnnotations(IProperty property, string tag)
public IEnumerable<(string Annotation, IEnumerable<string> Imports)> GetDomainAnnotations(IProperty property, string tag)
{
if (property.Domain is not null)
{
foreach (var annotation in GetImplementation(property.Domain)!.Annotations
.Where(a => FilterAnnotations(a, property, tag))
.Select(a => a.Text.ParseTemplate(property, this, tag)))
.Where(a => FilterAnnotations(a, property, tag)))
{
yield return annotation;
yield return (Annotation: annotation.Text.ParseTemplate(property, this, tag), Imports: annotation.Imports.Select(i => i.ParseTemplate(property, this, tag)));
}
}
}
Expand All @@ -213,14 +212,6 @@ public IEnumerable<string> GetDomainImports(IProperty property, string tag)
{
yield return import;
}

var op = property switch
{
AssociationProperty ap => ap.Property,
AliasProperty { OriginalProperty: AssociationProperty ap } => ap.Property,
AliasProperty alp => alp.OriginalProperty,
_ => property
};
}
}

Expand Down
4 changes: 2 additions & 2 deletions TopModel.Generator.Csharp/CSharpClassGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ protected virtual void GenerateProperty(CSharpWriter w, IProperty property, Hash
&& !sameColumnSet.Contains(property.SqlName))
{
var sqlName = Config.UseLowerCaseSqlNames ? property.SqlName.ToLower() : property.SqlName;
if (!Config.GetDomainAnnotations(property, tag).Any(a => a.TrimStart('[').StartsWith("Column")))
if (!Config.GetDomainAnnotations(property, tag).Any(a => a.Annotation.TrimStart('[').StartsWith("Column")))
{
w.WriteAttribute(1, "Column", $@"""{sqlName}""");
}
Expand Down Expand Up @@ -404,7 +404,7 @@ protected virtual void GenerateProperty(CSharpWriter w, IProperty property, Hash
foreach (var annotation in Config.GetDomainAnnotations(property, tag))
{
w.WriteAttribute(1, annotation);
w.WriteAttribute(1, annotation.Annotation);
}
if (Config.IsPersistent(property.Class, tag) && property is AssociationProperty { Type: AssociationType.OneToMany or AssociationType.ManyToMany })
Expand Down
7 changes: 7 additions & 0 deletions TopModel.Generator.Jpa/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 1.1.0

Breaking changes :
- Suppression du mode `enumShortcut`
- Les DAO des listes de références ne sont plus générés. La première génération risque de les supprimer
- Annuler la suppression des DAO utilisés. Normalement, il y en a peu, d'où la suppression de la génération automatique...

## 1.0.11
- [d31beb](https://github.com/klee-contrib/topmodel/commit/d31beb5e0d42178e62f6b19316abcbbccde8884d) Fix Initialisation enum dans le cas d'alias ou d'association : cas null

Expand Down
13 changes: 12 additions & 1 deletion TopModel.Generator.Jpa/GeneratorRegistration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,18 @@ public void Register(IServiceCollection services, JpaConfig config, int number)

config.Language ??= "java";

services.AddGenerator<JpaModelGenerator, JpaConfig>(config, number);
services.AddGenerator<JavaDtoGenerator, JpaConfig>(config, number);
if (config.UseJdbc)
{
services.AddGenerator<JdbcEntityGenerator, JpaConfig>(config, number);
}
else
{
services.AddGenerator<JpaEnumEntityGenerator, JpaConfig>(config, number);
services.AddGenerator<JavaEnumDtoGenerator, JpaConfig>(config, number);
services.AddGenerator<JpaEntityGenerator, JpaConfig>(config, number);
}

services.AddGenerator<JpaModelInterfaceGenerator, JpaConfig>(config, number);
services.AddGenerator<JpaMapperGenerator, JpaConfig>(config, number);
services.AddGenerator<JpaEnumGenerator, JpaConfig>(config, number);
Expand Down
20 changes: 0 additions & 20 deletions TopModel.Generator.Jpa/ImportsJpaExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,6 @@ public static string GetImport(this Class classe, JpaConfig config, string tag)
return $"{config.GetPackageName(classe, config.GetBestClassTag(classe, tag))}.{classe.NamePascal}";
}

public static List<string> GetImports(this Class classe, JpaConfig config, string tag, IEnumerable<Class> availableClasses)
{
var imports = new List<string>();

if (classe.Extends != null)
{
imports.Add(classe.GetImport(config, config.GetBestClassTag(classe, tag)));
}

if (config.MappersInClass)
{
imports
.AddRange(classe.FromMappers.Where(fm => fm.ClassParams.All(fmp => availableClasses.Contains(fmp.Class))).SelectMany(fm => fm.ClassParams).Select(fmp => fmp.Class.GetImport(config, tag)));
imports
.AddRange(classe.ToMappers.Where(tm => availableClasses.Contains(tm.Class)).Select(fmp => fmp.Class.GetImport(config, config.GetBestClassTag(classe, tag))));
}

return imports;
}

public static List<string> GetKindImports(this CompositionProperty cp, JpaConfig config, string tag)
{
return config.GetDomainImports(cp, config.GetBestClassTag(cp.Composition, tag)).ToList();
Expand Down
73 changes: 73 additions & 0 deletions TopModel.Generator.Jpa/JavaAnnotation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
namespace TopModel.Generator.Jpa;

Check warning on line 1 in TopModel.Generator.Jpa/JavaAnnotation.cs

View workflow job for this annotation

GitHub Actions / build


public class JavaAnnotation
{
public JavaAnnotation(string name, string import)
{
Name = name.Trim('@');
Imports = [import];
}

public JavaAnnotation(string name, IEnumerable<string> imports)
{
Name = name.Trim('@');
Imports.AddRange(imports);
}

public JavaAnnotation(string name, string value, string import)
{
Name = name.Trim('@');
Imports = [import];
Attributes.Add(("value", value));
}

public string Name { get; set; }

public List<string> Imports { get; set; } = new();

private List<(string Name, object Value)> Attributes { get; } = new();

public JavaAnnotation AddAttribute(string name, string value, string import)
{
Attributes.Add((name, value));
Imports.Add(import);
return this;
}

public JavaAnnotation AddAttribute(string name, string value)
{
Attributes.Add((name, value));
return this;
}

public JavaAnnotation AddAttribute(string value)
{
Attributes.Add(("value", value));
return this;
}

public JavaAnnotation AddAttribute(string name, JavaAnnotation value)
{
Attributes.Add((name, value));
Imports.AddRange(value.Imports);
return this;
}

public override string ToString()
{
var name = Name.StartsWith('@') ? Name : $"@{Name}";
if (!Attributes.Any())
{
return name;
}
else if (Attributes.Count() == 1 && Attributes.Any(a => a.Name == "value"))
{
return $"{name}({Attributes.First().Value})";
}
else
{
var attributes = string.Join(", ", Attributes.Select(a => $"{a.Name} = {a.Value}"));
return $"{name}({attributes})";
}
}
}
175 changes: 175 additions & 0 deletions TopModel.Generator.Jpa/JavaClassGeneratorBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
using Microsoft.Extensions.Logging;

Check warning on line 1 in TopModel.Generator.Jpa/JavaClassGeneratorBase.cs

View workflow job for this annotation

GitHub Actions / build

using TopModel.Core;
using TopModel.Core.Model.Implementation;
using TopModel.Generator.Core;
using TopModel.Utils;

namespace TopModel.Generator.Jpa;

/// <summary>
/// Générateur de fichiers de modèles JPA.
/// </summary>
public abstract class JavaClassGeneratorBase : ClassGeneratorBase<JpaConfig>
{
private JavaConstructorGenerator? _jpaModelConstructorGenerator;
private JpaModelPropertyGenerator? _jpaModelPropertyGenerator;

public JavaClassGeneratorBase(ILogger<JavaClassGeneratorBase> logger)
: base(logger)
{
}

protected static Dictionary<string, string> NewableTypes => new()
{
["List"] = "ArrayList",
["Set"] = "HashSet"
};

protected string JavaxOrJakarta => Config.PersistenceMode.ToString().ToLower();

protected virtual JavaConstructorGenerator ConstructorGenerator
{
get
{
_jpaModelConstructorGenerator ??= new JavaConstructorGenerator(Config);
return _jpaModelConstructorGenerator;
}
}

protected JpaModelPropertyGenerator JpaModelPropertyGenerator
{
get
{
_jpaModelPropertyGenerator ??= new JpaModelPropertyGenerator(Config, Classes, NewableTypes);
return _jpaModelPropertyGenerator;
}
}

protected virtual void WriteAnnotations(JavaWriter fw, Class classe, string tag)
{
fw.WriteDocStart(0, classe.Comment);
fw.WriteDocEnd(0);
if (Config.GeneratedHint)
{
fw.AddImport($"{JavaxOrJakarta}.annotation.Generated");
fw.WriteLine("@Generated(\"TopModel : https://github.com/klee-contrib/topmodel\")");
}

fw.AddImports(Config.GetDecoratorImports(classe, tag).ToList());
foreach (var a in Config.GetDecoratorAnnotations(classe, tag))
{
fw.WriteLine($"{(a.StartsWith("@") ? string.Empty : "@")}{a}");
}
}

protected void WriteFieldsEnum(JavaWriter fw, Class classe, string tag)
{
if (!classe.Properties.Any())
{
return;
}

if (Config.FieldsEnumInterface != null)
{
fw.AddImport(Config.FieldsEnumInterface.Replace("<>", string.Empty));
}

fw.WriteLine();
fw.WriteDocStart(1, $"Enumération des champs de la classe {{@link {classe.GetImport(Config, tag)} {classe.NamePascal}}}");
fw.WriteDocEnd(1);
string enumDeclaration = @$"public enum Fields ";
if (Config.FieldsEnumInterface != null)
{
enumDeclaration += $"implements {Config.FieldsEnumInterface.Split(".").Last().Replace("<>", $"<{classe.NamePascal}>")}";
}

enumDeclaration += " {";
fw.WriteLine(1, enumDeclaration);

var props = classe.GetProperties(Classes).Select(prop =>
{
string name;
if (prop is AssociationProperty ap && ap.Association.IsPersistent && !Config.UseJdbc)
{
name = ap.NameByClassCamel.ToConstantCase();
}
else
{
name = prop.NameCamel.ToConstantCase();
}

var javaType = Config.GetType(prop, useClassForAssociation: classe.IsPersistent && !Config.UseJdbc && prop is AssociationProperty asp && asp.Association.IsPersistent);
javaType = javaType.Split("<")[0];
return $" {name}({javaType}.class)";
});

fw.WriteLine(string.Join(", //\n", props) + ";");

fw.WriteLine();

fw.WriteLine(2, "private final Class<?> type;");
fw.WriteLine();
fw.WriteLine(2, "Fields(Class<?> type) {");
fw.WriteLine(3, "this.type = type;");
fw.WriteLine(2, "}");

fw.WriteLine();

fw.WriteLine(2, "public Class<?> getType() {");
fw.WriteLine(3, "return this.type;");
fw.WriteLine(2, "}");

fw.WriteLine(1, "}");
}

protected virtual void WriteGetters(JavaWriter fw, Class classe, string tag)
{
foreach (var property in classe.GetProperties(Classes))
{
JpaModelPropertyGenerator.WriteGetter(fw, tag, property);
}
}

protected virtual void WriteSetters(JavaWriter fw, Class classe, string tag)
{
foreach (var property in classe.GetProperties(Classes))
{
JpaModelPropertyGenerator.WriteSetter(fw, tag, property);
}
}

protected void WriteToMappers(JavaWriter fw, Class classe, string tag)
{
var toMappers = classe.ToMappers.Where(p => Classes.Contains(p.Class)).Select(m => (classe, m))
.OrderBy(m => m.m.Name)
.ToList();

foreach (var toMapper in toMappers)
{
var (clazz, mapper) = toMapper;
fw.AddImport(mapper.Class.GetImport(Config, tag));
fw.WriteLine();
fw.WriteDocStart(1, $"Mappe '{classe}' vers '{mapper.Class.NamePascal}'");
if (mapper.Comment != null)
{
fw.WriteLine(1, $" * {mapper.Comment}");
}

fw.WriteParam("target", $"Instance pré-existante de '{mapper.Class.NamePascal}'. Une nouvelle instance sera créée si non spécifié.");
fw.WriteReturns(1, $"Une instance de '{mapper.Class.NamePascal}'");

fw.WriteDocEnd(1);
var (mapperNs, mapperModelPath) = Config.GetMapperLocation(toMapper);

fw.WriteLine(1, $"public {mapper.Class.NamePascal} {mapper.Name.Value.ToCamelCase()}({mapper.Class.NamePascal} target) {{");
fw.WriteLine(2, $"return {Config.GetMapperName(mapperNs, mapperModelPath)}.{mapper.Name.Value.ToCamelCase()}(this, target);");
fw.AddImport(Config.GetMapperImport(mapperNs, mapperModelPath, tag)!);
fw.WriteLine(1, "}");

if (toMappers.IndexOf(toMapper) < toMappers.Count - 1)
{
fw.WriteLine();
}
}
}
}
Loading

0 comments on commit 27f4466

Please sign in to comment.