All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.ird.observe.toolkit.templates.TemplateContract Maven / Gradle / Ivy

There is a newer version: 10.0.1
Show newest version
package fr.ird.observe.toolkit.templates;

/*-
 * #%L
 * Toolkit :: Templates
 * %%
 * Copyright (C) 2017 - 2024 Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import fr.ird.observe.dto.ToolkitIdLabel;
import fr.ird.observe.dto.ToolkitIdTechnicalLabel;
import fr.ird.observe.dto.data.DataDto;
import fr.ird.observe.dto.referential.ReferentialDto;
import fr.ird.observe.dto.referential.ReferentialDtoReferenceWithCodeAware;
import fr.ird.observe.dto.referential.ReferentialDtoReferenceWithNoCodeAware;
import io.ultreia.java4all.classmapping.ImmutableClassMapping;
import io.ultreia.java4all.i18n.spi.type.TypeTranslators;
import io.ultreia.java4all.util.ServiceLoaders;
import org.nuiton.eugene.GeneratorUtil;
import org.nuiton.eugene.java.BeanTransformerContext;
import org.nuiton.eugene.java.extension.ImportsManager;
import org.nuiton.eugene.java.extension.ObjectModelAnnotation;
import org.nuiton.eugene.models.object.ObjectModel;
import org.nuiton.eugene.models.object.ObjectModelAttribute;
import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelClassifier;
import org.nuiton.eugene.models.object.ObjectModelElement;
import org.nuiton.eugene.models.object.ObjectModelInterface;
import org.nuiton.eugene.models.object.ObjectModelJavaModifier;
import org.nuiton.eugene.models.object.ObjectModelModifier;
import org.nuiton.eugene.models.object.ObjectModelOperation;
import org.nuiton.eugene.models.object.ObjectModelParameter;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.function.BiPredicate;




/**
 * @author Tony Chemit - [email protected]
 * @since 5
 */
@SuppressWarnings({"StringOperationCanBeSimplified", "UnusedAssignment", "UnusedReturnValue", "unused"})
public interface TemplateContract {

    static boolean isReferentialFromPackageName(String packageName) {
        return packageName.contains(".referential");
    }

    static String cleanDtoType(boolean referential, String fqn) {
        return TypeTranslators.getTranslator(referential ? ReferentialDto.class : DataDto.class).cleanType(fqn);
    }

    static void addToLabel(TemplateContract generate, ObjectModelClassifier output, String dtoType) {
        String dtoName = GeneratorUtil.getSimpleName(dtoType);
        generate.addImport(output, ToolkitIdLabel.class);
        generate.addImport(output, dtoType);
        ObjectModelOperation toLabel = generate.addOperation(output, "toLabel", ToolkitIdLabel.class.getSimpleName(), ObjectModelJavaModifier.PUBLIC);
        generate.addAnnotation(output, toLabel, Override.class);
        generate.setOperationBody(toLabel, ""+"\n"
+"        return ToolkitIdLabel.newLabel("+dtoName+".class, this);\n"
+"    "
        );
        generate.addImport(output, ToolkitIdTechnicalLabel.class);
        ObjectModelOperation toTechnicalLabel = generate.addOperation(output, "toTechnicalLabel", ToolkitIdTechnicalLabel.class.getSimpleName(), ObjectModelJavaModifier.PUBLIC);
        generate.addAnnotation(output, toTechnicalLabel, Override.class);
        generate.setOperationBody(toTechnicalLabel, ""+"\n"
+"        return ToolkitIdTechnicalLabel.newTechnicalLabel("+dtoName+".class, this);\n"
+"    "
        );
    }

    static Properties loadDtoTagValues(ClassLoader classLoader, String modelName) {
        Properties dtoTagValues = new Properties();
        URL resource = Objects.requireNonNull(classLoader.getResource("models/" + modelName + "/dto.properties"));
        try (InputStream inputStream = resource.openStream()) {
            dtoTagValues.load(inputStream);
        } catch (IOException e) {
            throw new IllegalStateException("Can't load dto tag values", e);
        }
        return dtoTagValues;
    }

    static Properties loadPersistenceTagValues(ClassLoader classLoader, String modelName) {
        Properties dtoTagValues = new Properties();
        URL resource = Objects.requireNonNull(classLoader.getResource("models/" + modelName + "/persistence.properties"));
        try (InputStream inputStream = resource.openStream()) {
            dtoTagValues.load(inputStream);
        } catch (IOException e) {
            throw new IllegalStateException("Can't load persistence tag values", e);
        }
        return dtoTagValues;
    }

    static String getDtoName(BeanTransformerContext context, ObjectModelClass input) {
        return Objects.requireNonNull(context.classesNameTranslation.get(input));
    }

    static List getProperties(ObjectModelClass beanClass, Collection attributes, BiPredicate filter) {
        List properties = new LinkedList<>();
        for (ObjectModelAttribute attr : attributes) {
            if (attr.isNavigable() && filter.test(beanClass, attr)) {
                properties.add(attr.getName());
            }
        }
        return properties;
    }

    ObjectModelClass createClass(String className, String packageName);

    ObjectModelParameter addParameter(ObjectModelOperation operation, Class type, String name);

    ObjectModelParameter addParameter(ObjectModelOperation operation, String type, String name);

    void addImport(ObjectModelClassifier output, Class type);

    void addImport(ObjectModelClassifier output, String type);

    void setSuperClass(ObjectModelClass output, Class superClass);

    void setSuperClass(ObjectModelClass output, String superClass);

    ObjectModelAnnotation addAnnotation(ObjectModelClassifier output, ObjectModelElement output1, Class annotationType);

    ObjectModelAnnotation addAnnotationParameter(ObjectModelClassifier output, ObjectModelAnnotation annotation, String name, Object value);

    ObjectModelOperation addConstructor(
            ObjectModelClass clazz, ObjectModelModifier visibility)
            throws IllegalArgumentException;

    ObjectModelOperation addOperation(
            ObjectModelClassifier classifier,
            String name,
            String type,
            ObjectModelModifier... modifiers);

    void addInterface(ObjectModelClassifier classifier, Class interfaceQualifiedName);

    void addInterface(ObjectModelClassifier classifier, String interfaceQualifiedName);

    void setOperationBody(ObjectModelOperation constructor, String body);

    ObjectModelAttribute addAttribute(ObjectModelClassifier classifier, String name, String type, String value, ObjectModelModifier... modifiers);

    ObjectModel getModel();

    void addAnnotationClassParameter(ImportsManager manager, ObjectModelClassifier output, ObjectModelAnnotation annotation, String name, Class value);

    void addAnnotationClassParameter(ImportsManager manager, ObjectModelClassifier output, ObjectModelAnnotation annotation, String name, String value);

    void addAnnotationClassParameter(ImportsManager manager, ObjectModelClassifier output, ObjectModelAnnotation annotation, String name, Class... values);

    void addAnnotationClassParameter(ObjectModelClassifier output, ObjectModelAnnotation annotation, String name, Iterable values);

    default void addStaticFactory(ObjectModelClass aClass, String realClassName) {
        String className = realClassName == null ? aClass.getQualifiedName() : realClassName;
        addAttribute(aClass, "INSTANCE", className, null, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.STATIC);
        ObjectModelOperation get = addOperation(aClass, "get", className, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
        setOperationBody(get, ""+"\n"
+"        return INSTANCE == null ? INSTANCE = new "+className+"() : INSTANCE;\n"
+"    ");
    }


    default void addStaticFactoryFromServiceLoader(ObjectModelClass aClass, String realClassName) {
        String className = realClassName == null ? aClass.getQualifiedName() : realClassName;
        addAttribute(aClass, "INSTANCE", className, null, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.STATIC);
        addImport(aClass, ServiceLoaders.class);
        ObjectModelOperation get = addOperation(aClass, "get", className, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
        setOperationBody(get, ""+"\n"
+"        return INSTANCE == null ? INSTANCE = ServiceLoaders.loadUniqueService("+className+".class) : INSTANCE;\n"
+"    ");
    }

    default void generateClassMapping(boolean useSimpleName, Class superClass, String sourceType, String targetType, Class builderType, String buildMethod, Map dtoToReferenceMapping) {

        String className = getModel().getName() + superClass.getSimpleName();
        ObjectModelClass output = createClass(className, superClass.getPackage().getName());
        addImport(output, ImmutableClassMapping.class);
        String initMethod = builderType.getName();
        if (useSimpleName) {

            addImport(output, builderType);
            addImport(output, sourceType);
            addImport(output, targetType);
            sourceType = GeneratorUtil.getSimpleName(sourceType);
            targetType = GeneratorUtil.getSimpleName(targetType);
            initMethod = GeneratorUtil.getSimpleName(initMethod);
        }
        setSuperClass(output, superClass);
        addStaticFactory(output, null);

        StringBuilder body = new StringBuilder(""+"\n"
+"        super("
        );
        body.append(""+""+initMethod+".<"+sourceType+", "+targetType+">builder()"
        );
        dtoToReferenceMapping.forEach((source, target) -> body.append(""+"\n"
+"                      .put("+source+".class, "+target+")"
        ));
        body.append(""+"\n"
+"                      ."+buildMethod+"());\n"
+"    "
        );
        ObjectModelOperation constructor = addConstructor(output, ObjectModelJavaModifier.PUBLIC);
        setOperationBody(constructor, body.toString());
    }

    default Set getInterfaces(ObjectModelClassifier classifier, ObjectModelInterface... interfaces) {
        Set result = new LinkedHashSet<>();
        for (ObjectModelInterface objectModelInterface : interfaces) {
            getInterfaces(classifier, objectModelInterface, result);
        }
        result.remove(classifier.getQualifiedName());
        return result;
    }

    default void getInterfaces(ObjectModelClassifier classifier, ObjectModelInterface anInterface, Set result) {

        for (ObjectModelInterface classifierInterface : classifier.getInterfaces()) {
            if (anInterface.equals(classifierInterface)) {
                result.add(classifier.getQualifiedName());
                result.add(anInterface.getQualifiedName());
                continue;
            }
            if (classifierInterface.getInterfaces() != null) {
                getInterfaces(classifierInterface, anInterface, result);
            }
        }
        if (classifier instanceof ObjectModelClass) {
            ObjectModelClass classifier1 = (ObjectModelClass) classifier;
            classifier1.getSuperclasses().forEach(superclass -> getInterfaces(superclass, anInterface, result));
        }

    }

    default void addWithNoCodeInterface(boolean referential, ObjectModelClass input, ObjectModelClassifier output) {
        if (referential) {
            boolean foundReferentialDtoReferenceWithNoCodeAware = input.getInterfaces().stream().anyMatch(i -> i.getQualifiedName().equals(ReferentialDtoReferenceWithNoCodeAware.class.getName()));
            if (!foundReferentialDtoReferenceWithNoCodeAware) {
                addInterface(output, ReferentialDtoReferenceWithCodeAware.class);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy