com.kenshoo.pl.entity.HierarchyKeyPopulator 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.internal.EntityDbUtil;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Predicate;
import static org.jooq.lambda.Seq.seq;
public class HierarchyKeyPopulator> {
private final CommandToValuesStrategy valueExtractor;
private final Predicate> keyFilter;
private final Hierarchy hierarchy;
private HierarchyKeyPopulator(Predicate> keyFilter, CommandToValuesStrategy identityValueGetter, Hierarchy hierarchy) {
this.valueExtractor = identityValueGetter;
this.keyFilter = keyFilter;
this.hierarchy = hierarchy;
}
public static > CommandToValuesStrategy fromContext(ChangeContext ctx) {
return (fields, cmd) -> EntityDbUtil.getFieldValues(fields, ctx.getEntity(cmd));
}
public static > CommandToValuesStrategy fromCommands() {
return (fields, cmd) -> EntityDbUtil.getFieldValues(fields, cmd);
}
public void populateKeysToChildren(Collection extends ChangeEntityCommand> parents) {
if (parents.isEmpty()) {
return;
}
hierarchy.childrenTypes(entityType(parents))
.forEach(populateKeysToChildrenOfSpecificTypeConsumer(parents));
}
@SuppressWarnings("unchecked")
private Consumer populateKeysToChildrenOfSpecificTypeConsumer(Collection extends ChangeEntityCommand> parents) {
return childType -> populateKeysToChildrenOfSpecificType(parents, childType);
}
private >
void populateKeysToChildrenOfSpecificType(
Collection extends ChangeEntityCommand> parents,
CHILD childType) {
final EntityType.ForeignKey childToParentFields = childType.getKeyTo(entityType(parents)).filterByTo(keyFilter);
if (childToParentFields.notEmpty()) {
seq(parents).filter(hasAnyChildOf(childType)).forEach(parent -> {
final UniqueKeyValue identityValues = parentValues(childToParentFields, valueExtractor, parent);
parent.getChildren(childType).forEach(child -> child.setKeysToParent(identityValues.concat(child.getKeysToParent())));
});
}
}
private PARENT entityType(Collection extends EntityChange> parents) {
return first(parents).getEntityType();
}
private >
UniqueKeyValue parentValues(EntityType.ForeignKey childToParentKeys, CommandToValuesStrategy commandToValuesStrategy, EntityChange parent) {
Object[] parentValues = commandToValuesStrategy.getValues(childToParentKeys.to(), parent);
if (childToParentKeys.size() != parentValues.length) {
throw new IllegalStateException("Found " + parentValues.length + " values out of " + childToParentKeys.size() + " fields for foreign keys. Keys: " + childToParentKeys);
}
return new UniqueKeyValue<>(new UniqueKey<>(array(childToParentKeys.from())), parentValues);
}
private >
Predicate> hasAnyChildOf(CHILD childType) {
return p -> p.getChildren(childType).findAny().isPresent();
}
private T first(Iterable items) {
return items.iterator().next();
}
private > EntityField[] array(Collection extends EntityField> childFields) {
return childFields.toArray(new EntityField[childFields.size()]);
}
public static >
Predicate> autoInc() {
return parentField -> parentField.getDbAdapter().isIdentityField();
}
static >
Predicate> notAutoInc() {
return parentField -> !parentField.getDbAdapter().isIdentityField();
}
public static >
Predicate> anyField() {
return parentField -> true;
}
public static class Builder> {
private CommandToValuesStrategy valueExtractor;
private Predicate> keyFilter;
private Hierarchy hierarchy;
public Builder with(Hierarchy hierarchy) {
this.hierarchy = hierarchy;
return this;
}
public Builder gettingValues(CommandToValuesStrategy valueExtractor) {
this.valueExtractor = valueExtractor;
return this;
}
public Builder whereParentFieldsAre(Predicate> keyFilter) {
this.keyFilter = keyFilter;
return this;
}
public HierarchyKeyPopulator build() {
return new HierarchyKeyPopulator(keyFilter, valueExtractor, hierarchy);
}
}
}