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

fr.ird.observe.toolkit.maven.plugin.fixtures.FixturesTemplate Maven / Gradle / Ivy

package fr.ird.observe.toolkit.maven.plugin.fixtures;

/*-
 * #%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 com.google.gson.Gson;
import fr.ird.observe.dto.BusinessDto;
import fr.ird.observe.dto.ToolkitId;
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 fr.ird.observe.navigation.tree.io.ToolkitTreeNodeStates;
import fr.ird.observe.navigation.tree.io.request.ToolkitRequestConfig;
import fr.ird.observe.services.ObserveServiceInitializer;
import fr.ird.observe.services.ObserveServiceMainFactory;
import fr.ird.observe.services.service.api.DataEntityService;
import fr.ird.observe.services.service.api.ReferentialEntityService;
import fr.ird.observe.spi.json.java.util.DateAdapter;
import fr.ird.observe.toolkit.maven.plugin.server.TemplateHelper;
import fr.ird.observe.toolkit.maven.plugin.server.html.model.DocModule;
import fr.ird.observe.toolkit.maven.plugin.server.html.model.DocPackage;
import fr.ird.observe.toolkit.maven.plugin.server.html.model.DocProject;
import fr.ird.observe.toolkit.maven.plugin.server.html.model.DocRequest;
import fr.ird.observe.toolkit.maven.plugin.server.html.model.DocType;
import fr.ird.observe.toolkit.maven.plugin.server.html.model.Requests;
import io.ultreia.java4all.util.SortedProperties;

import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiFunction;

/**
 * Created on 22/11/2021.
 *
 * @author Tony Chemit - [email protected]
 * @since 5.0.55
 */
public class FixturesTemplate {
    public static final String PAYLOAD = "payload";
    private final FixturesModel model;
    private final Gson gson;
    private final ReferentialEntityService referentialEntityService;
    private final DataEntityService dataEntityService;
    private final ToolkitRequestConfig config;
    private final ToolkitRequestConfig fullConfig;
    private final DateAdapter dataAdapter;

    public FixturesTemplate(FixturesModel model, Gson gson, ObserveServiceMainFactory serviceMainFactory, ObserveServiceInitializer serviceInitializer) {
        this.model = model;
        this.gson = gson;
        this.referentialEntityService = serviceMainFactory.newService(serviceInitializer, ReferentialEntityService.class);
        this.dataEntityService = serviceMainFactory.newService(serviceInitializer, DataEntityService.class);
        this.config = new ToolkitRequestConfig(false, true, true, false, false);
        this.fullConfig = new ToolkitRequestConfig(false, true, true, true, false);
        dataAdapter = new DateAdapter();
    }

    public void generate() throws IOException {
        generateIds();
        generateInit();
        this.generateContent(
                model.getReferentialPaths(),
                (type, id) -> referentialEntityService.getOne(type, config, id),
                (type, id) -> referentialEntityService.getOne(type, fullConfig, id));
        this.generateContent(
                model.getDataPaths(),
                (type, id) -> dataEntityService.getOne(type, config, id),
                (type, id) -> dataEntityService.getOne(type, fullConfig, id));
        generateByProject();
        generateByModule();
        generateByPackage();
    }

    private void generateIds() throws IOException {

        Path variablesPath = model.getVariablesPath();
        SortedProperties variables = model.getVariables();

        Files.deleteIfExists(variablesPath);
        List result = new ArrayList<>(variables.size());
        for (String variableId : variables.stringPropertyNames()) {
            result.add(String.format("%s=%s", variableId, variables.get(variableId)));
        }
        Files.write(variablesPath, result);
    }

    private void generateInit() {
        DocProject project = new DocProject("init");
        for (Map.Entry entry : model.getInitPaths().entrySet()) {
            String queryType = entry.getKey();
            Path path = entry.getValue();
            Requests requests = Requests.valueOf(queryType);
            Map parameters = createParameters();
            String result = null;
            String modelVersion = model.getModelVersion().getVersion();
            switch (requests) {
                case Ping:
                    parameters.clear();
                    result = "{\n" +
                            "  \"modelVersion\": \"" + modelVersion + "\",\n" +
                            "  \"serverVersion\": \"" + model.getApplicationVersion().getVersion() + "\"\n" +
                            "}";
                    break;
                case Open:
                    parameters.clear();
                    addParameter(parameters, "config.modelVersion", modelVersion);
                    addParameter(parameters, "config.login", "aLogin");
                    addParameter(parameters, "config.password", "aPassword");
                    addParameter(parameters, "config.databaseName", "9-tck");
                    addParameter(parameters, "referentialLocale", "FR");

                    result = "{\n" +
                            "  \"url\": \"http://localhost:8080/observeweb\",\n" +
                            "  \"authenticationToken\": \"XXX\",\n" +
                            "  \"dataSourceInformation\": {\n" +
                            "    \"permission\": \"ALL\",\n" +
                            "    \"minimumVersion\": \"3.0\",\n" +
                            "    \"version\": \"" + modelVersion + "\",\n" +
                            "    \"migrations\": [],\n" +
                            "    \"owner\": true,\n" +
                            "    \"superUser\": true\n" +
                            "  },\n" +
                            "  \"connectMode\": \"SERVER\"\n" +
                            "}";

                    break;
                case Close:
                    result = "null";
                    break;
                case Information:
                    result = "{\n" +
                            "  \"url\": \"http://localhost:8080/observeweb\",\n" +
                            "  \"login\": \"aLogin\",\n" +
                            "  \"database\": \"9-tck\",\n" +
                            "  \"apiAccess\": \"ALL\",\n" +
                            "  \"validationMode\": \"STRONG\",\n" +
                            "  \"authenticationToken\": \"XXX\",\n" +
                            "  \"modelVersion\": \"" + modelVersion + "\",\n" +
                            "  \"credentials\": \"ALL\"\n" +
                            "}";
                    break;
            }
            consumeInit(path, project, requests, parameters, result);
        }
    }

    private void consumeInit(Path path, DocProject project, Requests queryType, Map parameters, String responseContent) {
        DocRequest request = new DocRequest(project, queryType);
        String requestContent = toJson(request, parameters);
        write(request, path, requestContent, responseContent);
    }

    private void generateByProject() {
        ToolkitTreeNodeStates all = referentialEntityService.getByModule(null, config);
        consumeGetAll(Requests.GetAllForProject, model.getFixturesPath().resolve("referential"), all);
    }

    private void generateByModule() {
        for (Map.Entry entry : model.getGetByModule().entrySet()) {
            String moduleName = entry.getKey();
            Path path = entry.getValue();
            ToolkitTreeNodeStates all = referentialEntityService.getByModule(moduleName, config);
            consumeGetAll(Requests.GetAllForModule, path, all);
        }
    }

    private void generateByPackage() {
        for (Map.Entry entry : model.getGetByPackage().entrySet()) {
            String packageName = entry.getKey();
            Path path = entry.getValue();
            ToolkitTreeNodeStates all = referentialEntityService.getByPackage(packageName, config);
            consumeGetAll(Requests.GetAllForPackage, path, all);
        }
    }

    private  void generateContent(Map pathMap,
                                                         BiFunction, String, ToolkitTreeNodeStates> getConsumer,
                                                         BiFunction, String, ToolkitTreeNodeStates> fullConsumer) {
        Map> types = model.getTypes();
        SortedProperties variables = model.getVariables();
        for (Map.Entry entry : pathMap.entrySet()) {
            String idVariable = entry.getKey();
            Path path = entry.getValue();
            @SuppressWarnings("unchecked") Class dtoType = (Class) types.get(idVariable);
            String id = variables.getProperty(idVariable);
            if (id == null || id.isEmpty()) {
                continue;
            }
            ToolkitTreeNodeStates toolkitTreeNodeStates = getConsumer.apply(dtoType, id);
            ToolkitTreeNodeStates fullToolkitTreeNodeStates = fullConsumer.apply(dtoType, id);

            Path packagePath = path.getParent();
            Path modulePath = packagePath.getParent();
            Path projectPath = modulePath.getParent();
            DocProject project = new DocProject(projectPath.toFile().getName());
            DocModule module = new DocModule(project, modulePath.toFile().getName());
            DocPackage docPackage = new DocPackage(module, packagePath.toFile().getName());
            DocType docType = new DocType(docPackage, path.toFile().getName());

            Map result = new LinkedHashMap<>();

            if (ReferentialDto.class.isAssignableFrom(dtoType)) {
                @SuppressWarnings("unchecked") Class referentialType = (Class) dtoType;
                ToolkitTreeNodeStates all = referentialEntityService.getAll(referentialType, config);
                consumeGetAll(Requests.GetAll, path, all);
            }

            consumeGet(docType, path, dtoType, fullToolkitTreeNodeStates, id, result);

            Map object = consumeUpdate(docType, path, toolkitTreeNodeStates, id, result);
            consumeCreate(docType, path, object, result);
            consumeDelete(docType, path, id);
        }
    }

    protected  void consumeGet(DocType docType, Path path, Class dtoType, ToolkitTreeNodeStates toolkitTreeNodeStates, String id, Map result) {
        DocRequest requestOne = new DocRequest(docType, Requests.GetOne);
        Map requestOneParameters = addConfigParameters(createParameters());
        String requestPrototypeContent = toJson(requestOne, null);
        requestOne.setIdInPath(id);
        String requestOneContent = toJson(requestOne, requestOneParameters);
        String json = toolkitTreeNodeStates.getState("content");
        List> listObject = gson.fromJson(json, (Type) Object.class);
        Map object = listObject.get(0);
        TemplateHelper.reduceResult(object);
        String topiaCreateDate = (String) object.get("topiaCreateDate");
        String lastUpdateDate = (String) object.get("lastUpdateDate");
        result.put("id", id);
        result.put("topiaCreateDate", dataAdapter.deserializeToDate(topiaCreateDate));
        result.put("lastUpdateDate", dataAdapter.deserializeToDate(lastUpdateDate));

        toolkitTreeNodeStates.addState("content", List.of(object));
        String responseContent = gson.toJson(toolkitTreeNodeStates.getStates());

        write(requestOne, path, requestPrototypeContent, requestOneContent, responseContent);

        DocRequest request = new DocRequest(docType, Requests.GetSome);
        Map requestParameters = addConfigParameters(createParameters());
        boolean canUse = false;
        if (ReferentialDto.class.isAssignableFrom(dtoType)) {
            if (ReferentialDtoReferenceWithNoCodeAware.class.isAssignableFrom(dtoType)) {
                switch (dtoType.getSimpleName().replace("Dto", "")) {
                    case "Person":
                        addSimpleFiltersParameter(requestParameters, object, "lastName");
                        addSimpleFiltersParameter(requestParameters, object, "firstName");
                        canUse = true;
                        break;
                    case "Species":
                        addSimpleFiltersParameter(requestParameters, object, "faoCode");
                        canUse = true;
                        break;
                    case "LengthLengthParameter":
                    case "LengthWeightParameter":
                        addFiltersParameter(requestParameters, object, "ocean", "ocean_id");
                        addFiltersParameter(requestParameters, object, "species", "species_id");
                        addFiltersParameter(requestParameters, object, "sex", "sex_id");
                        canUse = true;
                        break;
                }
            } else if (ReferentialDtoReferenceWithCodeAware.class.isAssignableFrom(dtoType)) {
                addSimpleFiltersParameter(requestParameters, object, "code");
                canUse = true;
            }
        } else {
            //FIXME Add more nice requests
            addSimpleFiltersParameter(requestParameters, object, "lastUpdateDate");
            canUse = true;
        }
        if (canUse) {
            String requestContent = toJson(request, requestParameters);
            write(request, path, requestContent, responseContent);
        }
    }

    protected Map consumeUpdate(DocType docType, Path path, ToolkitTreeNodeStates toolkitTreeNodeStates, String id, Map result) {
        DocRequest request = new DocRequest(docType, Requests.Update);
        String json = toolkitTreeNodeStates.getState("content");
        List> listObject = gson.fromJson(json, (Type) Object.class);
        Map object = listObject.get(0);
        String requestPrototypeContent = toJson(request, null);
        request.setIdInPath(id);

        TemplateHelper.reduceResult(object);
        write(docType.resolveContent(path), gson.toJson(object));

        TemplateHelper.reduceForCreate(object);
        write(docType.resolveCreate(path), gson.toJson(object));

        Map requestParameters = createParameters();
        addParameter(requestParameters, PAYLOAD, object);
        String requestContent = toJson(request, requestParameters);
        String responseContent = gson.toJson(result);
        write(request, path, requestPrototypeContent, requestContent, responseContent);
        return object;
    }

    protected void consumeCreate(DocType docType, Path path, Map object, Map result) {
        DocRequest request = new DocRequest(docType, Requests.Create);
        TemplateHelper.reduceResult(object);
        Map requestParameters = addParameter(createParameters(), PAYLOAD, object);
        String requestContent = toJson(request, requestParameters);
        String responseContent = gson.toJson(result);
        write(request, path, requestContent, responseContent);
    }

    protected void consumeDelete(DocType docType, Path path, String id) {
        DocRequest request = new DocRequest(docType, Requests.Delete);
        String requestPrototypeContent = toJson(request, null);
        Map requestParameters = createParameters();
        request.setIdInPath(id);
        String requestContent = toJson(request, requestParameters);
        String responseContent = "{}";
        write(request, path, requestPrototypeContent, requestContent, responseContent);
    }

    private void consumeGetAll(Requests requests, Path path, ToolkitTreeNodeStates toolkitTreeNodeStates) {
        DocRequest request = new DocRequest(DocProject.API_PATH_PREFIX + "/" + path, requests, null);

        Map parameter = addParameter(createParameters(), "config.prettyPrint", "true");
        String requestContent = toJson(request, parameter);

        String json = toolkitTreeNodeStates.getState("content");
        Object object = gson.fromJson(json, (Type) Object.class);
        if (object instanceof Collection) {
            TemplateHelper.reduceResult((Collection) object);
        }
        if (object instanceof Map) {
            TemplateHelper.reduceResult((Map) object);
        }
        toolkitTreeNodeStates.addState("content", object);
        String responseContent = gson.toJson(toolkitTreeNodeStates.getStates());

        write(request, path, requestContent, responseContent);
    }

    private void write(DocRequest request, Path path, String requestContent, String responseContent) {
        String requestPrototypeContent = toJson(request, null);
        write(request.resolveRequestPrototype(path), requestPrototypeContent);
        if (requestContent != null) {
            write(request.resolveExampleRequest(path), requestContent);
        }
        if (responseContent != null) {
            write(request.resolveExampleResponse(path), responseContent);
        }
    }

    private void write(DocRequest request, Path path, String requestPrototypeContent, String requestContent, String responseContent) {
        write(request.resolveRequestPrototype(path), requestPrototypeContent);
        if (requestContent != null) {
            write(request.resolveExampleRequest(path), requestContent);
        }
        if (responseContent != null) {
            write(request.resolveExampleResponse(path), responseContent);
        }
    }

    public String toJson(DocRequest request, Map variables) {
        boolean usePayload = request.withContent();
        Object payload = null;
        if (variables == null) {
            variables = request.parametersMap();
            payload = true;
        } else {
            if (usePayload) {
                payload = Objects.requireNonNull(variables.remove(PAYLOAD));
            }
        }
        String requestContent = request.getPath();
        int beginIndex = requestContent.indexOf("?");
        String hostPart = requestContent.substring(0, beginIndex);
        Map requestProperties = new LinkedHashMap<>();
        requestProperties.put("url", hostPart);
        requestProperties.put("method", request.getMethod());
        requestProperties.put("headers", request.getHeaders());
        requestProperties.put("parameters", variables);
        if (usePayload) {
            requestProperties.put(PAYLOAD, payload);
        }
        return gson.toJson(requestProperties);
    }

    private void write(Path path, String requestContent) {
        try {
            Path target = model.getFixturesPath().resolve(path);
            if (Files.notExists(target.getParent())) {
                Files.createDirectories(target.getParent());
            }
            Files.deleteIfExists(target);
            Files.write(target, requestContent.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    private Map createParameters() {
        return new LinkedHashMap<>();
    }

    private Map addParameter(Map variables, String key, Object value) {
        if (key.equals("id") || key.equals("filter.id")) {
            value = ToolkitId.encodeId((String) value);
        }
        variables.put(key, value);
        return variables;
    }

    private void addSimpleFiltersParameter(Map variables, Map object, String objectKey) {
        addFiltersParameter(variables, object, objectKey, objectKey);
    }

    private void addFiltersParameter(Map variables, Map object, String objectKey, String key) {
        Object value = object.get(objectKey);
        if (key.endsWith("id")) {
            value = ToolkitId.encodeId((String) value);
        }
        variables.put("filters." + key, value);
    }

    private Map addConfigParameters(Map variables) {
        variables.put("config.recursive", "true");
        variables.put("config.prettyPrint", "true");
        variables.put("config.serializeNulls", "true");
        return variables;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy