
fr.ird.observe.spi.DbModelHelper Maven / Gradle / Ivy
package fr.ird.observe.spi;
/*-
* #%L
* ObServe Toolkit :: Common Persistence
* %%
* Copyright (C) 2017 - 2019 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.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.ReferentialDtoReference;
import fr.ird.observe.dto.referential.ReferentialDto;
import fr.ird.observe.entities.ObserveEntity;
import fr.ird.observe.entities.data.ObserveDataEntity;
import fr.ird.observe.entities.referential.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.context.DtoEntityContext;
import fr.ird.observe.spi.context.EntityContext;
import fr.ird.observe.spi.context.ReferenceEntityContext;
import fr.ird.observe.spi.context.ReferentialDtoEntityContext;
import fr.ird.observe.spi.context.ReferentialEntityContext;
import fr.ird.observe.spi.context.ReferentialReferenceEntityContext;
import fr.ird.observe.spi.initializer.DtoFormsInitializerSupport;
import fr.ird.observe.spi.initializer.DtoReferencesInitializerSupport;
import fr.ird.observe.spi.initializer.EntitiesBinderInitializerSupport;
import fr.ird.observe.spi.map.DtoToEntityClassMap;
import fr.ird.observe.spi.map.DtoToReferenceClassMap;
import fr.ird.observe.spi.map.ImmutableTypedMap;
import fr.ird.observe.spi.type.TypeTranslators;
import io.ultreia.java4all.application.context.spi.GenerateApplicationComponent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.nuiton.topia.persistence.TopiaEntityEnum;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Created by tchemit on 29/08/17.
*
* @author Tony Chemit - [email protected]
*/
@SuppressWarnings("unchecked")
@GenerateApplicationComponent(name = "Persistence Model Helper",
dependencies = {
DtoReferencesInitializerSupport.class,
DtoFormsInitializerSupport.class,
EntitiesBinderInitializerSupport.class
})
public class DbModelHelper {
private static final Logger log = LogManager.getLogger(DtoModelHelper.class);
private static final DbModelHelper INSTANCE = DbModelHelperApplicationComponent.value();
private final ImmutableTypedMap referentialDtoContext;
private final ImmutableTypedMap referentialEntityContext;
private final ImmutableTypedMap referentialReferenceContext;
private final ImmutableTypedMap dataDtoContext;
private final ImmutableTypedMap dataReferenceContext;
private final ImmutableTypedMap dataEntityContext;
public DbModelHelper(DtoReferencesInitializerSupport referencesInitializer, DtoFormsInitializerSupport formInitializer, EntitiesBinderInitializerSupport entitiesBinderInitializer) {
log.info("Persistence model helper initialization (" + this + ").");
// DtoReferencesInitializerSupport referencesInitializer = getReferencesInitializer();
// DtoFormsInitializerSupport formInitializer = getFormInitializer();
// EntitiesBinderInitializerSupport entitiesBinderInitializer = ServiceLoaders.loadUniqueService(EntitiesBinderInitializerSupport.class);
DtoToEntityClassMap dtoToEntityClassMapping = entitiesBinderInitializer.getDtoToEntityClassMapping();
DtoToReferenceClassMap dtoToReferenceClassMapping = referencesInitializer.getDtoToReferenceClassMapping();
ImmutableTypedMap.Builder referentialDtoContextBuilder = ImmutableTypedMap.builder();
ImmutableTypedMap.Builder dataDtoContextBuilder = ImmutableTypedMap.builder();
ImmutableTypedMap.Builder referentialReferenceContextBuilder = ImmutableTypedMap.builder();
ImmutableTypedMap.Builder dataReferenceContextBuilder = ImmutableTypedMap.builder();
ImmutableTypedMap.Builder referentialEntityContextBuilder = ImmutableTypedMap.builder();
ImmutableTypedMap.Builder dataEntityContextBuilder = ImmutableTypedMap.builder();
int referentialCount = 0;
for (Class extends ReferentialDto> dtoType : referencesInitializer.getReferentialTypes()) {
registerReferential(dtoType,
dtoToReferenceClassMapping,
dtoToEntityClassMapping,
referencesInitializer,
formInitializer,
entitiesBinderInitializer,
referentialDtoContextBuilder,
referentialReferenceContextBuilder,
referentialEntityContextBuilder);
referentialCount++;
}
log.debug("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) entitiesBinderInitializer.getEntityToDtoClassMapping().values().stream().filter(DtoModelHelper::isData).collect(Collectors.toSet()));
dataTypes.addAll((Collection) entitiesBinderInitializer.getEntityDtoDataBinders().values().stream().filter(f -> DtoModelHelper.isData(f.getDtoType())).map(EntityBinderSupport::getDtoType).collect(Collectors.toSet()));
dataTypes.removeAll(referencesInitializer.getReferentialTypes());
for (Class extends DataDto> 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,
entitiesBinderInitializer,
dataDtoContextBuilder,
dataReferenceContextBuilder,
dataEntityContextBuilder);
dataCountWithReference++;
} else {
registerData(dtoType,
dtoToEntityClassMapping,
referencesInitializer,
formDefinition,
entitiesBinderInitializer,
dataDtoContextBuilder,
dataEntityContextBuilder);
}
}
log.debug("Load " + dataCountWithReference + " reference definitions.");
log.debug("Load " + dataCountWithForm + " form definitions.");
log.info("Load " + referencesInitializer.getReferentialBinders().size() + " dto referential binders.");
log.info("Load " + entitiesBinderInitializer.getEntityDtoReferentialBinders().size() + " entity referential binders.");
log.info("Load " + referencesInitializer.getDataBinders().size() + " dto data binders.");
log.info("Load " + entitiesBinderInitializer.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();
log.info("Persistence model helper is initialized (" + this + ").");
}
public static boolean equalsDtoTypeAndEntityType(Class extends IdDto> one, Class extends ObserveEntity> two) {
return TypeTranslators.getDtoSimplifiedName(one).equals(TypeTranslators.getEntitySimplifiedName(two));
}
public static , E extends ObserveEntity> DtoEntityContext fromDto(D dtoType) {
return fromDto((Class) dtoType.getClass());
}
public static , E extends ObserveEntity> DtoEntityContext fromDto(Class dtoType) {
if (DtoModelHelper.isReferential(dtoType)) {
return INSTANCE.referentialDtoContext.get(dtoType);
} else {
return INSTANCE.dataDtoContext.get(dtoType);
}
}
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(getClass(entity));
}
public static , E extends ObserveReferentialEntity> ReferentialEntityContext fromReferentialEntity(Class entityType) {
return INSTANCE.referentialEntityContext.get(entityType);
}
public static , E extends ObserveEntity> EntityContext fromEntity(Class entityType) {
if (ObserveReferentialEntity.class.isAssignableFrom(entityType)) {
return INSTANCE.referentialEntityContext.get(entityType);
} else {
return INSTANCE.dataEntityContext.get(entityType);
}
}
public static , E extends ObserveEntity> ReferenceEntityContext fromReference(R reference) {
if (DtoModelHelper.isReferential(reference.getDtoType())) {
return INSTANCE.referentialReferenceContext.get(reference.getDtoType());
} else {
return INSTANCE.dataReferenceContext.get(reference.getDtoType());
}
}
public static , E extends ObserveEntity> ReferenceEntityContext fromReference(Class reference) {
if (DtoModelHelper.isReferential(reference)) {
return INSTANCE.referentialReferenceContext.get(reference);
} else {
return INSTANCE.dataReferenceContext.get(reference);
}
}
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 entity) {
return INSTANCE.dataEntityContext.get(getClass(entity));
}
public static , E extends ObserveDataEntity> DataEntityContext fromDataEntity(Class entityType) {
return INSTANCE.dataEntityContext.get(entityType);
}
private static Class> getClass(Object entity) {
if (entity.getClass().getName().contains("net.bytebuddy")) {
return entity.getClass().getInterfaces()[0];
}
if (entity.getClass().getName().contains("HibernateProxy")) {
return entity.getClass().getInterfaces()[0];
}
return entity.getClass();
}
private static , E extends ObserveReferentialEntity> void registerReferential(Class dtoType,
DtoToReferenceClassMap dtoToReferenceClassMapping,
DtoToEntityClassMap dtoToEntityClassMap,
DtoReferencesInitializerSupport referencesInitializer,
DtoFormsInitializerSupport formInitializer,
EntitiesBinderInitializerSupport initializer,
ImmutableTypedMap.Builder referentialDtoContextBuilder,
ImmutableTypedMap.Builder referentialReferenceContextBuilder,
ImmutableTypedMap.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,
ImmutableTypedMap.Builder dataDtoContextBuilder,
ImmutableTypedMap.Builder dataEntityContextBuilder) {
dataDtoContextBuilder.put(dtoType, new DataDtoEntityContext<>(dtoType, referencesInitializer, formDefinition, initializer));
Class entityType = dtoToEntityClassMap.forData(dtoType);
if (equalsDtoTypeAndEntityType(dtoType, entityType)) {
// 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,
ImmutableTypedMap.Builder dataDtoContextBuilder,
ImmutableTypedMap.Builder dataReferenceContextBuilder,
ImmutableTypedMap.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 (equalsDtoTypeAndEntityType(dtoType, entityType)) {
// 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));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy