com.kenshoo.pl.entity.FieldsToFetchBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of persistence-layer Show documentation
Show all versions of persistence-layer Show documentation
A Java persistence layer based on JOOQ for high performance and business flow support.
package com.kenshoo.pl.entity;
import com.kenshoo.pl.entity.spi.CurrentStateConsumer;
import com.kenshoo.pl.entity.spi.PostFetchCommandEnricher;
import org.jooq.lambda.Seq;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.kenshoo.pl.entity.ChangeOperation.*;
import static com.kenshoo.pl.entity.FieldFetchRequest.newRequest;
import static com.kenshoo.pl.entity.spi.CurrentStateConsumer.supporting;
import static java.util.stream.Collectors.toList;
import static org.jooq.lambda.Seq.seq;
import static org.jooq.lambda.function.Functions.not;
public class FieldsToFetchBuilder> {
public Collection build(Collection extends ChangeEntityCommand> commands, ChangeFlowConfig flowConfig) {
return prepareFieldsToFetchRecursive(Hierarchy.build(flowConfig), commands, flowConfig)
.toList();
}
private > Seq prepareFieldsToFetchRecursive(
Hierarchy hierarchy,
Collection extends ChangeEntityCommand> commands,
ChangeFlowConfig flow) {
return Seq.concat(
getForOneLevel(hierarchy, only(commands, withOperator(UPDATE)), UPDATE, flow),
getForOneLevel(hierarchy, only(commands, withOperator(CREATE).or(withAllowMissingEntity())), CREATE, flow),
getForOneLevel(hierarchy, only(commands, withOperator(DELETE)), DELETE, flow),
seq(flow.childFlows()).flatMap(childFlow -> prepareChildFieldsToFetchRecursive(hierarchy, commands, childFlow))
);
}
private , CHILD extends EntityType> Seq prepareChildFieldsToFetchRecursive(Hierarchy hierarchy, Collection extends ChangeEntityCommand> commands, ChangeFlowConfig childFlow) {
return prepareFieldsToFetchRecursive(hierarchy, commands.stream().flatMap(parent -> parent.getChildren(childFlow.getEntityType())).collect(toList()), childFlow);
}
private > Seq getForOneLevel(
Hierarchy hierarchy,
Collection extends ChangeEntityCommand> commands,
ChangeOperation operation,
ChangeFlowConfig flow) {
if (commands.isEmpty()) {
return Seq.empty();
}
final EntityType currentLevel = flow.getEntityType();
final Stream> currentStateConsumers =
Stream.concat(flow.currentStateConsumers(), consumerOf(commands))
.filter(supporting(operation));
final Seq> fields = Seq.concat(
fieldsConsumedBy(commands, operation, flow, currentStateConsumers),
fieldsRelatedByChildrenOf(commands, operation),
fieldsOfIdentifiersOf(commands, operation));
return fields.flatMap(field -> {
if (isSameLevel(flow, field)) {
return Seq.of(newRequest().field(field).queryOn(currentLevel).askedBy(currentLevel).build());
} else if (hierarchy.contains(field)) {
return Seq.of(newRequest().field(field).queryOn(field.getEntityType()).askedBy(currentLevel).build());
} else {
return Seq.of(newRequest().field(field).queryOn(hierarchy.root()).askedBy(currentLevel).build());
}
});
}
private > Stream extends EntityField, ?>> fieldsConsumedBy(Collection extends ChangeEntityCommand> commands, ChangeOperation operation, ChangeFlowConfig flow, Stream> currentStateConsumers) {
Stream> fieldsByCommands = commands.stream().flatMap(ChangeEntityCommand::getChangedFields);
Stream> fieldsToEnrich = flow.getPostFetchCommandEnrichers().stream().filter(enricher -> enricher.shouldRun(commands)).flatMap(PostFetchCommandEnricher::fieldsToEnrich);
Set> fieldsToUpdate = Stream.concat(fieldsByCommands, fieldsToEnrich).collect(Collectors.toSet());
return currentStateConsumers.flatMap(
consumer -> filterFieldsByOperator(flow, operation, consumer.requiredFields(fieldsToUpdate, operation), consumer)
);
}
private > Stream> fieldsOfIdentifiersOf(Collection extends ChangeEntityCommand> commands, ChangeOperation operation) {
if(!commands.isEmpty() && SupportedChangeOperation.UPDATE_AND_DELETE.supports(operation)) {
ChangeEntityCommand cmd = commands.stream().findFirst().get();
return uniqueFields(cmd);
} else {
return Stream.empty();
}
}
private > Stream> fieldsRelatedByChildrenOf(Collection extends ChangeEntityCommand> commands, ChangeOperation operation) {
if(SupportedChangeOperation.UPDATE_AND_DELETE.supports(operation) && hasAnyChildCommand(commands)) {
ChangeEntityCommand cmd = commands.stream().findFirst().get();
return primaryKeyFields(cmd);
} else {
return Stream.empty();
}
}
private > Stream> uniqueFields(ChangeEntityCommand cmd) {
return Arrays.stream(cmd.getIdentifier().getUniqueKey().getFields());
}
private > Stream> primaryKeyFields(ChangeEntityCommand cmd) {
EntityType entityType = cmd.getEntityType();
return entityType.findFields(entityType.getPrimaryTable().getPrimaryKey().getFields()).stream();
}
private > boolean hasAnyChildCommand(Collection extends ChangeEntityCommand> commands) {
return commands.stream().flatMap(ChangeEntityCommand::getChildren).findAny().isPresent();
}
private > boolean isSameLevel(ChangeFlowConfig flow, EntityField, ?> field) {
return flow.getEntityType().equals(field.getEntityType());
}
private List extends T> only(Iterable extends T> items, Predicate super T> predicate) {
return seq(items).filter(predicate).toList();
}
private Predicate> withOperator(ChangeOperation op) {
return cmd -> op == cmd.getChangeOperation();
}
private Predicate super EntityChange>> withAllowMissingEntity() {
return EntityChange::allowMissingEntity;
}
private > Stream> consumerOf(Collection extends ChangeEntityCommand> commands) {
return commands.stream()
.flatMap(ChangeEntityCommand::getCurrentStateConsumers);
}
private , EF extends EntityField, ?>> Stream filterFieldsByOperator(ChangeFlowConfig flowConfig, ChangeOperation changeOperation, Stream fieldsToFetch, CurrentStateConsumer consumer) {
if(changeOperation == CREATE) {
return fieldsToFetch.filter(not(ofEntity(flowConfig.getEntityType())));
} else {
return fieldsToFetch;
}
}
private , EF extends EntityField, ?>> Predicate ofEntity(EntityType entityType) {
return entityField -> entityField.getEntityType().equals(entityType);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy