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

com.softicar.platform.common.container.schedule.coverage.ScheduleCoverageComputer Maven / Gradle / Ivy

Go to download

The SoftiCAR Platform is a lightweight, Java-based library to create interactive business web applications.

There is a newer version: 50.0.0
Show newest version
package com.softicar.platform.common.container.schedule.coverage;

import com.softicar.platform.common.container.matrix.IImmutableMatrix;
import com.softicar.platform.common.math.arithmetic.IArithmetic;
import java.util.Set;
import java.util.TreeSet;

/**
 * Computes the coverage of a work schedule over a to-do schedule.
 *
 * @author Oliver Richers
 */
public class ScheduleCoverageComputer> {

	protected final IImmutableMatrix todoSchedule;
	protected final IImmutableMatrix workSchedule;
	protected final IArithmetic arithmetic;
	protected final ScheduleCoverage todoCoverage;
	protected final ScheduleCoverage workCoverage;

	public ScheduleCoverageComputer(IImmutableMatrix todoSchedule, IImmutableMatrix workSchedule,
			IArithmetic arithmetic) {

		this.todoSchedule = todoSchedule;
		this.workSchedule = workSchedule;
		this.arithmetic = arithmetic;
		this.todoCoverage = new ScheduleCoverage<>(arithmetic);
		this.workCoverage = new ScheduleCoverage<>(arithmetic);
	}

	public Set getAllRows() {

		Set rows = new TreeSet<>();
		rows.addAll(todoSchedule.getRows());
		rows.addAll(workSchedule.getRows());
		return rows;
	}

	public ScheduleCoverageComputer compute() {

		for (Row row: getAllRows()) {
			new RowCoverageComputer(row).compute();
		}

		return this;
	}

	public void computeRow(Row row) {

		this.todoCoverage.resetRow(row);
		this.workCoverage.resetRow(row);
		new RowCoverageComputer(row).compute();
	}

	public ScheduleCoverage getTodoCoverage() {

		return todoCoverage;
	}

	public ScheduleCoverage getWorkCoverage() {

		return workCoverage;
	}

	private class RowCoverageComputer {

		private final ScheduleCellIterator todoIterator;
		private final ScheduleCellIterator workIterator;
		private Quantity backlog;

		public RowCoverageComputer(Row row) {

			this.todoIterator = new ScheduleCellIterator<>(todoSchedule, arithmetic, row);
			this.workIterator = new ScheduleCellIterator<>(workSchedule, arithmetic, row);
			this.backlog = arithmetic.getZero();
		}

		public void compute() {

			while (todoIterator.gatherQuantity() && workIterator.gatherQuantity()) {
				Quantity todoQuantity = todoIterator.getQuantity();
				Quantity workQuantity = workIterator.getQuantity();
				if (isNegative(todoQuantity)) {
					handleNegativeTodoQuantity();
				} else if (isNegative(workQuantity)) {
					handleNegativeWorkQuantity(workQuantity);
				} else if (isPositive(backlog)) {
					handleBacklog();
				} else {
					Quantity minimum = getMinimum(todoQuantity, workQuantity);
					todoIterator.transferToCoverage(todoCoverage, workIterator.getColumn(), minimum);
					workIterator.transferToCoverage(workCoverage, todoIterator.getColumn(), minimum);
				}
			}

			// gather remaining to-do and work quantities
			gatherRemainingQuantities(todoIterator, todoCoverage);
			gatherRemainingQuantities(workIterator, workCoverage);
		}

		private void handleNegativeTodoQuantity() {

			throw new IllegalArgumentException(
				String
					.format(
						"Got negative to-do quantity '%s' for row '%s' and column '%s'. Quantities of the to-do schedule may not be negative.",
						todoIterator.getQuantity(),
						todoIterator.getRow(),
						todoIterator.getColumn()));
		}

		private void handleNegativeWorkQuantity(Quantity workQuantity) {

			backlog = arithmetic.plus(backlog, arithmetic.negate(workQuantity));
			workIterator.transferToCoverage(workCoverage, workQuantity);
		}

		private void handleBacklog() {

			Quantity minimum = getMinimum(backlog, workIterator.getQuantity());
			backlog = arithmetic.minus(backlog, minimum);
			workIterator.transferToCoverage(workCoverage, minimum);
		}

		private void gatherRemainingQuantities(ScheduleCellIterator iterator, ScheduleCoverage coverage) {

			while (iterator.gatherQuantity()) {
				iterator.transferToCoverage(coverage, iterator.getQuantity());
			}
		}

		private boolean isPositive(Quantity quantity) {

			return arithmetic.isLess(arithmetic.getZero(), quantity);
		}

		private boolean isNegative(Quantity quantity) {

			return arithmetic.isLess(quantity, arithmetic.getZero());
		}

		private Quantity getMinimum(Quantity a, Quantity b) {

			return arithmetic.isLess(a, b)? a : b;
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy