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

com.kenshoo.pl.entity.HierarchyKeyPopulator Maven / Gradle / Ivy

Go to download

A Java persistence layer based on JOOQ for high performance and business flow support.

There is a newer version: 0.1.121-jooq-3.16.3
Show newest version
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> parents) {

        if (parents.isEmpty()) {
            return;
        }

        hierarchy.childrenTypes(entityType(parents))
                .forEach(populateKeysToChildrenOfSpecificTypeConsumer(parents));
    }

    @SuppressWarnings("unchecked")
    private Consumer populateKeysToChildrenOfSpecificTypeConsumer(Collection> parents) {
        return childType -> populateKeysToChildrenOfSpecificType(parents, childType);
    }

    private >
    void populateKeysToChildrenOfSpecificType(
            Collection> 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> 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> 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);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy