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

colesico.framework.dslvalidator.builder.FlowControlBuilder Maven / Gradle / Ivy

/*
 * Copyright © 2014-2020 Vladlen V. Larionov and others as noted.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package colesico.framework.dslvalidator.builder;

import colesico.framework.dslvalidator.Command;
import colesico.framework.dslvalidator.DSLValidator;
import colesico.framework.dslvalidator.Sequence;
import colesico.framework.dslvalidator.ValidationContext;
import colesico.framework.dslvalidator.commands.*;
import colesico.framework.dslvalidator.t9n.ValidatorMessages;
import colesico.framework.translation.Translatable;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;

abstract public class FlowControlBuilder {

    public static final String FIELD_METHOD = "field";
    public static final String OPTIONAL_GROUP_METHOD = "optionalGroup";
    public static final String MANDATORY_GROUP_METHOD = "mandatoryGroup";

    protected final ValidatorMessages vrMessages;

    public FlowControlBuilder(ValidatorMessages vrMessages) {
        this.vrMessages = vrMessages;
    }

    protected final  DSLValidator validator(Sequence commands) {
        return new DSLValidator<>(commands, null);
    }

    /**
     * Defines validation algorithm based on {@link GroupSequence }
     */
    protected final  DSLValidator validator(final Command... commands) {
        MandatoryGroup sequence = new MandatoryGroup<>(vrMessages);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return new DSLValidator<>(sequence, null);
    }

    protected final  DSLValidator validator(final String subject, Sequence commands) {
        return new DSLValidator<>(commands, subject);
    }

    /**
     * Defines validation algorithm based on {@link ChainSequence }
     */
    protected final  DSLValidator validator(final String subject, final Command... commands) {
        MandatoryChain sequence = new MandatoryChain<>(vrMessages);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return new DSLValidator<>(sequence, subject);
    }

    /**
     * Executes group commands  within the local context if context value is not null,
     * otherwise throws validation error.
     * In case of local validation errors occur, command execution is NOT interrupted.
     *
     * @see GroupSequence
     */
    protected final  Command group(final Command... commands) {
        GroupSequence sequence = new GroupSequence<>();
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    /**
     * Executes group commands if context value is not null.
     * In case of local validation errors occur, command execution is NOT interrupted.
     */
    protected final  Command optionalGroup(final Command... commands) {
        ConditionalGroup sequence = new ConditionalGroup<>(c -> c.getValue() != null);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    protected final  Command conditionalGroup(Predicate condition, final Command... commands) {
        ConditionalGroup sequence = new ConditionalGroup<>(condition);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    protected final  Command mandatoryGroup(final Command... commands) {
        MandatoryGroup sequence = new MandatoryGroup<>(vrMessages);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    /**
     * Executes commands within the local context.
     * In case of local validation errors occur, command execution is interrupted.
     *
     * @param commands
     * @return
     */
    protected final  Command chain(final Command... commands) {
        ChainSequence sequence = new ChainSequence<>();
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    /**
     * @see ConditionalChain
     */
    protected final  Command optionalChain(final Command... commands) {
        ConditionalChain sequence = new ConditionalChain<>(c -> c.getValue() != null);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    protected final  Command conditionalChain(Predicate condition, final Command... commands) {
        ConditionalChain sequence = new ConditionalChain<>(condition);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }


    /**
     * @see MandatoryChain
     */
    protected final  Command mandatoryChain(final Command... commands) {
        MandatoryChain sequence = new MandatoryChain<>(vrMessages);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    /**
     * Executes commands within the new nested context with specified subject.
     * In case of local validation errors occur, commands execution is interrupted.
     *
     * @see SubjectChain
     */
    protected final  Command subject(final String subject, final Command... commands) {
        SubjectChain sequence = new SubjectChain<>(subject);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    /**
     * Creates new nested context with the subject and the value, extracted from the value of the local context.
     * Execute commands within that nested context.
     * In case of validation errors occur in the nested context, command execution is interrupted.
     *
     * @see FieldChain
     */
    protected final  Command field(final String subject, final Function extractor, final Command... commands) {
        FieldChain sequence = new FieldChain<>(subject, extractor);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    /**
     * Nested Chain
     *
     * @see NestedChain
     */
    protected final  Command nested(final String subject, final Function, Optional> extractor, final Command... commands) {
        NestedChain sequence = new NestedChain<>(subject, extractor);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    /**
     * In case of local  validation errors occur, command execution is interrupted.
     *
     * @return
     */
    protected final , E> Command item(final String subject, final int index, final Command... commands) {
        ItemChain sequence = new ItemChain<>(subject, index);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    /**
     * Map emtry
     */
    protected final , K, E> Command entry(final String subject, final K key, final Command... commands) {
        EntryChain sequence = new EntryChain<>(subject, key);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    /**
     * Iterates the elements of value from local context.
     * In case of  local validation errors occur, command execution is interrupted.
     *
     * @see IterableChain
     */
    protected final , I> Command forEach(final Command... commands) {
        IterableChain sequence = new IterableChain<>();
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    protected final  Command hookError(String errorCode, Translatable errorMsg, final Command... commands) {
        HookErrorChain sequence = new HookErrorChain<>(errorCode, errorMsg);
        for (Command cmd : commands) {
            sequence.addCommand(cmd);
        }
        return sequence;
    }

    /**
     * Helper to create generic commands array
     */
    protected  Command[] commands(Command... cmd) {
        return cmd;
    }
}