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

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

package fr.ird.observe.toolkit.templates;

/*-
 * #%L
 * ObServe Toolkit :: Templates
 * %%
 * Copyright (C) 2017 - 2020 IRD, 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.data.DataDto;
import fr.ird.observe.dto.referential.ReferentialDto;
import fr.ird.observe.spi.type.TypeTranslators;
import io.ultreia.java4all.application.context.spi.GenerateApplicationComponent;
import io.ultreia.java4all.classmapping.ImmutableClassMapping;
import org.nuiton.eugene.GeneratorUtil;
import org.nuiton.eugene.java.extension.ObjectModelAnnotation;
import org.nuiton.eugene.models.object.ObjectModel;
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.ObjectModelOperation;
import org.nuiton.eugene.models.object.ObjectModelParameter;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;




/**
 * @author Tony Chemit - [email protected]
 * @since 5
 */
@SuppressWarnings("StringOperationCanBeSimplified")
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);
    }

    String getDefaultPackageName();

    ObjectModelClass createClass(String className, String packageName);

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

    void addImport(ObjectModelClass output, Class type);

    void addImport(ObjectModelClass output, String type);

    void setSuperClass(ObjectModelClass output, Class superClass);

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

    void addAnnotationParameter(ObjectModelClass output, ObjectModelAnnotation annotation, String name, String value);

    default void addAnnotationClassParameter(ObjectModelClass output, ObjectModelAnnotation annotation, String name, Class value) {
        addImport(output, value);
        addAnnotationParameter(output, annotation, name, "{" + value.getSimpleName() + ".class}");
    }

    default void addAnnotationClassParameter(ObjectModelClass output, ObjectModelAnnotation annotation, String name, Class... values) {
        StringBuilder content = new StringBuilder("{");
        for (Class value : values) {
            addImport(output, value);
            content.append(value.getSimpleName()).append(".class");
        }
        content.append("}");
        addAnnotationParameter(output, annotation, name, content.toString());
    }

    ObjectModelOperation addConstructor(ObjectModelClass output, ObjectModelJavaModifier modifiers);

    void setOperationBody(ObjectModelOperation constructor, String body);

    default void generateClassMapping(boolean useSimpleName, String name, Class superClass, String sourceType, String targetType, Class builderType, String buildMethod, Map dtoToReferenceMapping) {
        generateClassMapping(useSimpleName, name, superClass, sourceType, targetType, builderType, buildMethod, dtoToReferenceMapping, new Class[0]);
    }

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

        String className = getModel().getName() + superClass.getSimpleName();
        ObjectModelClass output = createClass(className, getDefaultPackageName());
        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);

        ObjectModelAnnotation annotation = addAnnotation(output, output, GenerateApplicationComponent.class);
        addAnnotationParameter(output, annotation, "name", name);
        addAnnotationClassParameter(output, annotation, "hints", superClass);
        if (dependencies.length != 0) {
            addAnnotationClassParameter(output, annotation, "dependencies", dependencies);
        }

        StringBuilder body = new StringBuilder(""+"\n"
+"        super("
        );
        if (dependencies.length != 0) {
            for (Class dependency : dependencies) {
                body.append(""+""+dependency.getSimpleName()+", "
                );
            }
        }
        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);

        if (dependencies.length > 0) {
            for (Class dependency : dependencies) {
                addParameter(constructor, dependency, dependency.getSimpleName());
            }
        }
        setOperationBody(constructor, body.toString());
    }

    ObjectModel getModel();

    default Set getInterfaces(ObjectModelClassifier classifier, ObjectModelInterface anInterface) {
        Set result = new LinkedHashSet<>();
        getInterfaces(classifier, anInterface, result);
        return result;
    }

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

        for (ObjectModelInterface classifierInterface : classifier.getInterfaces()) {
            if (anInterface.equals(classifierInterface)) {
                result.add(classifier.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));
        }

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy