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

fr.ird.observe.toolkit.maven.plugin.server.mapping.Template Maven / Gradle / Ivy

package fr.ird.observe.toolkit.maven.plugin.server.mapping;

/*-
 * #%L
 * ObServe Toolkit :: Maven plugin
 * %%
 * Copyright (C) 2017 - 2022 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.IdDto;
import fr.ird.observe.dto.data.DataDto;
import fr.ird.observe.dto.data.EditableDto;
import fr.ird.observe.dto.data.RootOpenableDto;
import fr.ird.observe.dto.referential.ReferentialDto;
import fr.ird.observe.spi.module.BusinessDataPackage;
import fr.ird.observe.spi.module.BusinessModule;
import fr.ird.observe.spi.module.BusinessProject;
import fr.ird.observe.spi.module.BusinessProjectVisitor;
import fr.ird.observe.spi.module.BusinessReferentialPackage;
import fr.ird.observe.spi.module.BusinessSubModule;
import io.ultreia.java4all.util.ServiceLoaders;
import org.apache.maven.plugin.logging.Log;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created on 19/04/2021.
 *
 * @author Tony Chemit - [email protected]
 * @since 5.0.17
 */
public class Template extends fr.ird.observe.toolkit.maven.plugin.server.Template {

    public static final String MAPPING_MODEL = "" +
            "# Generated by fr.ird.observe.toolkit.maven.plugin.server.mapping.Template\n" +
            "#\n" +
            "# Build version  ${project.version}\n" +
            "# Build date     ${buildDate}\n" +
            "# Build number   ${buildNumber}\n" +
            "#\n\n" +
            "[config]\n" +
            "package.filters=fr.ird.observe.server.filter\n" +
            "package.actions=fr.ird.observe.server.controller\n" +
            "server.main.handler.class=fr.ird.observe.server.ObserveWebMainHandler\n" +
            "default.render=fr.ird.observe.server.ObserveWebMotionRender\n" +
            "\n" +
            "[filters]\n" +
            "*      /*                                                        PublicApiFilter.inject\n\n" +
            "[actions]\n\n" +
            "#\n" +
            "# Real path are prefixed by /api/public\n" +
            "#\n" +
            "%1$s";
    private static final String INPUT_PATTERN = "%1$-6s %2$s";
    private static final String INPUT_PATTERN_WITH_ID = "%1$-6s %2$s/{id}";
    private static final String ACTION_PATTERN = "api.%1$s.%2$-8s     dtoType=%3$s";
    private static final String ACTION_PATTERN_WITH_CONTENT = "api.%1$s.%2$-8s     dtoType=%3$s,content=$body";
    private final BusinessProject businessProject;
    List init = new LinkedList<>();
    List data = new LinkedList<>();
    List referential = new LinkedList<>();
    int actionPrefix = 0;

    public Template(Log log, Path targetDirectory) {
        super(log, Runner.PACKAGE, "", targetDirectory);
        businessProject = ServiceLoaders.loadUniqueService(BusinessProject.class);

        ServerTypeActionModel actionTemplate = new ServerTypeActionModel();
        init.add(actionTemplate);
        actionTemplate.actions.put("GET    /init/ping", "AnonymousServiceRestApi.ping");
        actionTemplate.actions.put("GET    /init/open", "AnonymousServiceRestApi.open");
        actionTemplate.actions.put("GET    /init/close", "DataSourceServiceRestApi.close");
        actionTemplate.actions.put("GET    /init/information", "DataSourceServiceRestApi.information");
    }

    public void generateMapping() throws IOException {

        ServerTypeActionModel actionTemplate = new ServerTypeActionModel("referential", "all in project", null);
        referential.add(actionTemplate);
        actionTemplate.actions.put("GET    /referential", "api.ReferentialEntityServiceRestApi.getByModule");

        BusinessProjectVisitor visitor = new BusinessProjectVisitor() {

            @Override
            public void enterSubModuleDataType(BusinessModule module, BusinessSubModule subModule, BusinessDataPackage dataPackage, Class dtoType) {
                Class mainDtoType = businessProject.getMapping().getMainDtoType(dtoType);
                if (mainDtoType != dtoType && !EditableDto.class.isAssignableFrom(dtoType)) {
                    return;
                }

                String moduleName = module.getName().toLowerCase() + "/" + subModule.getName().toLowerCase();
                String simpleName = dtoType.getSimpleName().replace("Dto", "");
                String dtoFullyQualifiedName = dtoType.getName();
                ServerTypeActionModel actionTemplate = new ServerTypeActionModel(dtoFullyQualifiedName.replace(IdDto.class.getPackageName(), prefix).replace("Dto", ""), simpleName, moduleName);
                data.add(actionTemplate);
                boolean canEdit = RootOpenableDto.class.isAssignableFrom(dtoType);
                addEditActions(actionTemplate, false, canEdit, moduleName, simpleName, dtoFullyQualifiedName);
            }

            @Override
            public void enterModule(BusinessModule module) {
                String moduleName = module.getName().toLowerCase();
                String path = "referential/" + moduleName;
                ServerTypeActionModel actionTemplate = new ServerTypeActionModel(path, "all in this module", moduleName);
                referential.add(actionTemplate);
                actionTemplate.actions.put(String.format("GET    /%1$s", path), String.format("api.ReferentialEntityServiceRestApi.getByModule  moduleName=%1$s", moduleName));
            }

            @Override
            public void enterSubModuleReferentialPackage(BusinessModule module, BusinessSubModule subModule, BusinessReferentialPackage referentialPackage) {
                String moduleName = module.getName().toLowerCase();
                String packageName = subModule.getName().toLowerCase();
                String path = "referential/" + moduleName + "/" + packageName;
                ServerTypeActionModel actionTemplate = new ServerTypeActionModel(path, "all in this package", moduleName);
                referential.add(actionTemplate);
                actionTemplate.actions.put(String.format("GET    /%1$s", path), String.format("api.ReferentialEntityServiceRestApi.getByPackage packageName=%1$s_%2$s", moduleName, packageName));
            }

            @Override
            public void enterSubModuleReferentialType(BusinessModule module, BusinessSubModule subModule, BusinessReferentialPackage referentialPackage, Class dtoType) {
                String moduleName = module.getName().toLowerCase() + "/" + subModule.getName().toLowerCase();
                String simpleName = dtoType.getSimpleName().replace("Dto", "");
                String dtoFullyQualifiedName = dtoType.getName();
                ServerTypeActionModel actionTemplate = new ServerTypeActionModel(dtoFullyQualifiedName.replace(IdDto.class.getPackageName(), prefix).replace("Dto", ""), simpleName, moduleName);
                referential.add(actionTemplate);
                addEditActions(actionTemplate, true, true, moduleName, simpleName, dtoFullyQualifiedName);
            }

            private void addEditActions(ServerTypeActionModel actionTemplate, boolean referential, boolean canEdit, String moduleName, String simpleName, String dtoFullyQualifiedName) {
                String action = String.format("/%1$s/%2$s/%3$s", referential ? "referential" : "data", moduleName.replace("common/", ""), simpleName);
                String serviceName = referential ? "ReferentialEntityServiceRestApi" : "DataEntityServiceRestApi";
                if (referential) {
                    actionTemplate.actions.put(String.format(INPUT_PATTERN, "GET", action + "/all"), String.format(ACTION_PATTERN, serviceName, "getAll", dtoFullyQualifiedName));
                }
                actionTemplate.actions.put(String.format(INPUT_PATTERN, "GET", action), String.format(ACTION_PATTERN, serviceName, "getSome", dtoFullyQualifiedName));
                actionTemplate.actions.put(String.format(INPUT_PATTERN_WITH_ID, "GET", action), String.format(ACTION_PATTERN, serviceName, "getOne", dtoFullyQualifiedName));
                if (canEdit) {
                    actionTemplate.actions.put(String.format(INPUT_PATTERN, "POST", action), String.format(ACTION_PATTERN_WITH_CONTENT, serviceName, "create", dtoFullyQualifiedName));
                    actionTemplate.actions.put(String.format(INPUT_PATTERN_WITH_ID, "PUT", action), String.format(ACTION_PATTERN_WITH_CONTENT, serviceName, "update", dtoFullyQualifiedName));
                    actionTemplate.actions.put(String.format(INPUT_PATTERN_WITH_ID, "DELETE", action), String.format(ACTION_PATTERN, serviceName, "delete", dtoFullyQualifiedName));
                }
                actionPrefix = Math.max(actionPrefix, actionTemplate.actionPrefix());
            }
        };
        businessProject.accept(visitor);

        actionPrefix += 2;
        String actions =
                init.stream().map(datum -> datum.generate(actionPrefix)).collect(Collectors.joining()) +
                        data.stream().map(datum -> datum.generate(actionPrefix)).collect(Collectors.joining()) +
                        referential.stream().map(datum -> datum.generate(actionPrefix)).collect(Collectors.joining());
        String content = String.format(MAPPING_MODEL, actions);
        Path targetFile = targetDirectory.resolve("META-INF").resolve("mapping-api-public.wm");
        if (Files.notExists(targetFile.getParent())) {
            Files.createDirectories(targetFile.getParent());
        }
        log.debug(String.format("Will generate at %s", targetFile));
        Files.write(targetFile, content.getBytes(StandardCharsets.UTF_8));
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy