diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/ConstraintCalculator.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/ConstraintCalculator.java
new file mode 100644
index 000000000..4ff80a38d
--- /dev/null
+++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/ConstraintCalculator.java
@@ -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 .
+ */
+
+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
+ */
+public abstract class ConstraintCalculator {
+
+ private final boolean reversed;
+
+ protected ConstraintCalculator(boolean reversed) {
+ this.reversed = reversed;
+ }
+
+ public List> getConstraints(
+ IDependency 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 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 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);
+
+}
diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/Dependency.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/Dependency.java
index 9fe01ee66..f7560ce93 100644
--- a/ganttzk/src/main/java/org/zkoss/ganttz/data/Dependency.java
+++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/Dependency.java
@@ -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 {
- private enum Calculation {
- START {
- @Override
- public List> toConstraints(Task source,
- DependencyType type) {
- return type.getStartConstraints(source);
- }
- },
- END {
- @Override
- public List> toConstraints(Task source,
- DependencyType type) {
- return type.getEndConstraints(source);
- }
- };
-
- abstract List> toConstraints(Task source,
- DependencyType type);
- }
-
- public static List> getStartConstraints(
- Collection dependencies) {
- return getConstraintsFor(dependencies, Calculation.START);
- }
-
- public static List> getEndConstraints(
- Collection incoming) {
- return getConstraintsFor(incoming, Calculation.END);
- }
-
- private static List> getConstraintsFor(
- Collection dependencies, Calculation calculation) {
+ public static List> getConstraintsFor(
+ ConstraintCalculator calculator,
+ Collection dependencies, Point pointBeingModified) {
List> result = new ArrayList>();
- 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 {
this(source, destination, type, true);
}
- private List> toConstraints(Calculation calculation) {
- return violationsNotificator.withListener(calculation.toConstraints(
- source, type));
+ private List> withViolationNotification(
+ List> original) {
+ return violationsNotificator.withListener(original);
}
public void addConstraintViolationListener(
diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/DependencyType.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/DependencyType.java
index 14864b2c6..5edd7fb97 100644
--- a/ganttzk/src/main/java/org/zkoss/ganttz/data/DependencyType.java
+++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/DependencyType.java
@@ -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> getStartConstraints(Task source) {
- return getStartConstraints(source, GanttDiagramGraph.taskAdapter());
- }
-
- public final List> getStartConstraints(V source,
- IAdapter adapter) {
- if (getDestination() != Point.START) {
- return emptyList();
- }
- return constraintsFromReferenceDate(getReferenceDate(source, adapter));
- }
-
- public final List> getEndConstraints(Task source) {
- return getEndConstraints(source, GanttDiagramGraph.taskAdapter());
- }
-
- public final List> getEndConstraints(V source,
- IAdapter adapter) {
- if (getDestination() != Point.END) {
- return emptyList();
- }
- return constraintsFromReferenceDate(getReferenceDate(source, adapter));
- }
-
- private GanttDate getReferenceDate(V source, IAdapter adapter) {
- if (getSource() == Point.START) {
- return adapter.getStartDate(source);
- } else {
- return adapter.getEndDateFor(source);
- }
- }
-
- private List> 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();
}
diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDiagramGraph.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDiagramGraph.java
index cc979e579..c4f556db2 100644
--- a/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDiagramGraph.java
+++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDiagramGraph.java
@@ -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> implements
GanttDate getSmallestBeginDateFromChildrenFor(V container);
- List> getCurrentLenghtConstraintFor(V task);
-
- List> getEndConstraintsGivenIncoming(
- Set incoming);
-
- List> getStartConstraintsGiven(
- Set withDependencies);
+ public List> getConstraints(
+ ConstraintCalculator calculator, Set withDependencies,
+ Point point);
List> getStartConstraintsFor(V task);
@@ -181,17 +179,6 @@ public class GanttDiagramGraph> implements
return task.getEndDate();
}
- @Override
- public List> getCurrentLenghtConstraintFor(
- Task task) {
- return task.getCurrentLengthConstraint();
- }
-
- @Override
- public List> getEndConstraintsGivenIncoming(
- Set incoming) {
- return Dependency.getEndConstraints(incoming);
- }
@Override
public void setEndDateFor(Task task, GanttDate newEnd) {
@@ -209,9 +196,11 @@ public class GanttDiagramGraph> implements
}
@Override
- public List> getStartConstraintsGiven(
- Set withDependencies) {
- return Dependency.getStartConstraints(withDependencies);
+ public List> getConstraints(
+ ConstraintCalculator calculator,
+ Set withDependencies, Point pointBeingModified) {
+ return Dependency.getConstraintsFor(calculator, withDependencies,
+ pointBeingModified);
}
@Override
@@ -1008,15 +997,27 @@ public class GanttDiagramGraph> 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> getConstraintsToApply() {
+ List> result = new ArrayList>();
+ 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> 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 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
- . initialValue(null)
- .withConstraints(originalRestrictions.getStartConstraints())
- .withConstraints(getStartConstraints())
+ GanttDate newStart = Constraint
+ . initialValue(null)
+ .withConstraints(
+ getConstraintsFrom(originalRestrictions,
+ getPrimaryPoint()))
+ .withConstraints(getConstraintsFor(getPrimaryPoint()))
.applyWithoutFinalCheck();
if (newStart == null) {
- return adapter.getStartDate(task);
+ return getTaskDateFor(getPrimaryPoint());
}
return newStart;
}
- @Override
- List> getStartConstraints() {
- List> result = new ArrayList>();
- if (dependenciesConstraintsHavePriority) {
- result.addAll(adapter.getStartConstraintsFor(task));
- result.addAll(getDependenciesCosntraintsForStart());
-
- } else {
- result.addAll(getDependenciesCosntraintsForStart());
- result.addAll(adapter.getStartConstraintsFor(task));
+ private List> 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> getDependenciesCosntraintsForStart() {
- final Set withDependencies = graph.incomingEdgesOf(task);
- return adapter.getStartConstraintsGiven(withDependencies);
- }
-
- private PositionRestrictions enforceEndDate(
+ private PositionRestrictions enforceSecondaryPoint(
PositionRestrictions restrictions) {
- GanttDate newEnd = Constraint
- . 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> getEndConstraints() {
- Set incoming = graph.incomingEdgesOf(task);
- return adapter.getEndConstraintsGivenIncoming(incoming);
+
+ private GanttDate calculateSecondaryPointDate(
+ PositionRestrictions restrictions) {
+ GanttDate newEnd = Constraint
+ . 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> 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> getConstraintsForPrimaryPoint() {
+ List> result = new ArrayList>();
+ 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> getConstraintsForSecondaryPoint() {
+ return getDependenciesConstraintsFor(getSecondaryPoint());
+ }
+
+ private List> getDependenciesConstraintsFor(
+ Point point) {
+ final Set withDependencies = getDependenciesAffectingThisTask();
+ return adapter.getConstraints(getCalculator(),
+ withDependencies, point);
+ }
+
+ protected abstract Set getDependenciesAffectingThisTask();
+
+ private List> 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 getCalculator();
+
+ protected ConstraintCalculator createNormalCalculator() {
+ return createCalculator(false);
+ }
+
+ protected ConstraintCalculator createBackwardsCalculator() {
+ return createCalculator(true);
+ }
+
+ private ConstraintCalculator createCalculator(boolean inverse) {
+ return new ConstraintCalculator(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> getStartConstraints() {
+ return getConstraintsForPrimaryPoint();
+ }
+
+ @Override
+ List> getEndConstraints() {
+ return getConstraintsForSecondaryPoint();
+ }
+
+ @Override
+ protected Set getDependenciesAffectingThisTask() {
+ return graph.incomingEdgesOf(task);
+ }
+
+ @Override
+ protected ConstraintCalculator 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> getStartConstraints() {
+ return getConstraintsForSecondaryPoint();
+ }
+
+ @Override
+ List> getEndConstraints() {
+ return getConstraintsForPrimaryPoint();
+ }
+
+ @Override
+ protected Set getDependenciesAffectingThisTask() {
+ return graph.outgoingEdgesOf(task);
+ }
+
+ @Override
+ protected ConstraintCalculator 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> getStartConstraints() {
+ return adapter.getStartConstraintsFor(task);
+ }
+
+ @Override
+ List> getEndConstraints() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ PositionRestrictions enforceUsingPreviousRestrictions(
+ PositionRestrictions restrictions) {
+ GanttDate result = Constraint. 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> implements
@Override
List> getEndConstraints() {
- return adapter.getEndConstraintsFor(task);
+ List> result = new ArrayList>();
+ result.addAll(adapter.getEndConstraintsFor(task));
+ if (scheduleBackwards) {
+ result.addAll(globalEndConstraints);
+ }
+ return result;
}
private PositionRestrictions enforceRestrictions(GanttDate newEnd) {
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModel.java
index b4fd30ddd..5b2be5809 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModel.java
@@ -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> getStartConstraintsGiven(
- TemplateModelAdapter adapter, Set withDependencies) {
+ public static List> getConstraints(
+ ConstraintCalculator calculator,
+ Set withDependencies, Point point) {
List> result = new ArrayList>();
for (DependencyWithVisibility each : withDependencies) {
- TaskElement source = each.getSource();
- DependencyType type = each.getType();
- result.addAll(type.getStartConstraints(source, adapter));
- }
- return result;
- }
-
- public static List> getEndConstraintsGiven(
- TemplateModelAdapter adapter,
- Set withDependencies) {
- List> result = new ArrayList>();
- 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;
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModelAdapter.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModelAdapter.java
index 907ab3385..e895ed896 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModelAdapter.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/TemplateModelAdapter.java
@@ -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> getEndConstraintsGivenIncoming(
- Set incoming) {
- return DependencyWithVisibility.getEndConstraintsGiven(this, incoming);
- }
-
- @Override
- public List> getCurrentLenghtConstraintFor(
- TaskElement task) {
- if (isContainer(task)) {
- return Collections.emptyList();
- }
- return Collections.singletonList(biggerOrEqualThan(this
- .getEndDateFor(task)));
- }
-
@Override
public Class getDependencyType() {
return DependencyWithVisibility.class;
@@ -116,10 +100,11 @@ public class TemplateModelAdapter implements
}
@Override
- public List> getStartConstraintsGiven(
- Set withDependencies) {
- return DependencyWithVisibility.getStartConstraintsGiven(this,
- withDependencies);
+ public List> getConstraints(
+ ConstraintCalculator calculator,
+ Set withDependencies, Point point) {
+ return DependencyWithVisibility.getConstraints(calculator,
+ withDependencies, point);
}
@Override