diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDate.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDate.java
new file mode 100644
index 000000000..8c761e3f8
--- /dev/null
+++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/GanttDate.java
@@ -0,0 +1,202 @@
+/*
+ * This file is part of NavalPlan
+ *
+ * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
+ * Desenvolvemento Tecnolóxico de Galicia
+ *
+ * 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 java.util.Date;
+
+import org.apache.commons.lang.Validate;
+import org.joda.time.LocalDate;
+
+/**
+ * @author Óscar González Fernández
+ *
+ */
+public abstract class GanttDate implements Comparable {
+
+ public static LocalDateBased createFrom(Date date) {
+ if (date == null) {
+ return null;
+ }
+ return createFrom(LocalDate.fromDateFields(date));
+ }
+
+ public static LocalDateBased createFrom(LocalDate localDate) {
+ if (localDate == null) {
+ return null;
+ }
+ return new LocalDateBased(localDate);
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof GanttDate) {
+ GanttDate other = (GanttDate) obj;
+ return isEqualsTo(other);
+ }
+ return false;
+ }
+
+ protected abstract boolean isEqualsTo(GanttDate other);
+
+ @Override
+ public abstract int hashCode();
+
+ public interface ICases {
+ public R on(LocalDateBased localDateBased);
+
+ public R on(CustomDate customType);
+ }
+
+ public static abstract class Cases implements
+ ICases {
+
+ private final Class klass;
+
+ public Cases(Class klass) {
+ Validate.notNull(klass);
+ this.klass = klass;
+ }
+
+ @Override
+ public R on(CustomDate customType) {
+ return onCustom(klass.cast(customType));
+ }
+
+ protected abstract R onCustom(T customType);
+ }
+
+ public abstract R byCases(ICases cases);
+
+ // TODO remove this method
+ public abstract Date toDateApproximation();
+
+ public static class LocalDateBased extends GanttDate {
+
+ private final LocalDate localDate;
+
+ public LocalDateBased(LocalDate localDate) {
+ Validate.notNull(localDate);
+ this.localDate = localDate;
+ }
+
+ public LocalDate getLocalDate() {
+ return localDate;
+ }
+
+ public R byCases(ICases cases) {
+ return cases.on(this);
+ }
+
+ @Override
+ public int compareTo(GanttDate o) {
+ return o.byCases(new ICases() {
+
+ @Override
+ public Integer on(LocalDateBased localDateBased) {
+ return localDate.compareTo(localDateBased.localDate);
+ }
+
+ @Override
+ public Integer on(CustomDate customType) {
+ return -customType.compareToLocalDate(localDate);
+ }
+ });
+ }
+
+ @Override
+ public Date toDateApproximation() {
+ return localDate.toDateTimeAtStartOfDay().toDate();
+ }
+
+ @Override
+ public boolean isEqualsTo(GanttDate other) {
+ return other.byCases(new ICases() {
+
+ @Override
+ public Boolean on(LocalDateBased localDateBased) {
+ return localDate.equals(localDateBased.localDate);
+ }
+
+ @Override
+ public Boolean on(CustomDate customType) {
+ return false;
+ }
+ });
+ }
+
+ @Override
+ public int hashCode() {
+ return localDate.hashCode();
+ }
+
+ }
+
+ public static abstract class CustomDate extends GanttDate {
+
+ public CustomDate() {
+ }
+
+ protected abstract boolean isEqualsToCustom(CustomDate customType);
+
+ @Override
+ protected boolean isEqualsTo(GanttDate other) {
+ return other.byCases(new ICases() {
+
+ @Override
+ public Boolean on(LocalDateBased localDateBased) {
+ return false;
+ }
+
+ @Override
+ public Boolean on(CustomDate customType) {
+ return isEqualsToCustom(customType);
+ }
+ });
+ }
+
+ @Override
+ public R byCases(ICases cases) {
+ return cases.on(this);
+ }
+
+ @Override
+ public int compareTo(GanttDate o) {
+ return byCases(new ICases() {
+ @Override
+ public Integer on(LocalDateBased localDateBased) {
+ return compareToLocalDate(localDateBased.localDate);
+ }
+
+ @Override
+ public Integer on(CustomDate customType) {
+ return compareToCustom(customType);
+ }
+ });
+ }
+
+ protected abstract int compareToCustom(CustomDate customType);
+
+ protected abstract int compareToLocalDate(LocalDate localDate);
+ }
+
+}
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/workingday/IntraDayDate.java b/navalplanner-business/src/main/java/org/navalplanner/business/workingday/IntraDayDate.java
index a98b5ea3d..6a6f030d4 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/workingday/IntraDayDate.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/workingday/IntraDayDate.java
@@ -134,4 +134,12 @@ public class IntraDayDate implements Comparable {
return getDate().plusDays(1);
}
+ public int compareTo(LocalDate other) {
+ int result = this.date.compareTo(other);
+ if (result != 0) {
+ return result;
+ }
+ return isStartOfDay() ? 0 : 1;
+ }
+
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/TaskElementAdapter.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/TaskElementAdapter.java
index a2b9c4948..9cc8d9cc1 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/TaskElementAdapter.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/TaskElementAdapter.java
@@ -62,12 +62,17 @@ import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.scenarios.entities.Scenario;
+import org.navalplanner.business.workingday.IntraDayDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.zkoss.ganttz.adapters.DomainDependency;
import org.zkoss.ganttz.data.DependencyType;
+import org.zkoss.ganttz.data.GanttDate;
+import org.zkoss.ganttz.data.GanttDate.Cases;
+import org.zkoss.ganttz.data.GanttDate.CustomDate;
+import org.zkoss.ganttz.data.GanttDate.LocalDateBased;
import org.zkoss.ganttz.data.ITaskFundamentalProperties;
import org.zkoss.ganttz.data.constraint.Constraint;
import org.zkoss.ganttz.data.constraint.DateConstraint;
@@ -146,6 +151,74 @@ public class TaskElementAdapter implements ITaskElementAdapter {
public TaskElementAdapter() {
}
+ public static GanttDate toGantt(IntraDayDate date) {
+ return new GanttDateAdapter(date);
+ }
+
+ public static IntraDayDate toIntraDay(GanttDate date) {
+ return date.byCases(new Cases(
+ GanttDateAdapter.class) {
+
+ @Override
+ public IntraDayDate on(LocalDateBased localDate) {
+ return IntraDayDate.startOfDay(localDate.getLocalDate());
+ }
+
+ @Override
+ protected IntraDayDate onCustom(GanttDateAdapter customType) {
+ return customType.date;
+ }
+ });
+ }
+
+ public static LocalDate toLocalDate(GanttDate date) {
+ return toIntraDay(date).getDate();
+ }
+
+ static class GanttDateAdapter extends CustomDate {
+
+ private final IntraDayDate date;
+
+ GanttDateAdapter(IntraDayDate date) {
+ this.date = date;
+ }
+
+ protected int compareToCustom(CustomDate customType) {
+ if (customType instanceof GanttDateAdapter) {
+ GanttDateAdapter other = (GanttDateAdapter) customType;
+ return this.date.compareTo(other.date);
+ }
+ throw new RuntimeException("incompatible type: " + customType);
+ }
+
+ protected int compareToLocalDate(LocalDate localDate) {
+ return this.date.compareTo(localDate);
+ }
+
+ public IntraDayDate getDate() {
+ return date;
+ }
+
+ @Override
+ public Date toDateApproximation() {
+ return date.toDateTimeAtStartOfDay().toDate();
+ }
+
+ @Override
+ protected boolean isEqualsToCustom(CustomDate customType) {
+ if (customType instanceof GanttDateAdapter) {
+ GanttDateAdapter other = (GanttDateAdapter) customType;
+ return this.date.equals(other.date);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return date.hashCode();
+ }
+ }
+
private class TaskElementWrapper implements ITaskFundamentalProperties {
private final TaskElement taskElement;