From d74167240feb66d0686d6331c54484f1d78d0d76 Mon Sep 17 00:00:00 2001 From: Bruno Thomas Date: Mon, 28 Oct 2024 17:16:20 +0000 Subject: [PATCH] refactor: move methods from SourceGenerator info Model --- src/main/java/org/icij/ftm/Model.java | 65 ++++++++++++++- .../java/org/icij/ftm/SourceGenerator.java | 81 ++++--------------- src/test/resources/logback.xml | 2 +- 3 files changed, 79 insertions(+), 69 deletions(-) diff --git a/src/main/java/org/icij/ftm/Model.java b/src/main/java/org/icij/ftm/Model.java index e8b4a99..f7d62c8 100644 --- a/src/main/java/org/icij/ftm/Model.java +++ b/src/main/java/org/icij/ftm/Model.java @@ -1,5 +1,8 @@ package org.icij.ftm; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -7,18 +10,21 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import static java.lang.String.format; public class Model { + private final static Logger logger = LoggerFactory.getLogger(Model.class); + final Map parents; private final Map yaml; - private final Map parents; private static final Set mixins = new LinkedHashSet<>(List.of("Asset")); public Model(Map modelMap, Map parents) { this.yaml = Collections.unmodifiableMap(modelMap); - this.parents = parents; + this.parents = Collections.unmodifiableMap(parents);; if (yaml.size() > 1) { throw new IllegalStateException(format("model should contain one definition, found %s", yaml.keySet())); } @@ -32,6 +38,39 @@ public String name() { return yaml.keySet().iterator().next(); } + public Optional getConcreteParent() { + List extendz = getExtends(); + List concreteParents = extendz.stream().filter(p -> parents.get(p) == null || parents.get(p).isConcrete()).collect(Collectors.toList()); + if (concreteParents.size()>1) { + logger.warn("got 2 concrete parents ({}) for {}, using the first", concreteParents, label()); + return Optional.of(concreteParents.get(0)); + } else if (concreteParents.isEmpty()) { + // this is fragile. It works because the multiple inheritance is ending with diamonds + logger.debug("got no concrete parent for {}, searching in grand-parents", label()); + Set> concreteGrandParents = extendz.stream() + .map(parents::get) + .map(Model::getConcreteParent) + .filter(Optional::isPresent).collect(Collectors.toSet()); + if (!concreteGrandParents.isEmpty()) { + if (concreteGrandParents.size() > 1) { + logger.warn("got {} concrete grand-parents, returning first", concreteGrandParents); + } + return concreteGrandParents.iterator().next(); + } + return Optional.empty(); + } else { + return Optional.of(concreteParents.get(0)); + } + } + + public LinkedHashSet getParentsAttributes() { + return getParentsAttributes(this); + } + + public Map getProperty(String prop) { + return getProperty(prop, this); + } + public Map description() { return (Map) yaml.get(name()); } @@ -56,6 +95,28 @@ public boolean isConcrete() { return !mixins.contains(name()) && !getRequired().isEmpty(); } + private Map getProperty(String prop, Model model) { + Map property = (Map) model.properties().get(prop); + if (property == null) { + Optional parent = model.getConcreteParent(); + return parent.map(s -> getProperty(prop, parents.get(s))).orElse(null); + } else { + return property; + } + } + + private LinkedHashSet getParentsAttributes(Model model) { + Optional parentName = model.getConcreteParent(); + if (parentName.isPresent()) { + LinkedHashSet grandParentsAttributes = getParentsAttributes(parents.get(parentName.get())); + List parentAttributes = parents.get(parentName.get()).getRequired(); + grandParentsAttributes.addAll(parentAttributes); + return grandParentsAttributes; + } else { + return new LinkedHashSet<>(); + } + } + @Override public String toString() { return name(); diff --git a/src/main/java/org/icij/ftm/SourceGenerator.java b/src/main/java/org/icij/ftm/SourceGenerator.java index fac526b..4ab14f3 100644 --- a/src/main/java/org/icij/ftm/SourceGenerator.java +++ b/src/main/java/org/icij/ftm/SourceGenerator.java @@ -12,12 +12,10 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Properties; -import java.util.Set; import java.util.stream.Collectors; import static java.lang.String.format; @@ -55,16 +53,16 @@ public String generate(Path path) throws IOException { Model model = new Model(getYamlContent(path.toFile()), parents); List required = model.getRequired(); - String inheritanceString = getInheritanceString(model, parents); + String inheritanceString = getInheritanceString(model); if (model.isConcrete()) { - List parentsAttributes = new ArrayList<>(getParentsAttributes(model, parents)); + List parentsAttributes = new ArrayList<>(model.getParentsAttributes()); List modelAttributes = required.stream().filter(a -> !parentsAttributes.contains(a)).toList(); - String parentsStringProperties = new AttributeHandlerForSignature(model, parents).generateFor(parentsAttributes); - String stringProperties = new AttributeHandlerForSignature(model, parents).generateFor(modelAttributes); + String parentsStringProperties = new AttributeHandlerForSignature(model).generateFor(parentsAttributes); + String stringProperties = new AttributeHandlerForSignature(model).generateFor(modelAttributes); String classAttributes = new AttributeHandlerForAttrs(model, parents).generateFor(modelAttributes); - String classAttributesAssignation = getConstructor(model, parents); + String classAttributesAssignation = getConstructor(model); if (parents.containsKey(model.name()) || inheritanceString.contains("extends")) { return format(""" @@ -105,18 +103,8 @@ public interface %s %s{}; } } - private static Map getProperty(String prop, Model model, Map parents) { - Map property = (Map) model.properties().get(prop); - if (property == null) { - Optional parent = getConcreteParent(model, parents); - return parent.map(s -> getProperty(prop, parents.get(s), parents)).orElse(null); - } else { - return property; - } - } - - private static String getConstructor(Model model, Map parents) { - List parentAttributes = new ArrayList<>(getParentsAttributes(model, parents)); + private static String getConstructor(Model model) { + List parentAttributes = new ArrayList<>(model.getParentsAttributes()); List required = model.getRequired(); if (!parentAttributes.isEmpty()) { return format("super(%s);\n", String.join(", ", parentAttributes)) + required.stream().filter(a -> !parentAttributes.contains(a)).map(a -> format("this.%s = %s;", a, a)).collect(Collectors.joining("\n")); @@ -125,47 +113,10 @@ private static String getConstructor(Model model, Map parents) { } } - private static LinkedHashSet getParentsAttributes(Model model, Map parents) { - Optional parent = getConcreteParent(model, parents); - if (parent.isPresent()) { - LinkedHashSet grandParentsAttributes = getParentsAttributes(parents.get(parent.get()), parents); - List parentAttributes = parents.get(parent.get()).getRequired(); - grandParentsAttributes.addAll(parentAttributes); - return grandParentsAttributes; - } else { - return new LinkedHashSet<>(); - } - } - - private static Optional getConcreteParent(Model model, Map parents) { - List extendz = model.getExtends(); - List concreteParents = extendz.stream().filter(p -> parents.get(p) == null || parents.get(p).isConcrete()).collect(Collectors.toList()); - if (concreteParents.size()>1) { - logger.warn("got 2 concrete parents ({}) for {}, using the first", concreteParents, model.label()); - return Optional.of(concreteParents.get(0)); - } else if (concreteParents.isEmpty()) { - // this is fragile. It works because the multiple inheritance is ending with diamonds - logger.debug("got no concrete parent for {}, searching in grand-parents", model.label()); - Set> concreteGrandParents = extendz.stream() - .map(parents::get) - .map(m -> getConcreteParent(m, parents)) - .filter(Optional::isPresent).collect(Collectors.toSet()); - if (!concreteGrandParents.isEmpty()) { - if (concreteGrandParents.size() > 1) { - logger.warn("got {} concrete grand-parents, returning first", concreteGrandParents); - } - return concreteGrandParents.iterator().next(); - } - return Optional.empty(); - } else { - return Optional.of(concreteParents.get(0)); - } - } - - private static String getInheritanceString(Model model, Map parents) { - Optional javaExtend = getConcreteParent(model, parents); + private static String getInheritanceString(Model model) { + Optional javaExtend = model.getConcreteParent(); List extendz = model.getExtends(); - List implementsList = extendz.stream().filter(p -> parents.get(p) == null || !parents.get(p).isConcrete()).collect(Collectors.toList()); + List implementsList = extendz.stream().filter(p -> model.parents.get(p) == null || !model.parents.get(p).isConcrete()).collect(Collectors.toList()); String extendsString = model.isConcrete() && javaExtend.isPresent() ? format("extends %s ", javaExtend.get()): ""; String implementsString = implementsList.isEmpty() ? "" : model.isConcrete() ? format("implements %s ", String.join(", ", implementsList)): @@ -187,18 +138,16 @@ private static String sanitizedProp(String prop) { } static class AttributeHandlerForSignature { - private final Model modelDesc; - private final Map parents; + private final Model model; - public AttributeHandlerForSignature(Model modelDesc, Map parents) { - this.modelDesc = modelDesc; - this.parents = parents; + public AttributeHandlerForSignature(Model model) { + this.model = model; } String generateFor(List attributes) { StringBuilder stringProperties = new StringBuilder(); for (String prop: attributes) { - Map property = getProperty(prop, modelDesc, parents); + Map property = model.getProperty(prop); if (property != null) { if ("entity".equals(property.get("type"))) { addPropertyForEntity(stringProperties, prop, property); @@ -234,7 +183,7 @@ protected void addPropertyForNativeType(StringBuilder stringProperties, String p static class AttributeHandlerForAttrs extends AttributeHandlerForSignature { public AttributeHandlerForAttrs(Model model, Map parents) { - super(model, parents); + super(model); } @Override diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index 691bb63..0798383 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -6,7 +6,7 @@ - + \ No newline at end of file