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 7501d3f3f..f62e43d27 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDiagramGraph.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDiagramGraph.java @@ -1039,6 +1039,9 @@ public class GanttDiagramGraph> implements .withConstraints(currentLength) .withConstraints(adapter.getEndConstraintsGivenIncoming(incoming)) .apply(); + if (newEnd == null) { + return false; + } if (hasChanged(previousEndDate, newEnd)) { adapter.setEndDateFor(task, newEnd); } @@ -1059,13 +1062,14 @@ public class GanttDiagramGraph> implements } private boolean hasChanged(GanttDate old, GanttDate newValue) { - if (old == newValue) { - return false; - } - return (old == null) != (newValue == null) - || old.compareTo(newValue) != 0; + return old != newValue && old.compareTo(newValue) != 0; } + /** + * Calculates the new start date based on the present constraints. If + * there are no constraints this method will return the existent start + * date value. + */ private GanttDate calculateStartDateFor(V task, Set withDependencies) { List> dependencyConstraints = adapter .getStartConstraintsGiven(withDependencies); @@ -1082,6 +1086,9 @@ public class GanttDiagramGraph> implements .withConstraints(adapter.getStartConstraintsFor(task)) .withConstraints(globalStartConstraints).apply(); } + if (newStart == null) { + return adapter.getStartDate(task); + } return newStart; } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/TaskElement.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/TaskElement.java index b5c98705a..38807bfb5 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/TaskElement.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/TaskElement.java @@ -35,6 +35,8 @@ import java.util.SortedMap; import java.util.TreeMap; import org.apache.commons.lang.Validate; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.hibernate.validator.NotNull; import org.joda.time.LocalDate; import org.navalplanner.business.calendars.entities.BaseCalendar; @@ -54,6 +56,8 @@ import org.navalplanner.business.workingday.ResourcesPerDay; */ public abstract class TaskElement extends BaseEntity { + private static final Log LOG = LogFactory.getLog(TaskElement.class); + public interface IDatesInterceptor { public void setStartDate(IntraDayDate previousStart, IntraDayDate previousEnd, IntraDayDate newStart); @@ -251,6 +255,9 @@ public abstract class TaskElement extends BaseEntity { } public void setIntraDayStartDate(IntraDayDate startDate) { + if (startDate == null) { + LOG.error(doNotProvideNullsDiscouragingMessage()); + } IntraDayDate previousStart = getIntraDayStartDate(); IntraDayDate previousEnd = getIntraDayEndDate(); this.startDate = startDate; @@ -281,11 +288,21 @@ public abstract class TaskElement extends BaseEntity { } public void setIntraDayEndDate(IntraDayDate endDate) { + if (endDate == null) { + LOG.error(doNotProvideNullsDiscouragingMessage()); + } IntraDayDate previousEnd = getIntraDayEndDate(); this.endDate = endDate; datesInterceptor.setNewEnd(previousEnd, this.endDate); } + private String doNotProvideNullsDiscouragingMessage() { + return "The provided date shouldn't be null.\n" + + "Providing null values to start or end dates is not safe.\n" + + "In a near future an exception will be thrown if you provide a null value to a start or end date.\n" + + "Please detect the caller and fix it"; + } + public IntraDayDate getIntraDayEndDate() { return endDate; } @@ -304,33 +321,27 @@ public abstract class TaskElement extends BaseEntity { } private IDatesHandler getDatesHandler(Scenario scenario) { - return ignoreNullDates(createDatesHandler(scenario)); + return noNullDates(createDatesHandler(scenario)); } - private IDatesHandler ignoreNullDates(final IDatesHandler decorated) { + private IDatesHandler noNullDates(final IDatesHandler decorated) { return new IDatesHandler() { @Override public void resizeTo(IntraDayDate endDate) { - if (endDate == null) { - return; - } + Validate.notNull(endDate); decorated.resizeTo(endDate); } @Override public void moveTo(IntraDayDate newStartDate) { - if (newStartDate == null) { - return; - } + Validate.notNull(newStartDate); decorated.moveTo(newStartDate); } @Override public void moveEndTo(IntraDayDate newEnd) { - if (newEnd == null) { - return; - } + Validate.notNull(newEnd); decorated.moveEndTo(newEnd); } };