diff --git a/TopModel.Core/FileModel/ModelFile.cs b/TopModel.Core/FileModel/ModelFile.cs index 6e36cad1..cc69125a 100644 --- a/TopModel.Core/FileModel/ModelFile.cs +++ b/TopModel.Core/FileModel/ModelFile.cs @@ -80,6 +80,7 @@ public class ModelFile .ToList(); public IList Properties => Classes.SelectMany(c => c.Properties) + .Concat(Classes.SelectMany(c => c.FromMapperProperties)) .Concat(Endpoints.SelectMany(e => e.Params)) .Concat(Endpoints.Select(e => e.Returns)) .Concat(Decorators.SelectMany(e => e.Properties)) diff --git a/TopModel.Core/Loaders/ClassLoader.cs b/TopModel.Core/Loaders/ClassLoader.cs index 4d3200f0..8d117934 100644 --- a/TopModel.Core/Loaders/ClassLoader.cs +++ b/TopModel.Core/Loaders/ClassLoader.cs @@ -98,10 +98,7 @@ public Class Load(Parser parser) case "properties": parser.ConsumeSequence(() => { - foreach (var property in _propertyLoader.Load(parser)) - { - classe.Properties.Add(property); - } + classe.Properties.Add(_propertyLoader.Load(parser)); }); break; case "unique": @@ -138,7 +135,7 @@ public Class Load(Parser parser) case "from": parser.ConsumeSequence(() => { - var mapper = new FromMapper(); + var mapper = new FromMapper { Class = classe }; classe.FromMappers.Add(mapper); parser.ConsumeMapping(prop => @@ -196,12 +193,10 @@ public Class Load(Parser parser) switch (prop.Value) { case "property": - foreach (var p in _propertyLoader.Load(parser)) - { - var param = new PropertyMapping { Property = p }; - mapper.Params.Add(param); - } - + var p = _propertyLoader.Load(parser); + var param = new PropertyMapping { Property = p, FromMapper = mapper }; + p.PropertyMapping = param; + mapper.Params.Add(param); break; case "target": var targetReference = new Reference(parser.Consume()); diff --git a/TopModel.Core/Loaders/DecoratorLoader.cs b/TopModel.Core/Loaders/DecoratorLoader.cs index 768ec9fe..6d8a7b7c 100644 --- a/TopModel.Core/Loaders/DecoratorLoader.cs +++ b/TopModel.Core/Loaders/DecoratorLoader.cs @@ -38,10 +38,7 @@ public Decorator Load(Parser parser) case "properties": parser.ConsumeSequence(() => { - foreach (var property in _propertyLoader.Load(parser)) - { - decorator.Properties.Add(property); - } + decorator.Properties.Add(_propertyLoader.Load(parser)); }); break; default: diff --git a/TopModel.Core/Loaders/EndpointLoader.cs b/TopModel.Core/Loaders/EndpointLoader.cs index a718e765..f7ab4456 100644 --- a/TopModel.Core/Loaders/EndpointLoader.cs +++ b/TopModel.Core/Loaders/EndpointLoader.cs @@ -45,17 +45,14 @@ public Endpoint Load(Parser parser) case "params": parser.ConsumeSequence(() => { - foreach (var property in _propertyLoader.Load(parser)) - { - property.Endpoint = endpoint; - endpoint.Params.Add(property); - } + var property = _propertyLoader.Load(parser); + property.Endpoint = endpoint; + endpoint.Params.Add(property); }); break; case "returns": - endpoint.Returns = _propertyLoader.Load(parser).First(); + endpoint.Returns = _propertyLoader.Load(parser); endpoint.Returns.Endpoint = endpoint; - parser.Consume(); break; case "decorators": parser.ConsumeSequence(() => diff --git a/TopModel.Core/Loaders/PropertyLoader.cs b/TopModel.Core/Loaders/PropertyLoader.cs index 4544006a..e653b465 100644 --- a/TopModel.Core/Loaders/PropertyLoader.cs +++ b/TopModel.Core/Loaders/PropertyLoader.cs @@ -4,7 +4,7 @@ namespace TopModel.Core.Loaders; -public class PropertyLoader : ILoader> +public class PropertyLoader : ILoader { private readonly ModelConfig _modelConfig; @@ -14,7 +14,7 @@ public PropertyLoader(ModelConfig modelConfig) } /// - public IEnumerable Load(Parser parser) + public IProperty Load(Parser parser) { parser.Consume(); switch (parser.Current) @@ -67,8 +67,8 @@ public IEnumerable Load(Parser parser) rp.Required = true; } - yield return rp; - break; + parser.Consume(); + return rp; case Scalar { Value: "association" } s: var ap = new AssociationProperty @@ -136,8 +136,8 @@ public IEnumerable Load(Parser parser) ap.Required = true; } - yield return ap; - break; + parser.Consume(); + return ap; case Scalar { Value: "composition" } s: var cp = new CompositionProperty @@ -172,8 +172,8 @@ public IEnumerable Load(Parser parser) } } - yield return cp; - break; + parser.Consume(); + return cp; case Scalar { Value: "alias" } s: var aliasReference = new AliasReference(); @@ -274,13 +274,11 @@ public IEnumerable Load(Parser parser) } alp.Reference = aliasReference; - yield return alp; - break; + parser.Consume(); + return alp; default: throw new ModelException($"Type de propriété inconnu."); } - - parser.Consume(); } } \ No newline at end of file diff --git a/TopModel.Core/Model/AliasProperty.cs b/TopModel.Core/Model/AliasProperty.cs index 27fff770..00dc3b19 100644 --- a/TopModel.Core/Model/AliasProperty.cs +++ b/TopModel.Core/Model/AliasProperty.cs @@ -39,6 +39,8 @@ public IFieldProperty Property public Decorator Decorator { get; set; } + public PropertyMapping PropertyMapping { get; set; } + #nullable enable public LocatedString? Trigram { get; set; } diff --git a/TopModel.Core/Model/AssociationProperty.cs b/TopModel.Core/Model/AssociationProperty.cs index f9ee3990..2b4ede23 100644 --- a/TopModel.Core/Model/AssociationProperty.cs +++ b/TopModel.Core/Model/AssociationProperty.cs @@ -31,6 +31,8 @@ public IFieldProperty Property public Endpoint Endpoint { get; set; } public Decorator Decorator { get; set; } + + public PropertyMapping PropertyMapping { get; set; } #nullable enable public string? Role { get; set; } diff --git a/TopModel.Core/Model/Class.cs b/TopModel.Core/Model/Class.cs index 480d8091..5fea0807 100644 --- a/TopModel.Core/Model/Class.cs +++ b/TopModel.Core/Model/Class.cs @@ -66,6 +66,8 @@ public class Class : IPropertyContainer public List FromMappers { get; } = new(); + public IEnumerable FromMapperProperties => FromMappers.SelectMany(fm => fm.PropertyParams.Select(pp => pp.Property)); + public List ToMappers { get; } = new(); public string PluralName diff --git a/TopModel.Core/Model/CompositionProperty.cs b/TopModel.Core/Model/CompositionProperty.cs index d371b4d7..ecf3f27e 100644 --- a/TopModel.Core/Model/CompositionProperty.cs +++ b/TopModel.Core/Model/CompositionProperty.cs @@ -32,6 +32,8 @@ public class CompositionProperty : IProperty public Decorator Decorator { get; set; } + public PropertyMapping PropertyMapping { get; set; } + public string Label => Name; public bool PrimaryKey => false; diff --git a/TopModel.Core/Model/FromMapper.cs b/TopModel.Core/Model/FromMapper.cs index 69740c77..757fad6c 100644 --- a/TopModel.Core/Model/FromMapper.cs +++ b/TopModel.Core/Model/FromMapper.cs @@ -4,7 +4,6 @@ namespace TopModel.Core; public class FromMapper { -#nullable enable public string? Comment { get; set; } public List> Params { get; } = new(); @@ -14,5 +13,7 @@ public class FromMapper public IEnumerable PropertyParams => Params.Where(p => p.IsT1).Select(p => p.AsT1); #nullable disable + public Class Class { get; set; } + internal LocatedString Reference { get; set; } } diff --git a/TopModel.Core/Model/IProperty.cs b/TopModel.Core/Model/IProperty.cs index a8b08adb..6e32f351 100644 --- a/TopModel.Core/Model/IProperty.cs +++ b/TopModel.Core/Model/IProperty.cs @@ -30,6 +30,8 @@ public interface IProperty Decorator Decorator { get; set; } + PropertyMapping PropertyMapping { get; set; } + IPropertyContainer Parent => Class ?? (IPropertyContainer)Endpoint ?? Decorator; IProperty CloneWithClassOrEndpoint(Class? classe = null, Endpoint? endpoint = null); diff --git a/TopModel.Core/Model/PropertyMapping.cs b/TopModel.Core/Model/PropertyMapping.cs index c56ea808..48e42b90 100644 --- a/TopModel.Core/Model/PropertyMapping.cs +++ b/TopModel.Core/Model/PropertyMapping.cs @@ -10,4 +10,6 @@ public class PropertyMapping public IProperty TargetProperty { get; set; } public Reference TargetPropertyReference { get; set; } + + public FromMapper FromMapper { get; set; } } diff --git a/TopModel.Core/Model/RegularProperty.cs b/TopModel.Core/Model/RegularProperty.cs index 976289b6..1c352c54 100644 --- a/TopModel.Core/Model/RegularProperty.cs +++ b/TopModel.Core/Model/RegularProperty.cs @@ -41,6 +41,8 @@ public class RegularProperty : IFieldProperty public Decorator Decorator { get; set; } + public PropertyMapping PropertyMapping { get; set; } + public DomainReference DomainReference { get; set; } #nullable enable diff --git a/TopModel.Core/ModelExtensions.cs b/TopModel.Core/ModelExtensions.cs index 5826c82c..acb96e55 100644 --- a/TopModel.Core/ModelExtensions.cs +++ b/TopModel.Core/ModelExtensions.cs @@ -7,6 +7,7 @@ public static class ModelExtensions public static IEnumerable<(ClassReference Reference, ModelFile File)> GetClassReferences(this ModelStore modelStore, Class classe) { return modelStore.Classes.SelectMany(c => c.Properties) + .Concat(modelStore.Classes.SelectMany(c => c.FromMapperProperties)) .Concat(modelStore.Endpoints.SelectMany(e => e.Properties)) .Concat(modelStore.Decorators.SelectMany(d => d.Properties)) .Where(p => @@ -54,6 +55,7 @@ public static class ModelExtensions public static IEnumerable<(DomainReference Reference, ModelFile File)> GetDomainReferences(this ModelStore modelStore, Domain domain) { return modelStore.Classes.SelectMany(c => c.Properties) + .Concat(modelStore.Classes.SelectMany(c => c.FromMapperProperties)) .Concat(modelStore.Decorators.SelectMany(c => c.Properties)) .Concat(modelStore.Endpoints.SelectMany(e => e.Properties)) .Where(p => @@ -86,6 +88,7 @@ public static ModelFile GetFile(this object? objet) IProperty { Decorator: Decorator decorator } => decorator.ModelFile, IProperty { Class: Class classe } => classe.ModelFile, IProperty { Endpoint: Endpoint endpoint } => endpoint.ModelFile, + IProperty { PropertyMapping: PropertyMapping param } => param.FromMapper.Class.ModelFile, Domain domain => domain.ModelFile, Converter converter => converter.ModelFile, Decorator decorator => decorator.ModelFile, diff --git a/TopModel.Core/ModelStore.cs b/TopModel.Core/ModelStore.cs index af147cd1..fec94afb 100644 --- a/TopModel.Core/ModelStore.cs +++ b/TopModel.Core/ModelStore.cs @@ -670,13 +670,32 @@ private IEnumerable ResolveReferences(ModelFile modelFile) if (alp.OriginalAliasProperty is not null) { var index = classe.Properties.IndexOf(alp); - classe.Properties.RemoveAt(classe.Properties.IndexOf(alp)); + classe.Properties.RemoveAt(index); if (!classe.Properties.Contains(alp.OriginalAliasProperty)) { classe.Properties.Insert(index, alp.OriginalAliasProperty); } } } + + foreach (var alp in classe.FromMapperProperties.OfType().ToList()) + { + if (alp.OriginalAliasProperty is not null) + { + var index = alp.PropertyMapping.FromMapper.Params.IndexOf(alp.PropertyMapping); + alp.PropertyMapping.FromMapper.Params.RemoveAt(index); + if (!alp.PropertyMapping.FromMapper.Params.Contains(alp.OriginalAliasProperty.PropertyMapping)) + { + alp.PropertyMapping.FromMapper.Params.Insert(index, new PropertyMapping + { + FromMapper = alp.PropertyMapping.FromMapper, + Property = alp.OriginalAliasProperty, + TargetProperty = alp.PropertyMapping.TargetProperty, + TargetPropertyReference = alp.PropertyMapping.TargetPropertyReference + }); + } + } + } } // Reset des alias déjà résolus sur les endpoints. @@ -803,6 +822,22 @@ IEnumerable ResolveAliases(IEnumerable alps) alp.Decorator.Properties.Insert(index + 1, prop); } } + else if (alp.PropertyMapping != null) + { + var index = alp.PropertyMapping.FromMapper.Params.IndexOf(alp.PropertyMapping); + if (index >= 0) + { + var mapping = new PropertyMapping + { + FromMapper = alp.PropertyMapping.FromMapper, + Property = prop, + TargetProperty = alp.PropertyMapping.TargetProperty, + TargetPropertyReference = alp.PropertyMapping.TargetPropertyReference, + }; + prop.PropertyMapping = mapping; + alp.PropertyMapping.FromMapper.Params.Insert(index + 1, mapping); + } + } } if (alp.Class != null) @@ -813,6 +848,10 @@ IEnumerable ResolveAliases(IEnumerable alps) { alp.Endpoint.Params.Remove(alp); } + else if (alp.PropertyMapping != null) + { + alp.PropertyMapping.FromMapper.Params.Remove(alp.PropertyMapping); + } else { alp.Decorator?.Properties.Remove(alp);