Support backwards scheduling
The implementation is the same as for forward scheduling but some parametrizations. Lots of refactorings to make it possible. FEA: ItEr64OTS03PlanificacionHaciaAtras
This commit is contained in:
parent
1b1d11aff7
commit
2f498a9070
6 changed files with 483 additions and 216 deletions
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2010 Igalia S.L.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.zkoss.ganttz.data;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.zkoss.ganttz.data.constraint.ConstraintOnComparableValues.biggerOrEqualThan;
|
||||
import static org.zkoss.ganttz.data.constraint.ConstraintOnComparableValues.lessOrEqualThan;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.zkoss.ganttz.data.DependencyType.Point;
|
||||
import org.zkoss.ganttz.data.constraint.Constraint;
|
||||
|
||||
/**
|
||||
* Calculates the {@link GanttDate} constraints for a given {@link IDependency}
|
||||
*
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public abstract class ConstraintCalculator<T> {
|
||||
|
||||
private final boolean reversed;
|
||||
|
||||
protected ConstraintCalculator(boolean reversed) {
|
||||
this.reversed = reversed;
|
||||
}
|
||||
|
||||
public List<Constraint<GanttDate>> getConstraints(
|
||||
IDependency<T> dependency, Point pointToBeModified) {
|
||||
T effectiveSource = getEffectiveSource(dependency);
|
||||
DependencyType effectiveType = getEffectiveType(dependency.getType());
|
||||
if (!effectiveType.getDestination().equals(pointToBeModified)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return singletonList(constraintGiven(getReferenceDate(effectiveSource,
|
||||
effectiveType)));
|
||||
}
|
||||
|
||||
private Constraint<GanttDate> constraintGiven(GanttDate referenceDate) {
|
||||
if (!reversed) {
|
||||
return biggerOrEqualThan(referenceDate);
|
||||
} else {
|
||||
return lessOrEqualThan(referenceDate);
|
||||
}
|
||||
}
|
||||
|
||||
private GanttDate getReferenceDate(T effectiveSource,
|
||||
DependencyType effectiveType) {
|
||||
if (effectiveType.getSource().equals(Point.START)) {
|
||||
return getStartDate(effectiveSource);
|
||||
} else {
|
||||
return getEndDate(effectiveSource);
|
||||
}
|
||||
}
|
||||
|
||||
private T getEffectiveSource(IDependency<T> dependency) {
|
||||
return !reversed ? dependency.getSource() : dependency.getDestination();
|
||||
}
|
||||
|
||||
private DependencyType getEffectiveType(DependencyType type) {
|
||||
return !reversed ? type : type.inverse();
|
||||
}
|
||||
|
||||
protected abstract GanttDate getStartDate(T vertex);
|
||||
|
||||
protected abstract GanttDate getEndDate(T vertex);
|
||||
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ import java.util.List;
|
|||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.zkoss.ganttz.data.DependencyType.Point;
|
||||
import org.zkoss.ganttz.data.constraint.Constraint;
|
||||
import org.zkoss.ganttz.data.constraint.Constraint.IConstraintViolationListener;
|
||||
import org.zkoss.ganttz.util.ConstraintViolationNotificator;
|
||||
|
|
@ -37,41 +38,13 @@ import org.zkoss.ganttz.util.ConstraintViolationNotificator;
|
|||
*/
|
||||
public class Dependency implements IDependency<Task> {
|
||||
|
||||
private enum Calculation {
|
||||
START {
|
||||
@Override
|
||||
public List<Constraint<GanttDate>> toConstraints(Task source,
|
||||
DependencyType type) {
|
||||
return type.getStartConstraints(source);
|
||||
}
|
||||
},
|
||||
END {
|
||||
@Override
|
||||
public List<Constraint<GanttDate>> toConstraints(Task source,
|
||||
DependencyType type) {
|
||||
return type.getEndConstraints(source);
|
||||
}
|
||||
};
|
||||
|
||||
abstract List<Constraint<GanttDate>> toConstraints(Task source,
|
||||
DependencyType type);
|
||||
}
|
||||
|
||||
public static List<Constraint<GanttDate>> getStartConstraints(
|
||||
Collection<Dependency> dependencies) {
|
||||
return getConstraintsFor(dependencies, Calculation.START);
|
||||
}
|
||||
|
||||
public static List<Constraint<GanttDate>> getEndConstraints(
|
||||
Collection<Dependency> incoming) {
|
||||
return getConstraintsFor(incoming, Calculation.END);
|
||||
}
|
||||
|
||||
private static List<Constraint<GanttDate>> getConstraintsFor(
|
||||
Collection<Dependency> dependencies, Calculation calculation) {
|
||||
public static List<Constraint<GanttDate>> getConstraintsFor(
|
||||
ConstraintCalculator<Task> calculator,
|
||||
Collection<Dependency> dependencies, Point pointBeingModified) {
|
||||
List<Constraint<GanttDate>> result = new ArrayList<Constraint<GanttDate>>();
|
||||
for (Dependency dependency : dependencies) {
|
||||
result.addAll(dependency.toConstraints(calculation));
|
||||
for (Dependency each : dependencies) {
|
||||
result.addAll(each.withViolationNotification(calculator
|
||||
.getConstraints(each, pointBeingModified)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -109,9 +82,9 @@ public class Dependency implements IDependency<Task> {
|
|||
this(source, destination, type, true);
|
||||
}
|
||||
|
||||
private List<Constraint<GanttDate>> toConstraints(Calculation calculation) {
|
||||
return violationsNotificator.withListener(calculation.toConstraints(
|
||||
source, type));
|
||||
private List<Constraint<GanttDate>> withViolationNotification(
|
||||
List<Constraint<GanttDate>> original) {
|
||||
return violationsNotificator.withListener(original);
|
||||
}
|
||||
|
||||
public void addConstraintViolationListener(
|
||||
|
|
|
|||
|
|
@ -20,12 +20,8 @@
|
|||
|
||||
package org.zkoss.ganttz.data;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.zkoss.ganttz.data.constraint.ConstraintOnComparableValues.biggerOrEqualThan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.zkoss.ganttz.data.GanttDiagramGraph.IAdapter;
|
||||
import org.zkoss.ganttz.data.constraint.Constraint;
|
||||
|
||||
|
|
@ -36,15 +32,45 @@ import org.zkoss.ganttz.data.constraint.Constraint;
|
|||
*/
|
||||
public enum DependencyType {
|
||||
|
||||
VOID(Point.VOID, Point.VOID),
|
||||
VOID(Point.VOID, Point.VOID) {
|
||||
|
||||
END_START(Point.END, Point.START),
|
||||
@Override
|
||||
public DependencyType inverse() {
|
||||
return VOID;
|
||||
}
|
||||
},
|
||||
|
||||
START_END(Point.START, Point.END),
|
||||
END_START(Point.END, Point.START) {
|
||||
|
||||
START_START(Point.START, Point.START),
|
||||
@Override
|
||||
public DependencyType inverse() {
|
||||
return START_END;
|
||||
}
|
||||
},
|
||||
|
||||
END_END(Point.END, Point.END);
|
||||
START_END(Point.START, Point.END) {
|
||||
|
||||
@Override
|
||||
public DependencyType inverse() {
|
||||
return END_START;
|
||||
}
|
||||
},
|
||||
|
||||
START_START(Point.START, Point.START) {
|
||||
|
||||
@Override
|
||||
public DependencyType inverse() {
|
||||
return START_START;
|
||||
}
|
||||
},
|
||||
|
||||
END_END(Point.END, Point.END) {
|
||||
|
||||
@Override
|
||||
public DependencyType inverse() {
|
||||
return END_END;
|
||||
}
|
||||
};
|
||||
|
||||
public enum Point {
|
||||
VOID, START, END;
|
||||
|
|
@ -69,52 +95,17 @@ public enum DependencyType {
|
|||
return biggerOrEqualThan(adapter.getStartDate(source));
|
||||
}
|
||||
|
||||
public final List<Constraint<GanttDate>> getStartConstraints(Task source) {
|
||||
return getStartConstraints(source, GanttDiagramGraph.taskAdapter());
|
||||
}
|
||||
|
||||
public final <V> List<Constraint<GanttDate>> getStartConstraints(V source,
|
||||
IAdapter<V, ?> adapter) {
|
||||
if (getDestination() != Point.START) {
|
||||
return emptyList();
|
||||
}
|
||||
return constraintsFromReferenceDate(getReferenceDate(source, adapter));
|
||||
}
|
||||
|
||||
public final List<Constraint<GanttDate>> getEndConstraints(Task source) {
|
||||
return getEndConstraints(source, GanttDiagramGraph.taskAdapter());
|
||||
}
|
||||
|
||||
public final <V> List<Constraint<GanttDate>> getEndConstraints(V source,
|
||||
IAdapter<V, ?> adapter) {
|
||||
if (getDestination() != Point.END) {
|
||||
return emptyList();
|
||||
}
|
||||
return constraintsFromReferenceDate(getReferenceDate(source, adapter));
|
||||
}
|
||||
|
||||
private <V> GanttDate getReferenceDate(V source, IAdapter<V, ?> adapter) {
|
||||
if (getSource() == Point.START) {
|
||||
return adapter.getStartDate(source);
|
||||
} else {
|
||||
return adapter.getEndDateFor(source);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Constraint<GanttDate>> constraintsFromReferenceDate(
|
||||
GanttDate referenceDate) {
|
||||
return singletonList(biggerOrEqualThan(referenceDate));
|
||||
}
|
||||
|
||||
public Point[] getSourceAndDestination() {
|
||||
return new Point[] { getSource(), getDestination() };
|
||||
}
|
||||
|
||||
private final Point getSource() {
|
||||
public Point getSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
private final Point getDestination() {
|
||||
public Point getDestination() {
|
||||
return this.destination;
|
||||
}
|
||||
|
||||
public abstract DependencyType inverse();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
package org.zkoss.ganttz.data;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
|
@ -99,13 +101,9 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
|
|||
|
||||
GanttDate getSmallestBeginDateFromChildrenFor(V container);
|
||||
|
||||
List<Constraint<GanttDate>> getCurrentLenghtConstraintFor(V task);
|
||||
|
||||
List<Constraint<GanttDate>> getEndConstraintsGivenIncoming(
|
||||
Set<D> incoming);
|
||||
|
||||
List<Constraint<GanttDate>> getStartConstraintsGiven(
|
||||
Set<D> withDependencies);
|
||||
public List<Constraint<GanttDate>> getConstraints(
|
||||
ConstraintCalculator<V> calculator, Set<D> withDependencies,
|
||||
Point point);
|
||||
|
||||
List<Constraint<GanttDate>> getStartConstraintsFor(V task);
|
||||
|
||||
|
|
@ -181,17 +179,6 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
|
|||
return task.getEndDate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Constraint<GanttDate>> getCurrentLenghtConstraintFor(
|
||||
Task task) {
|
||||
return task.getCurrentLengthConstraint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Constraint<GanttDate>> getEndConstraintsGivenIncoming(
|
||||
Set<Dependency> incoming) {
|
||||
return Dependency.getEndConstraints(incoming);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEndDateFor(Task task, GanttDate newEnd) {
|
||||
|
|
@ -209,9 +196,11 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Constraint<GanttDate>> getStartConstraintsGiven(
|
||||
Set<Dependency> withDependencies) {
|
||||
return Dependency.getStartConstraints(withDependencies);
|
||||
public List<Constraint<GanttDate>> getConstraints(
|
||||
ConstraintCalculator<Task> calculator,
|
||||
Set<Dependency> withDependencies, Point pointBeingModified) {
|
||||
return Dependency.getConstraintsFor(calculator, withDependencies,
|
||||
pointBeingModified);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1008,15 +997,27 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
|
|||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean taskChangesPosition() {
|
||||
ChangeTracker tracker = trackTaskChanges();
|
||||
Constraint.initialValue(noRestrictions())
|
||||
.withConstraints(new BackwardsForces(), new ForwardForces())
|
||||
.withConstraints(getConstraintsToApply())
|
||||
.apply();
|
||||
return tracker.taskHasChanged();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Constraint<PositionRestrictions>> getConstraintsToApply() {
|
||||
List<Constraint<PositionRestrictions>> result = new ArrayList<Constraint<PositionRestrictions>>();
|
||||
if (!scheduleBackwards) {
|
||||
result.addAll(asList(new WeakBackwardsForces(),
|
||||
new DominatingForwardForces()));
|
||||
} else {
|
||||
result.addAll(asList(new WeakForwardForces(),
|
||||
new DominatingBackwardForces()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
abstract class PositionRestrictions {
|
||||
|
||||
|
|
@ -1188,123 +1189,361 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
|
|||
PositionRestrictions restrictions);
|
||||
}
|
||||
|
||||
class ForwardForces extends Forces {
|
||||
abstract class Dominating extends Forces {
|
||||
|
||||
private final Point primary;
|
||||
private final Point secondary;
|
||||
|
||||
public Dominating(Point primary, Point secondary) {
|
||||
Validate.isTrue(isSupportedPoint(primary));
|
||||
Validate.isTrue(isSupportedPoint(secondary));
|
||||
Validate.isTrue(!primary.equals(secondary));
|
||||
|
||||
this.primary = primary;
|
||||
this.secondary = secondary;
|
||||
}
|
||||
|
||||
private boolean isSupportedPoint(Point point) {
|
||||
EnumSet<Point> validPoints = EnumSet.of(Point.START, Point.END);
|
||||
return validPoints.contains(point);
|
||||
}
|
||||
|
||||
private Point getPrimaryPoint() {
|
||||
return primary;
|
||||
}
|
||||
|
||||
private Point getSecondaryPoint() {
|
||||
return secondary;
|
||||
}
|
||||
|
||||
@Override
|
||||
PositionRestrictions enforceUsingPreviousRestrictions(
|
||||
PositionRestrictions restrictions) {
|
||||
if (taskPoint.areAllPointsPotentiallyModified()) {
|
||||
return enforceStartAndEnd(restrictions);
|
||||
return enforceBoth(restrictions);
|
||||
} else if (taskPoint.somePointPotentiallyModified()) {
|
||||
return enforceEndDate(restrictions);
|
||||
return enforceSecondaryPoint(restrictions);
|
||||
}
|
||||
return restrictions;
|
||||
}
|
||||
|
||||
private PositionRestrictions enforceStartAndEnd(
|
||||
private PositionRestrictions enforceBoth(
|
||||
PositionRestrictions restrictions) {
|
||||
ChangeTracker changeTracker = trackTaskChanges();
|
||||
PositionRestrictions currentRestrictions = enforceStartDate(restrictions);
|
||||
PositionRestrictions currentRestrictions = enforcePrimaryPoint(restrictions);
|
||||
if (changeTracker.taskHasChanged() || parentRecalculation
|
||||
|| couldHaveBeenModifiedBeforehand) {
|
||||
return enforceEndDate(currentRestrictions);
|
||||
return enforceSecondaryPoint(currentRestrictions);
|
||||
}
|
||||
return currentRestrictions;
|
||||
}
|
||||
|
||||
private PositionRestrictions enforceStartDate(
|
||||
private PositionRestrictions enforcePrimaryPoint(
|
||||
PositionRestrictions originalRestrictions) {
|
||||
GanttDate newStart = calculateStartDate(originalRestrictions);
|
||||
return enforceRestrictionsForStartIfNeeded(newStart);
|
||||
}
|
||||
|
||||
private PositionRestrictions enforceRestrictionsForStartIfNeeded(
|
||||
GanttDate newStart) {
|
||||
GanttDate old = adapter.getStartDate(task);
|
||||
if (areNotEqual(old, newStart)) {
|
||||
adapter.setStartDateFor(task, newStart);
|
||||
}
|
||||
return biggerThan(newStart, adapter.getEndDateFor(task));
|
||||
GanttDate newDominatingPointDate = calculatePrimaryPointDate(originalRestrictions);
|
||||
return enforceRestrictionsFor(primary, newDominatingPointDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the new start date based on the present constraints.
|
||||
* If there are no constraints this method will return the existent
|
||||
* start date value.
|
||||
* Calculates the new date for the primary point based on the
|
||||
* present constraints. If there are no constraints this method will
|
||||
* return the existent commanding point date
|
||||
* @param originalRestrictions
|
||||
*/
|
||||
private GanttDate calculateStartDate(
|
||||
private GanttDate calculatePrimaryPointDate(
|
||||
PositionRestrictions originalRestrictions) {
|
||||
GanttDate newStart = Constraint
|
||||
.<GanttDate> initialValue(null)
|
||||
.withConstraints(originalRestrictions.getStartConstraints())
|
||||
.withConstraints(getStartConstraints())
|
||||
GanttDate newStart = Constraint
|
||||
.<GanttDate> initialValue(null)
|
||||
.withConstraints(
|
||||
getConstraintsFrom(originalRestrictions,
|
||||
getPrimaryPoint()))
|
||||
.withConstraints(getConstraintsFor(getPrimaryPoint()))
|
||||
.applyWithoutFinalCheck();
|
||||
if (newStart == null) {
|
||||
return adapter.getStartDate(task);
|
||||
return getTaskDateFor(getPrimaryPoint());
|
||||
}
|
||||
return newStart;
|
||||
}
|
||||
|
||||
@Override
|
||||
List<Constraint<GanttDate>> getStartConstraints() {
|
||||
List<Constraint<GanttDate>> result = new ArrayList<Constraint<GanttDate>>();
|
||||
if (dependenciesConstraintsHavePriority) {
|
||||
result.addAll(adapter.getStartConstraintsFor(task));
|
||||
result.addAll(getDependenciesCosntraintsForStart());
|
||||
|
||||
} else {
|
||||
result.addAll(getDependenciesCosntraintsForStart());
|
||||
result.addAll(adapter.getStartConstraintsFor(task));
|
||||
private List<Constraint<GanttDate>> getConstraintsFor(Point point) {
|
||||
Validate.isTrue(isSupportedPoint(point));
|
||||
switch (point) {
|
||||
case START:
|
||||
return getStartConstraints();
|
||||
case END:
|
||||
return getEndConstraints();
|
||||
default:
|
||||
throw new RuntimeException("shouldn't happen");
|
||||
}
|
||||
result.addAll(globalStartConstraints);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Constraint<GanttDate>> getDependenciesCosntraintsForStart() {
|
||||
final Set<D> withDependencies = graph.incomingEdgesOf(task);
|
||||
return adapter.getStartConstraintsGiven(withDependencies);
|
||||
}
|
||||
|
||||
private PositionRestrictions enforceEndDate(
|
||||
private PositionRestrictions enforceSecondaryPoint(
|
||||
PositionRestrictions restrictions) {
|
||||
GanttDate newEnd = Constraint
|
||||
.<GanttDate> initialValue(null)
|
||||
.withConstraints(restrictions.getEndConstraints())
|
||||
.withConstraints(getEndConstraints())
|
||||
.applyWithoutFinalCheck();
|
||||
if (newEnd == null) {
|
||||
GanttDate newSecondaryPointDate = calculateSecondaryPointDate(restrictions);
|
||||
if (newSecondaryPointDate == null) {
|
||||
return restrictions;
|
||||
}
|
||||
restrictions = enforceRestrictionsForEndIfNeeded(newEnd);
|
||||
if (taskPoint.onlyModifies(Point.END)) {
|
||||
// start constraints could be the ones "commanding" now
|
||||
GanttDate newStart = calculateStartDate(restrictions);
|
||||
if (newStart.compareTo(adapter.getStartDate(task)) > 0) {
|
||||
return enforceRestrictionsForStartIfNeeded(newStart);
|
||||
restrictions = enforceRestrictionsFor(getSecondaryPoint(),
|
||||
newSecondaryPointDate);
|
||||
if (taskPoint.onlyModifies(getSecondaryPoint())) {
|
||||
// primary point constraints could be the ones "commanding"
|
||||
// now
|
||||
GanttDate potentialPrimaryDate = calculatePrimaryPointDate(restrictions);
|
||||
if (!doSatisfyOrderCondition(potentialPrimaryDate,
|
||||
getTaskDateFor(getPrimaryPoint()))) {
|
||||
return enforceRestrictionsFor(getPrimaryPoint(),
|
||||
potentialPrimaryDate);
|
||||
}
|
||||
}
|
||||
return restrictions;
|
||||
}
|
||||
|
||||
@Override
|
||||
List<Constraint<GanttDate>> getEndConstraints() {
|
||||
Set<D> incoming = graph.incomingEdgesOf(task);
|
||||
return adapter.getEndConstraintsGivenIncoming(incoming);
|
||||
|
||||
private GanttDate calculateSecondaryPointDate(
|
||||
PositionRestrictions restrictions) {
|
||||
GanttDate newEnd = Constraint
|
||||
.<GanttDate> initialValue(null)
|
||||
.withConstraints(
|
||||
getConstraintsFrom(restrictions,
|
||||
getSecondaryPoint()))
|
||||
.withConstraints(getConstraintsFor(getSecondaryPoint()))
|
||||
.applyWithoutFinalCheck();
|
||||
return newEnd;
|
||||
}
|
||||
|
||||
private PositionRestrictions enforceRestrictionsForEndIfNeeded(
|
||||
GanttDate newEnd) {
|
||||
GanttDate previousEndDate = adapter.getEndDateFor(task);
|
||||
if (areNotEqual(previousEndDate, newEnd)) {
|
||||
adapter.setEndDateFor(task, newEnd);
|
||||
protected abstract boolean doSatisfyOrderCondition(
|
||||
GanttDate supposedlyBefore, GanttDate supposedlyAfter);
|
||||
|
||||
private PositionRestrictions enforceRestrictionsFor(Point point,
|
||||
GanttDate newDate) {
|
||||
GanttDate old = getTaskDateFor(point);
|
||||
if (areNotEqual(old, newDate)) {
|
||||
setTaskDateFor(point, newDate);
|
||||
}
|
||||
return biggerThan(adapter.getStartDate(task), newEnd);
|
||||
return createRestrictionsFor(getTaskDateFor(Point.START),
|
||||
getTaskDateFor(Point.END));
|
||||
}
|
||||
|
||||
private GanttDate getTaskDateFor(Point point) {
|
||||
Validate.isTrue(isSupportedPoint(point));
|
||||
switch (point) {
|
||||
case START:
|
||||
return adapter.getStartDate(task);
|
||||
case END:
|
||||
return adapter.getEndDateFor(task);
|
||||
default:
|
||||
throw new RuntimeException("shouldn't happen");
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract PositionRestrictions createRestrictionsFor(
|
||||
GanttDate start, GanttDate end);
|
||||
|
||||
private void setTaskDateFor(Point point, GanttDate date) {
|
||||
Validate.isTrue(isSupportedPoint(point));
|
||||
switch (point) {
|
||||
case START:
|
||||
adapter.setStartDateFor(task, date);
|
||||
break;
|
||||
case END:
|
||||
adapter.setEndDateFor(task, date);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Constraint<GanttDate>> getConstraintsFrom(
|
||||
PositionRestrictions restrictions, Point point) {
|
||||
Validate.isTrue(isSupportedPoint(point));
|
||||
switch (point) {
|
||||
case START:
|
||||
return restrictions.getStartConstraints();
|
||||
case END:
|
||||
return restrictions.getEndConstraints();
|
||||
default:
|
||||
throw new RuntimeException("shouldn't happen");
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Constraint<GanttDate>> getConstraintsForPrimaryPoint() {
|
||||
List<Constraint<GanttDate>> result = new ArrayList<Constraint<GanttDate>>();
|
||||
if (dependenciesConstraintsHavePriority) {
|
||||
result.addAll(getTaskConstraints(getPrimaryPoint()));
|
||||
result.addAll(getDependenciesConstraintsFor(getPrimaryPoint()));
|
||||
|
||||
} else {
|
||||
result.addAll(getDependenciesConstraintsFor(getPrimaryPoint()));
|
||||
result.addAll(getTaskConstraints(getPrimaryPoint()));
|
||||
}
|
||||
result.addAll(globalStartConstraints);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected List<Constraint<GanttDate>> getConstraintsForSecondaryPoint() {
|
||||
return getDependenciesConstraintsFor(getSecondaryPoint());
|
||||
}
|
||||
|
||||
private List<Constraint<GanttDate>> getDependenciesConstraintsFor(
|
||||
Point point) {
|
||||
final Set<D> withDependencies = getDependenciesAffectingThisTask();
|
||||
return adapter.getConstraints(getCalculator(),
|
||||
withDependencies, point);
|
||||
}
|
||||
|
||||
protected abstract Set<D> getDependenciesAffectingThisTask();
|
||||
|
||||
private List<Constraint<GanttDate>> getTaskConstraints(Point point) {
|
||||
Validate.isTrue(isSupportedPoint(point));
|
||||
switch (point) {
|
||||
case START:
|
||||
return adapter.getStartConstraintsFor(task);
|
||||
case END:
|
||||
return adapter.getEndConstraintsFor(task);
|
||||
default:
|
||||
throw new RuntimeException("shouldn't happen");
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract ConstraintCalculator<V> getCalculator();
|
||||
|
||||
protected ConstraintCalculator<V> createNormalCalculator() {
|
||||
return createCalculator(false);
|
||||
}
|
||||
|
||||
protected ConstraintCalculator<V> createBackwardsCalculator() {
|
||||
return createCalculator(true);
|
||||
}
|
||||
|
||||
private ConstraintCalculator<V> createCalculator(boolean inverse) {
|
||||
return new ConstraintCalculator<V>(inverse) {
|
||||
|
||||
@Override
|
||||
protected GanttDate getStartDate(V vertex) {
|
||||
return adapter.getStartDate(vertex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GanttDate getEndDate(V vertex) {
|
||||
return adapter.getEndDateFor(vertex);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BackwardsForces extends Forces {
|
||||
class DominatingForwardForces extends Dominating {
|
||||
|
||||
public DominatingForwardForces() {
|
||||
super(Point.START, Point.END);
|
||||
}
|
||||
|
||||
@Override
|
||||
List<Constraint<GanttDate>> getStartConstraints() {
|
||||
return getConstraintsForPrimaryPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
List<Constraint<GanttDate>> getEndConstraints() {
|
||||
return getConstraintsForSecondaryPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<D> getDependenciesAffectingThisTask() {
|
||||
return graph.incomingEdgesOf(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConstraintCalculator<V> getCalculator() {
|
||||
return createNormalCalculator();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PositionRestrictions createRestrictionsFor(
|
||||
GanttDate start, GanttDate end) {
|
||||
return biggerThan(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doSatisfyOrderCondition(
|
||||
GanttDate supposedlyBefore,
|
||||
GanttDate supposedlyAfter) {
|
||||
return supposedlyBefore.compareTo(supposedlyAfter) <= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DominatingBackwardForces extends Dominating {
|
||||
|
||||
public DominatingBackwardForces() {
|
||||
super(Point.END, Point.START);
|
||||
}
|
||||
|
||||
@Override
|
||||
List<Constraint<GanttDate>> getStartConstraints() {
|
||||
return getConstraintsForSecondaryPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
List<Constraint<GanttDate>> getEndConstraints() {
|
||||
return getConstraintsForPrimaryPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<D> getDependenciesAffectingThisTask() {
|
||||
return graph.outgoingEdgesOf(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConstraintCalculator<V> getCalculator() {
|
||||
return createBackwardsCalculator();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PositionRestrictions createRestrictionsFor(
|
||||
GanttDate start, GanttDate end) {
|
||||
return lessThan(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doSatisfyOrderCondition(
|
||||
GanttDate supposedlyBefore,
|
||||
GanttDate supposedlyAfter) {
|
||||
return supposedlyBefore.compareTo(supposedlyAfter) >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WeakForwardForces extends Forces {
|
||||
|
||||
@Override
|
||||
List<Constraint<GanttDate>> getStartConstraints() {
|
||||
return adapter.getStartConstraintsFor(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
List<Constraint<GanttDate>> getEndConstraints() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
PositionRestrictions enforceUsingPreviousRestrictions(
|
||||
PositionRestrictions restrictions) {
|
||||
GanttDate result = Constraint.<GanttDate> initialValue(null)
|
||||
.withConstraints(restrictions.getStartConstraints())
|
||||
.withConstraints(getStartConstraints())
|
||||
.applyWithoutFinalCheck();
|
||||
if (result != null) {
|
||||
return enforceRestrictions(result);
|
||||
}
|
||||
return restrictions;
|
||||
}
|
||||
|
||||
private PositionRestrictions enforceRestrictions(GanttDate result) {
|
||||
adapter.setStartDateFor(task, result);
|
||||
return biggerThan(result, adapter.getEndDateFor(task));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WeakBackwardsForces extends Forces {
|
||||
|
||||
@Override
|
||||
PositionRestrictions enforceUsingPreviousRestrictions(
|
||||
|
|
@ -1326,7 +1565,12 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements
|
|||
|
||||
@Override
|
||||
List<Constraint<GanttDate>> getEndConstraints() {
|
||||
return adapter.getEndConstraintsFor(task);
|
||||
List<Constraint<GanttDate>> result = new ArrayList<Constraint<GanttDate>>();
|
||||
result.addAll(adapter.getEndConstraintsFor(task));
|
||||
if (scheduleBackwards) {
|
||||
result.addAll(globalEndConstraints);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private PositionRestrictions enforceRestrictions(GanttDate newEnd) {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,9 @@ import org.springframework.security.context.SecurityContextHolder;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.zkoss.ganttz.adapters.PlannerConfiguration;
|
||||
import org.zkoss.ganttz.data.ConstraintCalculator;
|
||||
import org.zkoss.ganttz.data.DependencyType;
|
||||
import org.zkoss.ganttz.data.DependencyType.Point;
|
||||
import org.zkoss.ganttz.data.GanttDate;
|
||||
import org.zkoss.ganttz.data.GanttDiagramGraph;
|
||||
import org.zkoss.ganttz.data.GanttDiagramGraph.IAdapter;
|
||||
|
|
@ -94,25 +96,12 @@ public class TemplateModel implements ITemplateModel {
|
|||
.getDestination(), toGraphicalType(each.getType()), true);
|
||||
}
|
||||
|
||||
public static List<Constraint<GanttDate>> getStartConstraintsGiven(
|
||||
TemplateModelAdapter adapter, Set<DependencyWithVisibility> withDependencies) {
|
||||
public static List<Constraint<GanttDate>> getConstraints(
|
||||
ConstraintCalculator<TaskElement> calculator,
|
||||
Set<DependencyWithVisibility> withDependencies, Point point) {
|
||||
List<Constraint<GanttDate>> result = new ArrayList<Constraint<GanttDate>>();
|
||||
for (DependencyWithVisibility each : withDependencies) {
|
||||
TaskElement source = each.getSource();
|
||||
DependencyType type = each.getType();
|
||||
result.addAll(type.getStartConstraints(source, adapter));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Constraint<GanttDate>> getEndConstraintsGiven(
|
||||
TemplateModelAdapter adapter,
|
||||
Set<DependencyWithVisibility> withDependencies) {
|
||||
List<Constraint<GanttDate>> result = new ArrayList<Constraint<GanttDate>>();
|
||||
for (DependencyWithVisibility each : withDependencies) {
|
||||
TaskElement source = each.getSource();
|
||||
DependencyType type = each.getType();
|
||||
result.addAll(type.getEndConstraints(source, adapter));
|
||||
result.addAll(calculator.getConstraints(each, point));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,8 @@ package org.navalplanner.web.common;
|
|||
|
||||
import static org.navalplanner.web.planner.TaskElementAdapter.toGantt;
|
||||
import static org.navalplanner.web.planner.TaskElementAdapter.toIntraDay;
|
||||
import static org.zkoss.ganttz.data.constraint.ConstraintOnComparableValues.biggerOrEqualThan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
|
@ -18,7 +16,9 @@ import org.navalplanner.business.scenarios.entities.Scenario;
|
|||
import org.navalplanner.business.workingday.IntraDayDate;
|
||||
import org.navalplanner.web.common.TemplateModel.DependencyWithVisibility;
|
||||
import org.navalplanner.web.planner.TaskElementAdapter;
|
||||
import org.zkoss.ganttz.data.ConstraintCalculator;
|
||||
import org.zkoss.ganttz.data.DependencyType;
|
||||
import org.zkoss.ganttz.data.DependencyType.Point;
|
||||
import org.zkoss.ganttz.data.GanttDate;
|
||||
import org.zkoss.ganttz.data.GanttDiagramGraph.IAdapter;
|
||||
import org.zkoss.ganttz.data.GanttDiagramGraph.IDependenciesEnforcerHook;
|
||||
|
|
@ -63,22 +63,6 @@ public class TemplateModelAdapter implements
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Constraint<GanttDate>> getEndConstraintsGivenIncoming(
|
||||
Set<DependencyWithVisibility> incoming) {
|
||||
return DependencyWithVisibility.getEndConstraintsGiven(this, incoming);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Constraint<GanttDate>> getCurrentLenghtConstraintFor(
|
||||
TaskElement task) {
|
||||
if (isContainer(task)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.singletonList(biggerOrEqualThan(this
|
||||
.getEndDateFor(task)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<DependencyWithVisibility> getDependencyType() {
|
||||
return DependencyWithVisibility.class;
|
||||
|
|
@ -116,10 +100,11 @@ public class TemplateModelAdapter implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Constraint<GanttDate>> getStartConstraintsGiven(
|
||||
Set<DependencyWithVisibility> withDependencies) {
|
||||
return DependencyWithVisibility.getStartConstraintsGiven(this,
|
||||
withDependencies);
|
||||
public List<Constraint<GanttDate>> getConstraints(
|
||||
ConstraintCalculator<TaskElement> calculator,
|
||||
Set<DependencyWithVisibility> withDependencies, Point point) {
|
||||
return DependencyWithVisibility.getConstraints(calculator,
|
||||
withDependencies, point);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue