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

fr.ird.observe.spi.module.BusinessProject Maven / Gradle / Ivy

package fr.ird.observe.spi.module;

/*-
 * #%L
 * ObServe Toolkit :: Dto
 * %%
 * Copyright (C) 2017 - 2021 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.BusinessDto;
import fr.ird.observe.dto.IdDto;
import fr.ird.observe.dto.ObserveUtil;
import fr.ird.observe.dto.ToolkitId;
import fr.ird.observe.dto.ToolkitIdDtoBean;
import fr.ird.observe.dto.data.ContainerChildDto;
import fr.ird.observe.dto.data.ContainerDto;
import fr.ird.observe.dto.data.DataDto;
import fr.ird.observe.dto.data.EditableDto;
import fr.ird.observe.dto.data.OpenableDto;
import fr.ird.observe.dto.data.SimpleDto;
import fr.ird.observe.dto.form.FormDefinition;
import fr.ird.observe.dto.reference.DataDtoReference;
import fr.ird.observe.dto.reference.DtoReference;
import fr.ird.observe.dto.reference.DtoReferenceDefinition;
import fr.ird.observe.dto.reference.ReferentialDtoReference;
import fr.ird.observe.dto.referential.ReferentialDto;
import fr.ird.observe.spi.ProjectPackagesDefinition;
import fr.ird.observe.spi.decoration.I18nDecoratorHelper;
import io.ultreia.java4all.bean.definition.JavaBeanDefinition;
import io.ultreia.java4all.bean.definition.JavaBeanDefinitionStore;
import io.ultreia.java4all.i18n.I18n;
import io.ultreia.java4all.i18n.spi.type.TypeTranslators;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created on 03/10/2020.
 *
 * @author Tony Chemit - [email protected]
 * @since 8.0.1
 */
public class BusinessProject {

    private static final Logger log = LogManager.getLogger(BusinessProject.class);
    private static final Set SKIP_PROPERTIES = new LinkedHashSet<>(Arrays.asList(
            ReferentialDto.PROPERTY_LAST_UPDATE_DATE,
            ReferentialDto.PROPERTY_ID,
            ReferentialDto.PROPERTY_CREATE_DATE,
            ReferentialDto.PROPERTY_VERSION,
            ReferentialDto.PROPERTY_STATUS,
            ToolkitId.PROPERTY_PERSISTED,
            ToolkitId.PROPERTY_NOT_PERSISTED,
            ToolkitId.PROPERTY_TOOLKIT_ID,
            ToolkitId.PROPERTY_TOOLKIT_VERSION,
            ToolkitId.PROPERTY_TOOLKIT_CREATE_DATE));
    private final String name;
    private final List modules;
    private final BusinessProjectMapping mapping;
    private LinkedHashMap, List> referentialBusinessProperties;
    private ProjectPackagesDefinition packagesDefinition;

    public static boolean isReferential(Class type) {
        return ReferentialDto.class.isAssignableFrom(type) || ReferentialDtoReference.class.isAssignableFrom(type);
    }

    public static boolean isData(Class type) {
        return DataDto.class.isAssignableFrom(type) || DataDtoReference.class.isAssignableFrom(type);
    }

    public static String getLayout(BusinessModule businessModule, BusinessSubModule subBusinessModule, boolean data, String simpleName) {
        return businessModule.getName() + "." + (data ? "data" : "referential") + "." + subBusinessModule.getName() + "." + simpleName;
    }

    public static Path getDtoVariablePath(Path rootPath, BusinessModule module, BusinessSubModule subModule, Class dtoType) {
        String simpleName = dtoType.getSimpleName().replace("Dto", "");
        return rootPath.resolve(isData(dtoType) ? "data" : "referential").resolve(module.getName()).resolve(subModule.getName()).resolve(simpleName);
    }

    private static List getBusinessProperties0(Class dtoType) {
        JavaBeanDefinition javaBeanDefinition = JavaBeanDefinitionStore.getDefinition(dtoType).orElseThrow(() -> new IllegalStateException("Could not find javaBean definition for dto type: " + dtoType.getName()));
        List propertyNames = new LinkedList<>();
        javaBeanDefinition.readAndWriteProperties().filter(p -> !SKIP_PROPERTIES.contains(p.propertyName())).forEach(p -> propertyNames.add(p.propertyName()));
        return propertyNames;
    }

    public BusinessProject(String name, List modules, BusinessProjectMapping mapping) {
        this.name = Objects.requireNonNull(name);
        this.modules = Objects.requireNonNull(modules);
        this.mapping = mapping;
    }

    public  List> sortWithLongTitle(Collection> types, Locale locale) {
        return ObserveUtil.sortTypes(types, t -> getLongTitle(t, locale), locale);
    }

    public ToolkitIdDtoBean toShortDto(String id) {
        Class type = toDtoType(id);
        return ToolkitIdDtoBean.of(type, id);
    }

    public Class toDtoType(String id) {
        if (id == null) {
            return null;
        }
        ProjectPackagesDefinition packagesDefinition = getPackagesDefinition();
        String relativeEntityPackage = packagesDefinition.getRelativeEntityPackageFromId(id);
        String dtoFqn = packagesDefinition.getDtoRootPackage() + "." + relativeEntityPackage + "Dto";
        return getTypes().stream().filter(t -> dtoFqn.equals(t.getName())).findFirst().orElse(null);
    }

    public ProjectPackagesDefinition getPackagesDefinition() {
        if (packagesDefinition == null) {
            packagesDefinition = ProjectPackagesDefinition.of(getClass().getClassLoader());
        }
        return packagesDefinition;
    }

    public boolean accept(BusinessModule module, BusinessDto dto) {
        return module.getDataTypes().contains(dto.getClass()) || module.getReferentialTypes().contains(dto.getClass());
    }

    public String getDtoSimplifiedName(Class type) {
        String packageName = type.getPackage().getName();
        BusinessModule businessModule = getBusinessModule(packageName);
        BusinessSubModule subBusinessModule = getBusinessSubModule(businessModule, packageName);
        String simpleName = TypeTranslators.getTranslator(type).cleanSimpleName(type.getSimpleName());
        return getLayout(businessModule, subBusinessModule, isData(type), simpleName);
    }

    public Pair load(Class type) {
        String packageName = type.getPackage().getName();
        BusinessModule businessModule = getBusinessModule(packageName);
        BusinessSubModule subBusinessModule = getBusinessSubModule(businessModule, packageName);
        return Pair.of(businessModule, subBusinessModule);
    }

    public int getModulePriority(BusinessModule module) {
        return modules.indexOf(module);
    }

    public  Optional> getOptionalReferenceDefinition(Class dtoType) {
        return Optional.ofNullable(getMapping().getDtoToReferenceDtoClassMapping().getDefinition(dtoType));
    }

    public  Optional> getOptionalFormDefinition(Class dtoType) {
        return Optional.ofNullable(getMapping().getDtoToFormDtoMapping().getForm(dtoType));
    }

    public String getName() {
        return name;
    }

    public List getModules() {
        return modules;
    }

    public Set> getTypes() {
        return modules.stream().flatMap(m -> m.getTypes().stream()).collect(Collectors.toSet());
    }

    public Set> getReferentialTypes() {
        return modules.stream().flatMap(m -> m.getReferentialTypes().stream()).collect(Collectors.toSet());
    }

    public Set> getDataTypes() {
        return modules.stream().flatMap(m -> m.getDataTypes().stream()).collect(Collectors.toSet());
    }

    public Set> getSimpleDataTypes() {
        return modules.stream().flatMap(m -> m.getSimpleDataTypes().stream()).collect(Collectors.toSet());
    }

    public Set> getOpenableDataTypes() {
        return modules.stream().flatMap(m -> m.getOpenableDataTypes().stream()).collect(Collectors.toSet());
    }

    public Set> getEditableDataTypes() {
        return modules.stream().flatMap(m -> m.getEditableDataTypes().stream()).collect(Collectors.toSet());
    }

    public Set>> getContainerDataTypes() {
        return modules.stream().flatMap(m -> m.getContainerDataTypes().stream()).collect(Collectors.toSet());
    }

    @SuppressWarnings("unused")
    public Set> getContainerChildDataTypes() {
        return modules.stream().flatMap(m -> m.getContainerChildDataTypes().stream()).collect(Collectors.toSet());
    }

    public BusinessProjectMapping getMapping() {
        return mapping;
    }

    public BusinessModule getBusinessModule(String packageName) {
        String cleanPackageName = packageName.replace(".data", "")
                .replace(".referential", "");
        int lastIndexOf = cleanPackageName.lastIndexOf(".");
        String tmp = cleanPackageName.substring(0, lastIndexOf);
        String subModule = cleanPackageName.substring(lastIndexOf + 1);
        String module = tmp.substring(tmp.lastIndexOf(".") + 1);
        return modules.stream()
                .filter(m -> m.getName().equalsIgnoreCase(module))
                .findFirst()
                .orElse(modules.stream().filter(m -> m.getName().equalsIgnoreCase(subModule)).findFirst().orElse(null));
    }

    public BusinessSubModule getBusinessSubModule(BusinessModule module, String packageName) {
        String suffix = packageName.substring(packageName.lastIndexOf(".") + 1);
        return module.getSubModules().stream().filter(m -> m.getName().equalsIgnoreCase(suffix)).findFirst().orElse(null);
    }

    public BusinessSubModule getBusinessSubModule(BusinessModule module, Class subModuleType) {
        return module.getSubModules().stream().filter(m -> subModuleType.equals(m.getClass())).findFirst().orElse(null);
    }

    public BusinessModule getBusinessModule(Class moduleType) {
        return modules.stream().filter(m -> moduleType.equals(m.getClass())).findFirst().orElse(null);
    }

    public String getReferentialPackageTitle(BusinessModule module, BusinessSubModule subModule) {
        String shortLabel;
        if (module.getName().equals("common")) {
            shortLabel = "";
        } else {
            shortLabel = String.format("[%s] ", module.getShortLabel());
        }
        return I18n.t("observe.referential.package.title",
                      shortLabel,
                      subModule.getLabel());
    }

    public String getReferentialPackageTitle(BusinessModule module, BusinessSubModule subModule, Locale locale) {
        String shortLabel;
        if (module.getName().equals("common")) {
            shortLabel = "";
        } else {
            shortLabel = String.format("[%s] ", module.getShortLabel(locale));
        }
        return I18n.t("observe.referential.package.title",
                      shortLabel,
                      subModule.getLabel(locale));
    }

    public String gotoReferentialHomeToolTipText(BusinessModule module, BusinessSubModule subModule) {
        String text = getReferentialPackageTitle(module, subModule);
        return I18n.t("observe.Common.action.goto.tip", text);
    }

    public String gotoSelectedDataToolTipText(Class type) {
        return I18n.t("observe.Common.action.goto.selected.tip", I18nDecoratorHelper.getType(type));
    }

    public String createDataToolTipText(Class type) {
        String text = getDataTitleWithSubModulePrefix(type);
        return I18n.t("observe.Common.action.create.tip", text);
    }

    public String saveDataToolTipText(Class type) {
        String text = getDataTitleWithSubModulePrefix(type);
        return I18n.t("observe.Common.action.save.tip", text);
    }

    public String gotoOpenDataToolTipText(Class type) {
        String text = getDataTitleWithSubModulePrefix(type);
        return I18n.t("observe.Common.action.goto.open.tip", text);
    }

    public String getDataTitleWithSubModulePrefix(Class type) {
        Pair pair = load(type);
        BusinessSubModule subModule = pair.getRight();
        String prefix;
        if (subModule.getName().equals("common")) {
            prefix = "";
        } else {
            prefix = subModule.getLabel() + " - ";

        }
        return prefix + I18nDecoratorHelper.getType(type);
    }

    public String getFullTitle(Locale locale, Class type) {
        String prefix = isReferential(type) ? I18n.l(locale, "observe.Common.type.referential") : I18n.l(locale, "observe.Common.type.data");
        return prefix + " ` " + getLongTitle(type) + " `";
    }

    public String getLongTitle(Class type) {
        Pair pair = load(type);
        BusinessModule module = pair.getLeft();
        BusinessSubModule subModule = pair.getRight();
        String prefix = module.getLabel() + " - ";
        if (!module.getName().equals("common") || !subModule.getName().equals("common")) {
            prefix += subModule.getLabel() + " - ";
        }
        return prefix + I18nDecoratorHelper.getType(type);
    }

    public String getLongTitle(Class type, Locale locale) {
        Pair pair = load(type);
        BusinessModule module = pair.getLeft();
        BusinessSubModule subModule = pair.getRight();
        String prefix = module.getLabel(locale) + " - ";
        if (!module.getName().equals("common") || !subModule.getName().equals("common")) {
            prefix += subModule.getLabel(locale) + " - ";
        }
        return prefix + I18nDecoratorHelper.getType(locale, type);
    }

    @SuppressWarnings("unchecked")
    public List> sortReferentialTypesWithPackage(Locale locale, Set> classes) {
        return ObserveUtil.sortTypes(classes, t -> getReferentialWithPackage(locale, t), locale);
    }

    public void accept(BusinessProjectVisitor visitor) {
        BusinessProjectVisitor.simpleVisit(this, visitor);
    }

    public LinkedHashMap, List> getReferentialBusinessProperties() {
        if (referentialBusinessProperties == null) {
            referentialBusinessProperties = new LinkedHashMap<>();

            for (Class dtoType : getMapping().getDtoToMainDtoClassMapping().values()) {
                if (BusinessProject.isReferential(dtoType)) {
                    try {
                        @SuppressWarnings("unchecked") Class dtoType1 = (Class) dtoType;
                        List propertyNames = getBusinessProperties0(dtoType1);
                        log.info(String.format("%s - Detected %s business properties: %s.", dtoType.getName(), propertyNames.size(), propertyNames));
                        referentialBusinessProperties.put(dtoType1, propertyNames);
                    } catch (Exception e) {
                        throw new IllegalStateException("Could not find business properties for referential type: " + dtoType.getName(), e);
                    }
                }
            }
        }
        return referentialBusinessProperties;
    }

    private String getReferentialWithPackage(Locale locale, Class type) {
        String packageName = type.getPackageName();
        BusinessModule module = getBusinessModule(packageName);
        BusinessSubModule subModule = getBusinessSubModule(module, packageName);
        String prefix = getReferentialPackageTitle(module, subModule, locale);
        return prefix + " - " + I18nDecoratorHelper.getType(locale, type);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy