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

fr.ird.observe.spi.DtoModelHelper Maven / Gradle / Ivy

There is a newer version: 4.34
Show newest version
package fr.ird.observe.spi;

/*-
 * #%L
 * ObServe Toolkit :: Common Dto
 * %%
 * 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 com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import fr.ird.observe.dto.DtoToReference;
import fr.ird.observe.dto.IdDto;
import fr.ird.observe.dto.data.DataDto;
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.dto.referential.ReferentialLocale;
import fr.ird.observe.spi.mapping.DtoToFormDtoMapping;
import fr.ird.observe.spi.mapping.DtoToMainDtoClassMapping;
import fr.ird.observe.spi.mapping.DtoToReferenceDtoMapping;
import fr.ird.observe.spi.mapping.ReferenceDtoToDtoClassMapping;
import io.ultreia.java4all.application.context.spi.GenerateApplicationComponent;
import io.ultreia.java4all.bean.definition.JavaBeanDefinition;
import io.ultreia.java4all.bean.definition.JavaBeanDefinitionStore;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

/**
 * Created by tchemit on 02/09/17.
 *
 * @author Tony Chemit - [email protected]
 */
@SuppressWarnings({"unchecked", "rawtypes", "unused"})
@GenerateApplicationComponent(name = "Dto Model Helper",
        dependencies = {
                DtoToReferenceDtoMapping.class,
                ReferenceDtoToDtoClassMapping.class,
                DtoToFormDtoMapping.class,
                DtoToMainDtoClassMapping.class
        })
public class DtoModelHelper {

    private static final Logger log = LogManager.getLogger(DtoModelHelper.class);

    private static final ImmutableSet SKIP_PROPERTIES = ImmutableSet.builder()
            .add(ReferentialDto.PROPERTY_LAST_UPDATE_DATE)
            .add(ReferentialDto.PROPERTY_ID)
            .add(ReferentialDto.PROPERTY_CREATE_DATE)
            .add(ReferentialDto.PROPERTY_VERSION)
            .add(ReferentialDto.PROPERTY_STATUS)
            .add("persisted")
            .add("notPersisted")
            .add("topiaId")
            .add("topiaCreateDate")
            .add("topiaVersion")
            .build();

    /**
     * Dictionary of business properties for each referential type.
     */
    private final ArrayListMultimap, String> REFERENTIAL_BUSINESS_PROPERTIES = ArrayListMultimap.create();

    private static final DtoModelHelper INSTANCE = DtoModelHelperApplicationComponent.value();

    private final DtoToReferenceDtoMapping dtoToReferenceDtoMapping;
    private final ReferenceDtoToDtoClassMapping referenceDtoToDtoClassMapping;
    private final DtoToFormDtoMapping dtoToFormDtoMapping;
    private final DtoToMainDtoClassMapping dtoToMainDtoClassMapping;
    private final ImmutableSet referentialClasses;
    private final ImmutableSet mainDataClasses;

    public DtoModelHelper(DtoToReferenceDtoMapping dtoToReferenceDtoMapping,
                          ReferenceDtoToDtoClassMapping referenceDtoToDtoClassMapping,
                          DtoToFormDtoMapping dtoToFormDtoMapping,
                          DtoToMainDtoClassMapping dtoToMainDtoClassMapping
    ) {
        log.info("Dto model helper initialization  (" + this + ").");
        this.dtoToReferenceDtoMapping = Objects.requireNonNull(dtoToReferenceDtoMapping);
        this.referenceDtoToDtoClassMapping = Objects.requireNonNull(referenceDtoToDtoClassMapping);
        this.dtoToFormDtoMapping = Objects.requireNonNull(dtoToFormDtoMapping);
        this.dtoToMainDtoClassMapping = Objects.requireNonNull(dtoToMainDtoClassMapping);

        Set mainDataClassesBuilder = new LinkedHashSet<>();
        Set referentialClassesBuilder = new LinkedHashSet<>();

        int referentialCount = 0;
        int dataCount = 0;

        for (Class dtoType : this.dtoToMainDtoClassMapping.values()) {
            if (isReferential(dtoType)) {
                referentialClassesBuilder.add(dtoType);
                referentialCount++;
                try {
                    Class dtoType1 = (Class) dtoType;
                    ImmutableList propertyNames = getBusinessProperties0(dtoType1);
                    log.info(String.format("%s - Detected %s business properties: %s.", dtoType.getName(), propertyNames.size(), propertyNames));
                    REFERENTIAL_BUSINESS_PROPERTIES.putAll(dtoType1, propertyNames);
                } catch (Exception e) {
                    throw new IllegalStateException("Could not find business properties for referential type: " + dtoType.getName(), e);
                }
            } else {
                mainDataClassesBuilder.add(dtoType);
                dataCount++;
            }
        }

        log.info("Load " + referentialCount + " referential definitions.");
        log.info("Load " + dataCount + " data definitions.");
        log.info("Load " + referenceDtoToDtoClassMapping.size() + " reference definitions.");
        log.info("Load " + dtoToFormDtoMapping.size() + " form definitions.");
        log.info("Load " + dtoToMainDtoClassMapping.size() + " dto to main dto types.");

        this.referentialClasses = ImmutableSet.copyOf(referentialClassesBuilder);
        this.mainDataClasses = ImmutableSet.copyOf(mainDataClassesBuilder);

        log.info("Dto model helper is initialized (" + this + ").");
    }

    public static Set> getReferentialClasses() {
        return (Set) INSTANCE.referentialClasses;
    }

    public static Set> getMainDataClasses() {
        return (Set) INSTANCE.mainDataClasses;
    }

    public static > Class getReferenceType(Class dtoType) {
        if (Modifier.isAbstract(dtoType.getModifiers())) {
            if (ReferentialDto.class.isAssignableFrom(dtoType)) {
                return (Class) ReferentialDtoReference.class;
            }
            if (DataDto.class.equals(dtoType)) {
                return (Class) DataDtoReference.class;
            }
        }
        return getDtoToReferenceDtoClassMapping().get(dtoType);
    }

    public static > Class getDtoType(Class dtoType) {
        if (Modifier.isAbstract(dtoType.getModifiers())) {
            if (ReferentialDtoReference.class.isAssignableFrom(dtoType)) {
                return (Class) ReferentialDto.class;
            }
            if (DataDtoReference.class.equals(dtoType)) {
                return (Class) DataDto.class;
            }
        }
        return getReferenceDtoToDtoClassMapping().get(dtoType);
    }

    public static > R toReference(ReferentialLocale referentialLocale, D dto) {
        return (R) ((DtoToReference) dto).toReference(referentialLocale);
    }

    public static  Class getMainDtoType(Class dtoType) {
        return getDtoToMainDtoClassMapping().get(dtoType);
    }

    public static ImmutableSet> getSubDtoTypes(Class mainDtoType) {
        ImmutableSet.Builder> builder = ImmutableSet.builder();
        for (Class dtoType : getDtoToMainDtoClassMapping().keySet()) {
            if (Objects.equals(mainDtoType, getMainDtoType(dtoType))) {
                builder.add(dtoType);
            }
        }
        return builder.build();
    }

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

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

    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 Collection getBusinessProperties(Class dtoType) {
        return INSTANCE.REFERENTIAL_BUSINESS_PROPERTIES.get(dtoType);
    }

    protected static DtoToFormDtoMapping getDtoToFormDtoMapping() {
        return INSTANCE.dtoToFormDtoMapping;
    }

    public static DtoToMainDtoClassMapping getDtoToMainDtoClassMapping() {
        return INSTANCE.dtoToMainDtoClassMapping;
    }

    public static DtoToReferenceDtoMapping getDtoToReferenceDtoClassMapping() {
        return INSTANCE.dtoToReferenceDtoMapping;
    }

    protected static ReferenceDtoToDtoClassMapping getReferenceDtoToDtoClassMapping() {
        return INSTANCE.referenceDtoToDtoClassMapping;
    }

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

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy