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

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

The newest version!
package fr.ird.observe.spi;

/*-
 * #%L
 * ObServe Toolkit :: Common Db
 * %%
 * Copyright (C) 2008 - 2017 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.binder.EntityBinderSupport;
import fr.ird.observe.dto.IdDto;
import fr.ird.observe.dto.IdHelper;
import fr.ird.observe.dto.data.DataDto;
import fr.ird.observe.dto.form.FormDefinition;
import fr.ird.observe.dto.reference.DataDtoReferenceSupport;
import fr.ird.observe.dto.reference.ReferentialDtoReferenceSupport;
import fr.ird.observe.dto.referential.ReferentialDto;
import fr.ird.observe.entities.ObserveDataEntity;
import fr.ird.observe.entities.referentiel.ObserveReferentialEntity;
import fr.ird.observe.spi.context.DataDtoEntityContext;
import fr.ird.observe.spi.context.DataEntityContext;
import fr.ird.observe.spi.context.DataReferenceEntityContext;
import fr.ird.observe.spi.initializer.DtoFormsInitializerSupport;
import fr.ird.observe.spi.initializer.DtoReferencesInitializerSupport;
import fr.ird.observe.spi.map.DtoToEntityClassMap;
import fr.ird.observe.spi.map.DtoToReferenceClassMap;
import fr.ird.observe.spi.initializer.EntitiesBinderInitializerSupport;
import fr.ird.observe.spi.map.ImmutableDtoMap;
import fr.ird.observe.spi.context.ReferentialDtoEntityContext;
import fr.ird.observe.spi.context.ReferentialEntityContext;
import fr.ird.observe.spi.context.ReferentialReferenceEntityContext;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.persistence.TopiaEntityEnum;


import static fr.ird.observe.spi.DtoModelHelper.getFormInitializer;
import static fr.ird.observe.spi.DtoModelHelper.getReferencesInitializer;

/**
 * Created by tchemit on 29/08/17.
 *
 * @author Tony Chemit - [email protected]
 */
@SuppressWarnings("unchecked")
public class DbModelHelper {

    /** Logger. */
    private static final Log log = LogFactory.getLog(DtoModelHelper.class);

    private static final DbModelHelper INSTANCE = new DbModelHelper();

    private final ImmutableDtoMap referentialDtoContext;
    private final ImmutableDtoMap referentialEntityContext;
    private final ImmutableDtoMap referentialReferenceContext;
    private final ImmutableDtoMap dataDtoContext;
    private final ImmutableDtoMap dataReferenceContext;
    private final ImmutableDtoMap dataEntityContext;

    
    public static , E extends ObserveReferentialEntity> ReferentialDtoEntityContext fromReferentialDto(D dtoType) {
        return fromReferentialDto((Class) dtoType.getClass());
    }

    
    public static , E extends ObserveReferentialEntity> ReferentialDtoEntityContext fromReferentialDto(Class dtoType) {
        return INSTANCE.referentialDtoContext.get(dtoType);
    }

    
    public static , E extends ObserveReferentialEntity> ReferentialReferenceEntityContext fromReferentialReference(R reference) {
        return INSTANCE.referentialReferenceContext.get(reference.getClass());
    }

    
    public static , E extends ObserveReferentialEntity> ReferentialReferenceEntityContext fromReferentialReference(Class referenceType) {
        return INSTANCE.referentialReferenceContext.get(referenceType);
    }

    
    public static , E extends ObserveReferentialEntity> ReferentialEntityContext fromReferentialEntity(TopiaEntityEnum entityType) {
        return INSTANCE.referentialEntityContext.get(entityType.getContract());
    }

    
    public static , E extends ObserveReferentialEntity> ReferentialEntityContext fromReferentialEntity(E entity) {
        return INSTANCE.referentialEntityContext.get(entity.getClass());
    }

    
    public static , E extends ObserveReferentialEntity> ReferentialEntityContext fromReferentialEntity(Class entityType) {
        return INSTANCE.referentialEntityContext.get(entityType);
    }

    
    public static , E extends ObserveDataEntity> DataDtoEntityContext fromDataDto(D dto) {
        return fromDataDto((Class) dto.getClass());
    }

    
    public static , E extends ObserveDataEntity> DataDtoEntityContext fromDataDto(Class dtoType) {
        return INSTANCE.dataDtoContext.get(dtoType);
    }

    
    public static , E extends ObserveDataEntity> DataReferenceEntityContext fromDataReference(R reference) {
        return INSTANCE.dataReferenceContext.get(reference.getClass());
    }

    
    public static , E extends ObserveDataEntity> DataReferenceEntityContext fromDataReference(Class referenceType) {
        return INSTANCE.dataReferenceContext.get(referenceType);
    }

    
    public static , E extends ObserveDataEntity> DataEntityContext fromDataEntity(E entityType) {
        return INSTANCE.dataEntityContext.get(entityType.getClass());
    }

    public static , E extends ObserveDataEntity> DataEntityContext fromDataEntity(Class entityType) {
        return INSTANCE.dataEntityContext.get(entityType);
    }

    
    private DbModelHelper() {

        DtoReferencesInitializerSupport referencesInitializer = getReferencesInitializer();
        DtoFormsInitializerSupport formInitializer = getFormInitializer();
        EntitiesBinderInitializerSupport initializer = DtoModelHelper.getService(EntitiesBinderInitializerSupport.class);

        DtoToEntityClassMap dtoToEntityClassMapping = initializer.getDtoToEntityClassMapping();
        DtoToReferenceClassMap dtoToReferenceClassMapping = referencesInitializer.getDtoToReferenceClassMapping();

        ImmutableDtoMap.Builder referentialDtoContextBuilder = ImmutableDtoMap.builder();
        ImmutableDtoMap.Builder dataDtoContextBuilder = ImmutableDtoMap.builder();

        ImmutableDtoMap.Builder referentialReferenceContextBuilder = ImmutableDtoMap.builder();
        ImmutableDtoMap.Builder dataReferenceContextBuilder = ImmutableDtoMap.builder();

        ImmutableDtoMap.Builder referentialEntityContextBuilder = ImmutableDtoMap.builder(IdHelper::getEntitySimplifiedName);
        ImmutableDtoMap.Builder dataEntityContextBuilder = ImmutableDtoMap.builder(IdHelper::getEntitySimplifiedName);

        int referentialCount = 0;
        for (Class dtoType : referencesInitializer.getReferentialTypes()) {

            registerReferential(dtoType,
                                dtoToReferenceClassMapping,
                                dtoToEntityClassMapping,
                                referencesInitializer,
                                formInitializer,
                                initializer,
                                referentialDtoContextBuilder,
                                referentialReferenceContextBuilder,
                                referentialEntityContextBuilder);

            referentialCount++;
        }

        log.info("Load " + referentialCount + " referential definitions.");

        Collection> dtoTypesWithReference = referencesInitializer.getReferenceToDtoClassMapping().values();
        Collection dtoTypesWithForm = formInitializer.getDtoToFormClassMapping().values();

        int dataCountWithReference = 0;
        int dataCountWithForm = 0;
        Set> dataTypes = new LinkedHashSet<>(referencesInitializer.getDataTypes());
        dataTypes.addAll((Collection) dtoTypesWithForm);
        dataTypes.addAll((Collection) initializer.getEntityToDtoClassMapping().values().stream().filter(IdHelper::isData).collect(Collectors.toSet()));
        dataTypes.addAll((Collection) initializer.getEntityDtoDataBinders().values().stream().filter(f -> IdHelper.isData(f.getDtoType())).map(EntityBinderSupport::getDtoType).collect(Collectors.toSet()));

        for (Class dtoType : dataTypes) {

            FormDefinition formDefinition = null;
            if (dtoTypesWithForm.contains(dtoType)) {
                dataCountWithForm++;
                formDefinition = formInitializer.getFormDefinitions().get(dtoType);
            }
            if (dtoTypesWithReference.contains(dtoType)) {
                registerDataWithReference(dtoType,
                                          dtoToReferenceClassMapping,
                                          dtoToEntityClassMapping,
                                          referencesInitializer,
                                          formDefinition,
                                          initializer,
                                          dataDtoContextBuilder,
                                          dataReferenceContextBuilder,
                                          dataEntityContextBuilder);
                dataCountWithReference++;
            } else {
                registerData(dtoType,
                             dtoToEntityClassMapping,
                             referencesInitializer,
                             formDefinition,
                             initializer,
                             dataDtoContextBuilder,
                             dataEntityContextBuilder);
            }

        }

        log.info("Load " + dataCountWithReference + " reference definitions.");
        log.info("Load " + dataCountWithForm + " form definitions.");

        log.info("Load " + referencesInitializer.getReferentialBinders().size() + " dto referential binders.");
        log.info("Load " + initializer.getEntityDtoReferentialBinders().size() + " entity referential binders.");
        log.info("Load " + referencesInitializer.getDataBinders().size() + " dto data binders.");
        log.info("Load " + initializer.getEntityDtoDataBinders().size() + " entity data binders.");


        this.referentialDtoContext = referentialDtoContextBuilder.build();
        this.dataDtoContext = dataDtoContextBuilder.build();

        this.referentialReferenceContext = referentialReferenceContextBuilder.build();
        this.dataReferenceContext = dataReferenceContextBuilder.build();

        this.referentialEntityContext = referentialEntityContextBuilder.build();
        this.dataEntityContext = dataEntityContextBuilder.build();

    }


    private static , E extends ObserveReferentialEntity> void registerReferential(Class dtoType,
                                                                                                                                                           DtoToReferenceClassMap dtoToReferenceClassMapping,
                                                                                                                                                           DtoToEntityClassMap dtoToEntityClassMap,
                                                                                                                                                           DtoReferencesInitializerSupport referencesInitializer,
                                                                                                                                                           DtoFormsInitializerSupport formInitializer,
                                                                                                                                                           EntitiesBinderInitializerSupport initializer,
                                                                                                                                                           ImmutableDtoMap.Builder referentialDtoContextBuilder,
                                                                                                                                                           ImmutableDtoMap.Builder referentialReferenceContextBuilder,
                                                                                                                                                           ImmutableDtoMap.Builder referentialEntityContextBuilder
    ) {

        referentialDtoContextBuilder.put(dtoType, new ReferentialDtoEntityContext<>(dtoType, referencesInitializer, formInitializer, initializer));

        Class referenceType = dtoToReferenceClassMapping.forReferential(dtoType);
        referentialReferenceContextBuilder.put(dtoType, new ReferentialReferenceEntityContext<>(referenceType, referencesInitializer, initializer));

        Class entityType = dtoToEntityClassMap.forReferential(dtoType);
        referentialEntityContextBuilder.put(entityType, new ReferentialEntityContext<>(entityType, referencesInitializer, initializer));


    }

    private static  void registerData(Class dtoType,
                                                                                      DtoToEntityClassMap dtoToEntityClassMap,
                                                                                      DtoReferencesInitializerSupport referencesInitializer,
                                                                                      FormDefinition formDefinition,
                                                                                      EntitiesBinderInitializerSupport initializer,
                                                                                      ImmutableDtoMap.Builder dataDtoContextBuilder,
                                                                                      ImmutableDtoMap.Builder dataEntityContextBuilder) {

        dataDtoContextBuilder.put(dtoType, new DataDtoEntityContext<>(dtoType, referencesInitializer, formDefinition, initializer));

        Class entityType = dtoToEntityClassMap.forData(dtoType);
        if (IdHelper.equalsCleanId(entityType, dtoType)) {
            // main dto, keep this link only since when coming from entity, we only can bind to main dto
            dataEntityContextBuilder.put(entityType, new DataEntityContext<>(entityType, referencesInitializer, initializer));
        }

    }

    private static , E extends ObserveDataEntity> void registerDataWithReference(Class dtoType,
                                                                                                                                            DtoToReferenceClassMap dtoToReferenceClassMapping,
                                                                                                                                            DtoToEntityClassMap dtoToEntityClassMap,
                                                                                                                                            DtoReferencesInitializerSupport referencesInitializer,
                                                                                                                                            FormDefinition formDefinition,
                                                                                                                                            EntitiesBinderInitializerSupport initializer,
                                                                                                                                            ImmutableDtoMap.Builder dataDtoContextBuilder,
                                                                                                                                            ImmutableDtoMap.Builder dataReferenceContextBuilder,
                                                                                                                                            ImmutableDtoMap.Builder dataEntityContextBuilder) {

        dataDtoContextBuilder.put(dtoType, new DataDtoEntityContext<>(dtoType, referencesInitializer, formDefinition, initializer));

        Class referenceType = dtoToReferenceClassMapping.forData(dtoType);
        dataReferenceContextBuilder.put(dtoType, new DataReferenceEntityContext<>(referenceType, referencesInitializer, initializer));

        Class entityType = dtoToEntityClassMap.forData(dtoType);
        if (IdHelper.equalsCleanId(entityType, dtoType)) {
            // main dto, keep this link only since when coming from entity, we only can bind to main dto
            dataEntityContextBuilder.put(dtoType, new DataEntityContext<>(entityType, referencesInitializer, initializer));
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy