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

org.aktivecortex.core.notification.ProgressEvaluatorBuilder Maven / Gradle / Ivy

/*
 * Copyright (C) 2012-2013. Aktive Cortex
 *
 * 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 org.aktivecortex.core.notification;

import org.aktivecortex.api.command.Command;
import org.aktivecortex.api.notification.ProgressEvaluator;
import org.aktivecortex.dbc.assertion.Contract;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static com.google.common.collect.Sets.intersection;
import static com.google.common.collect.Sets.newHashSet;
import static java.math.BigDecimal.ROUND_HALF_UP;

/**
 * A builder for creating {@link ProgressEvaluator} instance.
 * Example: 
   {@code
 *
 *   private static final ProgressEvaluator BANK_TRANSFER_EVAL = ProgressEvaluatorBuilder.newBuilder()
 *          .addStep("BankTransferRequest", "Transfer order accepted", 0.25)
 *          .composedBy(MoneyTransferCommand.class, 1)
 *          .addStep("WithdrawalOrder", "Withdrawal order accepted", 0.25)
 *          .composedBy(DisposeWithdrawalCommand.class, 1)
 *          .addStep("DepositOrder", "Deposit order accepted", 0.25)
 *          .composedBy(DisposeDepositCommand.class, 1)
 *          .addStep("Confirmation", "Orders confirmed", 0.25)
 *          .composedBy(ConfirmWithdrawalCommand.class, 1)
 *          .composedBy(ConfirmDepositCommand.class, 1)
 *          .build();}
*

Builder instances can be reused - it is safe to call {@link #build} * multiple times to build multiple instances in series. * * @author Domenico Maria Giffone. * @since 1.2 */ public class ProgressEvaluatorBuilder { private ProgressEvaluatorBuilder() { } public static interface StepDefinition { FirstCommandDefinition addStep(String stepName, double stepWeight); FirstCommandDefinition addStep(String stepName, String stepDescription, double stepWeight); } public static interface FirstCommandDefinition { NextCommandDefinition composedBy(Class expectedType, int expectedAmount); } public static interface NextCommandDefinition extends FirstCommandDefinition, StepDefinition { ProgressEvaluator build(); } public static StepDefinition newBuilder() { return new StepBuilder(); } private static final class StepBuilder implements StepDefinition, FirstCommandDefinition, NextCommandDefinition { private static final double TOTAL_WEIGHT_INVARIANT = 1.00D; private List steps = new ArrayList(); private BigDecimal stepsWeight = BigDecimal.ZERO; private Step currentStep; @Override public ProgressEvaluator build() { validate(); return new DefaultProgressEvaluator(steps); } private void validate() { Contract.ENSURE.isTrue(TOTAL_WEIGHT_INVARIANT == stepsWeight.doubleValue(), "The sum of steps weight must be equal to 1", "Current weight is [{}]", stepsWeight.toPlainString()); Set intersections = newHashSet(); for (int i = 0; i < steps.size(); i++) { Set reference = steps.get(i).getCommands(); for (int k = 0; k < steps.size(); k++) { if (k != i) { intersections.addAll(intersection(reference, steps.get(k).getCommands())); } } } Contract.ENSURE.isTrue(intersections.size() == 0, "The same command can not belong to more than one step", "Repeated commands found: [{}]", intersections); } @Override public NextCommandDefinition composedBy(Class expectedType, int expectedAmount) { currentStep.addCommand(expectedType, expectedAmount); return this; } @Override public FirstCommandDefinition addStep(String stepName, double stepWeight) { return addStep(stepName, null, stepWeight); } @Override public FirstCommandDefinition addStep(String stepName, String stepDescription, double stepWeight) { currentStep = new Step(stepName, stepDescription, stepWeight); steps.add(currentStep); stepsWeight = stepsWeight.add(BigDecimal.valueOf(stepWeight)).setScale(2, ROUND_HALF_UP); return this; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy