org.libreplan.importers.MPXJProjectFileConverter.java Source code

Java tutorial

Introduction

Here is the source code for org.libreplan.importers.MPXJProjectFileConverter.java

Source

/*
 * This file is part of LibrePlan
 *
 * Copyright (C) 2012 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.libreplan.importers;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import net.sf.mpxj.DateRange;
import net.sf.mpxj.DayType;
import net.sf.mpxj.Duration;
import net.sf.mpxj.ProjectCalendar;
import net.sf.mpxj.ProjectCalendarDateRanges;
import net.sf.mpxj.ProjectCalendarException;
import net.sf.mpxj.ProjectCalendarWeek;
import net.sf.mpxj.ProjectFile;
import net.sf.mpxj.ProjectProperties;
import net.sf.mpxj.Relation;
import net.sf.mpxj.RelationType;
import net.sf.mpxj.Task;
import net.sf.mpxj.TimeUnit;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.libreplan.importers.CalendarDayHoursDTO.CalendarDayDTO;
import org.libreplan.importers.CalendarDayHoursDTO.CalendarTypeDayDTO;
import org.libreplan.importers.DependencyDTO.TypeOfDependencyDTO;

/**
 * Class that is a converter from the MPXJ format File to {@link OrderDTO}.
 *
 * @author Alba Carro Prez <alba.carro@gmail.com>
 * @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
 *
 * @todo It last relationships. resources, calendars, hours, etc.
 */
public class MPXJProjectFileConverter {

    private static ProjectProperties properties;

    /**
     * Map between the MPXJ Task and the OrderElemenDTO or MilestoneDTO that represent it.
     */
    private static Map<Task, IHasTaskAssociated> mapTask;

    /**
     * Converts a ProjectFile into a {@link OrderDTO}.
     *
     * This method contains a switch that is going to select the method to call for each format.
     * At this time it only differences between planner and project.
     *
     * @param file
     *            ProjectFile to extract data from.
     * @return ImportData with the data that we want to import.
     */
    public static OrderDTO convert(ProjectFile file, String filename) {

        OrderDTO importData = null;

        if (FilenameUtils.getExtension(filename).equals("planner"))
            importData = getImportDataFromPlanner(file, filename);
        else if (FilenameUtils.getExtension(filename).equals("mpp"))
            importData = getImportDataFromMPP(file, filename);
        return importData;
    }

    /**
     * Get a list of {@link CalendarDTO} from a ProjectFile.
     *
     * @param file
     *            ProjectFile to extract data from.
     * @return List<CalendarDTO> List with the calendars that we want to import.
     */
    public static List<CalendarDTO> convertCalendars(ProjectFile file) {

        List<CalendarDTO> calendarDTOs = new ArrayList<>();

        for (ProjectCalendar projectCalendar : file.getCalendars()) {
            if (StringUtils.isBlank(projectCalendar.getName())) {
                String name = "calendar-" + UUID.randomUUID();
                projectCalendar.setName(name);
            }
            calendarDTOs.add(toCalendarDTO(projectCalendar));
            calendarDTOs.addAll(getDerivedCalendars(projectCalendar.getDerivedCalendars()));
        }

        return calendarDTOs;
    }

    /**
     * Get a list of {@link CalendarDTO} from a ProjectFile.
     *
     * @param derivedProjectCalendars
     *            ProjectCalendar to extract data from.
     * @return List<CalendarDTO> List with the calendars that we want to import.
     */
    public static List<CalendarDTO> getDerivedCalendars(List<ProjectCalendar> derivedProjectCalendars) {

        List<CalendarDTO> calendarDTOs = new ArrayList<>();

        for (ProjectCalendar projectCalendar : derivedProjectCalendars) {

            if (projectCalendar.getResource() == null && projectCalendar.getName() != null
                    && projectCalendar.getName().length() != 0) {

                calendarDTOs.add(toCalendarDTO(projectCalendar));
                calendarDTOs.addAll(getDerivedCalendars(projectCalendar.getDerivedCalendars()));
            }
        }

        return calendarDTOs;
    }

    /**
     * Get {@link CalendarDTO} from a ProjectCalendar.
     *
     * @param projectCalendar
     *            ProjectCalendar to extract data from.
     * @return List<CalendarDTO> List with the calendars that we want to import.
     */
    private static CalendarDTO toCalendarDTO(ProjectCalendar projectCalendar) {

        CalendarDTO calendarDTO = new CalendarDTO();

        calendarDTO.name = projectCalendar.getName();

        if (projectCalendar.getParent() != null) {
            calendarDTO.parent = projectCalendar.getParent().getName();
        }

        calendarDTO.calendarExceptions = getCalendarExceptionDTOs(projectCalendar.getCalendarExceptions());

        List<ProjectCalendarWeek> workWeeks = projectCalendar.getWorkWeeks();

        Collections.sort(workWeeks, new CompareMPXJProjectCalendarWeeks());

        calendarDTO.calendarWeeks = getCalendarWeekDTOs(projectCalendar, workWeeks);

        return calendarDTO;
    }

    /**
     * Get a list of {@link CalendarExceptionDTO} from a list of CalendarExceptions.
     *
     * @param calendarExceptions
     *            List of CalendarException to extract data from.
     * @return List<CalendarExceptionDTO> List with the CalendarExcepitions that we want to import.
     */
    private static List<CalendarExceptionDTO> getCalendarExceptionDTOs(
            List<ProjectCalendarException> calendarExceptions) {

        List<CalendarExceptionDTO> calendarExceptionDTOs = new ArrayList<>();

        for (ProjectCalendarException projectCalendarException : calendarExceptions) {

            calendarExceptionDTOs.addAll(toCalendarExceptionDTOs(projectCalendarException));
        }

        return calendarExceptionDTOs;
    }

    /**
     * Get {@link CalendarExceptionDTO} from a ProjectCalendarException.
     *
     * @param projectCalendarException
     *            ProjectCalendarException to extract data from.
     * @return List<CalendarExceptionDTO>  with the calendar exceptions that we want to import.
     */
    private static List<CalendarExceptionDTO> toCalendarExceptionDTOs(
            ProjectCalendarException projectCalendarException) {

        List<CalendarExceptionDTO> calendarExceptionDTOs = new ArrayList<>();

        Date fromDate = projectCalendarException.getFromDate();

        Date toDate = projectCalendarException.getToDate();

        Period period = new Period(new DateTime(fromDate), new DateTime(toDate));

        boolean working = projectCalendarException.getWorking();

        int day = period.getDays();

        Calendar cal = Calendar.getInstance();
        cal.setTime(fromDate);

        List<Integer> duration = toHours(projectCalendarException);

        int hours;

        int minutes;

        if (duration != null) {
            hours = duration.get(0);

            minutes = duration.get(1);
        } else {

            if (working) {

                hours = 8;

            } else {

                hours = 0;

            }

            minutes = 0;
        }

        while (day > -1) {
            if (day == 0) {

                calendarExceptionDTOs.add(toCalendarExceptionDTO(cal.getTime(), hours, minutes, working));

            } else {

                calendarExceptionDTOs.add(toCalendarExceptionDTO(cal.getTime(), hours, minutes, working));

                cal.add(Calendar.DAY_OF_MONTH, +1);

            }

            day--;

        }

        return calendarExceptionDTOs;
    }

    /**
     * Get {@link CalendarExceptionDTO} from a ProjectCalendarException.
     *
     * @param fromDate
     *            Date with the day of the exception.
     * @param hours
     *            int with the hours.
     * @param minutes
     *            int with the minutes.
     * @param working
     *            boolean to express it is a working exception or not
     * @return CalendarExceptionDTO  with the calendar exceptions that we want to import.
     */
    private static CalendarExceptionDTO toCalendarExceptionDTO(Date fromDate, int hours, int minutes,
            boolean working) {

        CalendarExceptionDTO calendarExceptionDTO = new CalendarExceptionDTO();

        calendarExceptionDTO.date = fromDate;

        calendarExceptionDTO.hours = hours;

        calendarExceptionDTO.minutes = minutes;

        calendarExceptionDTO.working = working;

        return calendarExceptionDTO;

    }

    /**
     * Get a list of {@link CalendarWeekDTO} from a list of ProjectCalendarWeek.
     *
     * @param projectCalendar
     *            ProjectCalendarWeek with the default data
     * @param workWeeks
     *            List of ProjectCalendarWeek to extract data from.Assume that is ordered
     *            for its DataRange start date.
     * @return List<CalendarDataDTO> List with the CalendarData that we want to import.
     */
    private static List<CalendarWeekDTO> getCalendarWeekDTOs(ProjectCalendar projectCalendar,
            List<ProjectCalendarWeek> workWeeks) {

        List<CalendarWeekDTO> calendarDataDTOs = new ArrayList<>();

        Date startCalendarDate;
        Date endCalendarDate;

        if (projectCalendar.getDateRange() == null) {
            startCalendarDate = projectCalendar.getParentFile().getProjectProperties().getStartDate();
            endCalendarDate = projectCalendar.getParentFile().getProjectProperties().getFinishDate();

        } else {
            startCalendarDate = projectCalendar.getDateRange().getStart();
            endCalendarDate = projectCalendar.getDateRange().getEnd();

        }

        if (workWeeks.isEmpty()) {
            calendarDataDTOs.add(toCalendarWeekDTO(projectCalendar));
        } else {

            /*
             * TODO
             *  This utility is not currently implemented in MPXJ.
             *  This one is going to represent all the work weeks.
             *  Including the ones with the default value that are in the middle of two.
             */

            Date firsWorkWeekCalendarDate = workWeeks.get(0).getDateRange().getStart();
            Calendar calendar1 = Calendar.getInstance();
            Calendar calendar2 = Calendar.getInstance();

            // If the star of the first work week is after the start of the default we have to fill the hole
            if (startCalendarDate.compareTo(firsWorkWeekCalendarDate) < 0) {
                calendar1.setTime(firsWorkWeekCalendarDate);
                calendar1.set(Calendar.DAY_OF_MONTH, -1);
                calendarDataDTOs.add(toCalendarWeekDTO(projectCalendar));
            }

            Date endDate;
            Date nextStartDate;

            int j;
            for (int i = 0; i < workWeeks.size(); i++) {
                endDate = workWeeks.get(i).getDateRange().getEnd();
                calendarDataDTOs.add(toCalendarWeekDTO(workWeeks.get(i)));

                j = i + 1;

                // If is not the last one
                if (j < workWeeks.size()) {
                    nextStartDate = workWeeks.get(i + 1).getDateRange().getStart();
                    calendar1.setTime(endDate);
                    calendar1.set(Calendar.DAY_OF_MONTH, +1);

                    // If the end of the current work week is more than one day before the beginning of the next
                    if (calendar1.getTime().compareTo(nextStartDate) < 0) {
                        calendar2.setTime(nextStartDate);
                        calendar1.set(Calendar.DAY_OF_MONTH, -1);

                        // Adds a new default calendar week in the hole
                        calendarDataDTOs.add(toCalendarWeekDTO(projectCalendar));
                    }
                }
            }

            Date endWorkWeekCalendarDate = workWeeks.get(workWeeks.size()).getDateRange().getEnd();

            // If the end of the last work week is earlier than the end of the default we have to fill the hole
            if (endCalendarDate.compareTo(endWorkWeekCalendarDate) > 0) {
                calendar1.setTime(endWorkWeekCalendarDate);
                calendar1.set(Calendar.DAY_OF_MONTH, +1);
                calendarDataDTOs.add(toCalendarWeekDTO(projectCalendar));
            }

        }

        return calendarDataDTOs;
    }

    /**
     * Get {@link CalendarWeekDTO} from a ProjectCalendarWeek.
     *
     * @param projectCalendarWeek
     *            ProjectCalendarWeek to extract data from.
     * @return CalendarDataDTO  with the calendar data that we want to import.
     */
    private static CalendarWeekDTO toCalendarWeekDTO(ProjectCalendarWeek projectCalendarWeek) {

        CalendarWeekDTO calendarDataDTO = new CalendarWeekDTO();

        if (projectCalendarWeek.getDateRange() != null) {

            calendarDataDTO.startDate = projectCalendarWeek.getDateRange().getStart();

            calendarDataDTO.endDate = projectCalendarWeek.getDateRange().getEnd();

        } else {

            calendarDataDTO.startDate = null;

            calendarDataDTO.endDate = null;

        }
        List<CalendarDayHoursDTO> calendarDaysHourDTOs = new ArrayList<>();

        CalendarDayHoursDTO calendarDayHoursDTO;

        for (int i = 0; i < 7; i++) {

            calendarDayHoursDTO = new CalendarDayHoursDTO();

            calendarDayHoursDTO.type = toCalendarTypeDayDTO(projectCalendarWeek.getDays()[i]);
            calendarDayHoursDTO.day = CalendarDayDTO.values()[i];

            List<Integer> duration = toHours(projectCalendarWeek.getHours()[i]);

            if (duration != null) {
                calendarDayHoursDTO.hours = duration.get(0);

                calendarDayHoursDTO.minutes = duration.get(1);
            } else {
                if (calendarDayHoursDTO.type == CalendarTypeDayDTO.WORKING) {
                    calendarDayHoursDTO.hours = 8;
                } else if (calendarDayHoursDTO.type == CalendarTypeDayDTO.NOT_WORKING) {
                    calendarDayHoursDTO.hours = 0;
                } else if (calendarDayHoursDTO.type == CalendarTypeDayDTO.DEFAULT) {

                    // TODO Grab the ones form default
                    calendarDayHoursDTO.hours = 0;
                }
                calendarDayHoursDTO.minutes = 0;

            }
            calendarDaysHourDTOs.add(calendarDayHoursDTO);
        }

        calendarDataDTO.hoursPerDays = calendarDaysHourDTOs;

        return calendarDataDTO;
    }

    private static CalendarTypeDayDTO toCalendarTypeDayDTO(DayType dayType) {

        switch (dayType) {

        case DEFAULT:
            return CalendarTypeDayDTO.DEFAULT;

        case NON_WORKING:
            return CalendarTypeDayDTO.NOT_WORKING;

        case WORKING:
            return CalendarTypeDayDTO.WORKING;

        default:
            return null;

        }

    }

    /**
     * Get the number of hours of a ProjectCalendarHours.
     *
     * @param projectCalendarDateRanges
     *            ProjectCalendarDateRanges to extract data from.
     * @return Integer  with the total number of hours or null if the projectCalendarHours is null.
     */
    private static List<Integer> toHours(ProjectCalendarDateRanges projectCalendarDateRanges) {

        if (projectCalendarDateRanges != null) {

            List<Integer> duration = new ArrayList<>();

            int hours = 0;

            int minutes = 0;

            for (DateRange dateRange : projectCalendarDateRanges) {

                DateTime start = new DateTime(dateRange.getStart());

                DateTime end = new DateTime(dateRange.getEnd());

                Period period = new Period(start, end);

                int days = period.getDays();

                if (period.getDays() != 0) {
                    hours += 24 * days;
                }

                hours += period.getHours();

                minutes += period.getMinutes();
            }

            duration.add(hours);

            duration.add(minutes);

            return duration;

        } else {
            return null;
        }
    }

    /**
     * Converts a ProjectFile into a {@link OrderDTO}.
     * Assumes that the ProjectFile comes for a .planner file.
     *
     * @param file
     *            ProjectFile to extract data from.
     * @return ImportData with the data that we want to import.
     */
    private static OrderDTO getImportDataFromPlanner(ProjectFile file, String filename) {

        OrderDTO importData = new OrderDTO();

        mapTask = new HashMap<>();

        importData.name = filename.substring(0, filename.length() - 8/* ".planner" */);

        properties = file.getProjectProperties();

        importData.startDate = properties.getStartDate();

        importData.tasks = getImportTasks(file.getChildTasks());

        importData.milestones = getImportMilestones(file.getChildTasks());

        // MPXJ don't provide a deadline for the project so we take the finish date
        importData.deadline = properties.getFinishDate();

        importData.dependencies = createDependencies();

        importData.calendarName = file.getBaselineCalendar().getName();

        return importData;

    }

    /**
     * Uses the map mapTask to create the list of {@link DependencyDTO}.
     *
     * @return List<DependencyDTO>
     *            List with all the dependencies
     */
    private static List<DependencyDTO> createDependencies() {

        List<DependencyDTO> dependencies = new ArrayList<>();

        List<Relation> successors;

        Task task;

        DependencyDTO dependencyDTO;

        for (Map.Entry<Task, IHasTaskAssociated> mapEntry : mapTask.entrySet()) {

            task = mapEntry.getKey();

            successors = task.getSuccessors();

            if (successors != null) {

                for (Relation successor : successors) {

                    dependencyDTO = new DependencyDTO();

                    dependencyDTO.origin = mapEntry.getValue();

                    dependencyDTO.destination = mapTask.get(successor.getTargetTask());

                    dependencyDTO.type = toDependencyDTOType(successor.getType());

                    dependencies.add(dependencyDTO);

                }

            }

        }

        return dependencies;

    }

    /**
     * Mapping between LP and MPXJ relationships.
     *
     * @param type
     *            MPXJ RelationType to map.
     * @return TypeOfDependencyDTO
     *            Type of the dependency for DependencyDTO
     */
    private static TypeOfDependencyDTO toDependencyDTOType(RelationType type) {

        switch (type) {

        case FINISH_FINISH:
            return TypeOfDependencyDTO.END_END;

        case FINISH_START:
            return TypeOfDependencyDTO.END_START;

        case START_FINISH:
            return TypeOfDependencyDTO.START_END;

        case START_START:
            return TypeOfDependencyDTO.START_START;

        default:
            return null;

        }
    }

    /**
     * Converts a ProjectFile into a {@link OrderDTO}.
     * Assumes that the ProjectFile comes for a .mpp file.
     *
     * @param file
     *            ProjectFile to extract data from.
     * @return ImportData with the data that we want to import.
     */
    private static OrderDTO getImportDataFromMPP(ProjectFile file, String filename) {

        OrderDTO importData = new OrderDTO();

        mapTask = new HashMap<>();

        properties = file.getProjectProperties();

        importData.startDate = properties.getStartDate();

        // MPXJ doesn't provide a deadline for the project so we take the finish date
        importData.deadline = properties.getFinishDate();

        for (Task task : file.getChildTasks()) {
            // Projects are represented as a level 0 task with all real task as its children.
            // Ignore all other top level tasks.
            // See http://mpxj.sourceforge.net/faq.html#extra-tasks-and-resources
            if (!task.getChildTasks().isEmpty()) {

                String name = task.getName();

                if (name != null) {

                    importData.name = name;

                } else {
                    // Take the filename if the project name is not set
                    importData.name = filename.substring(0, filename.length() - 4 /* ".mpp" */ );

                }

                importData.tasks = getImportTasks(task.getChildTasks());

                importData.milestones = getImportMilestones(task.getChildTasks());

                importData.calendarName = file.getDefaultCalendar().getName();

                break;
            }

        }

        importData.dependencies = createDependencies();

        return importData;
    }

    /**
     * Converts a List of MPXJ Tasks into a List of {@link MilestoneDTO}.
     *
     * @param childTasks
     *            List of MPXJ Tasks to extract data from.
     * @return List<MilestoneDTO> List of MilestoneDTO with the data that we want to
     *         import.
     */
    private static List<MilestoneDTO> getImportMilestones(List<Task> childTasks) {

        List<MilestoneDTO> milestones = new ArrayList<>();

        for (Task task : childTasks) {

            if (task.getMilestone()) {

                MilestoneDTO milestone = getMilestoneData(task);

                mapTask.put(task, milestone);

                milestones.add(milestone);

            }
        }

        return milestones;
    }

    /**
     * Converts a MPXJ Task into a {@link MilestoneDTO}.
     *
     * @param task
     *            MPXJ Task to extract data from.
     * @return MilestoneDTO MilestoneDTO with the data that we want to import.
     */
    private static MilestoneDTO getMilestoneData(Task task) {

        MilestoneDTO milestone = new MilestoneDTO();

        milestone.name = task.getName();

        milestone.startDate = task.getStart();

        toLibreplanConstraint(task);

        milestone.constraint = constraint;

        milestone.constraintDate = constraintDate;

        return milestone;

    }

    /**
     * Converts the Duration into an integer that represent hours.
     *
     * @param duration
     *            Duration to convert.
     * @param properties
     *            ProjectProperties needed to convert
     * @return int Integer with the rounded duration in hours
     */
    private static int durationToIntHours(Duration duration, ProjectProperties properties) {
        Duration durationInHours = duration.convertUnits(TimeUnit.HOURS, properties);
        return (int) Math.floor(durationInHours.getDuration());
    }

    /**
     * Converts a List of MPXJ Tasks into a List of {@link OrderElementDTO}.
     *
     * @param tasks
     *            List of MPXJ Tasks to extract data from.
     * @return List<OrderElementDTO> List of ImportTask with the data that we want to import.
     */
    private static List<OrderElementDTO> getImportTasks(List<Task> tasks) {

        List<OrderElementDTO> importTasks = new ArrayList<>();

        for (Task task : tasks) {

            if (!task.getMilestone()) {

                OrderElementDTO importTask = getTaskData(task);

                importTask.children = getImportTasks(task.getChildTasks());

                importTask.milestones = getImportMilestones(task.getChildTasks());

                // This is because in MPXJ only MPP9 files have this attribute
                if (task.getCalendar() != null) {

                    importTask.calendarName = task.getCalendar().getName();

                } else {

                    importTask.calendarName = null;

                }

                mapTask.put(task, importTask);

                importTasks.add(importTask);

            }
        }

        return importTasks;

    }

    /**
     * Converts a MPXJ Task into a {@link OrderElementDTO}.
     *
     * @param task
     *            MPXJ Task to extract data from.
     * @return OrderElementDTO OrderElementDTO with the data that we want to import.
     */
    private static OrderElementDTO getTaskData(Task task) {

        OrderElementDTO importTask = new OrderElementDTO();

        importTask.name = task.getName();

        importTask.startDate = task.getStart();

        importTask.endDate = task.getFinish();

        importTask.totalHours = durationToIntHours(task.getDuration(), properties);

        importTask.deadline = task.getDeadline();

        toLibreplanConstraint(task);

        importTask.constraint = constraint;

        importTask.constraintDate = constraintDate;

        return importTask;

    }

    private static ConstraintDTO constraint;

    private static Date constraintDate;

    /**
     * Set the attributes constraint y constraintDate with the correct value.
     *
     * Because MPXJ has more types of constraints than Libreplan we had
     * choose to convert some of them.
     *
     * @param task
     *            MPXJ Task to extract data from.
     */
    private static void toLibreplanConstraint(Task task) {

        switch (task.getConstraintType()) {

        case AS_SOON_AS_POSSIBLE:
            constraint = ConstraintDTO.AS_SOON_AS_POSSIBLE;
            constraintDate = task.getConstraintDate();
            return;

        case AS_LATE_AS_POSSIBLE:
            constraint = ConstraintDTO.AS_LATE_AS_POSSIBLE;
            constraintDate = task.getConstraintDate();
            return;

        case MUST_START_ON:
            constraint = ConstraintDTO.START_IN_FIXED_DATE;
            constraintDate = task.getConstraintDate();
            return;

        case MUST_FINISH_ON:
            constraint = ConstraintDTO.START_IN_FIXED_DATE;
            constraintDate = recalculateConstraintDateMin(task);
            return;

        case START_NO_EARLIER_THAN:
            constraint = ConstraintDTO.START_NOT_EARLIER_THAN;
            constraintDate = task.getConstraintDate();
            return;

        case START_NO_LATER_THAN:
            constraint = ConstraintDTO.FINISH_NOT_LATER_THAN;
            constraintDate = recalculateConstraintDateSum(task);
            return;

        case FINISH_NO_EARLIER_THAN:
            constraint = ConstraintDTO.START_NOT_EARLIER_THAN;
            constraintDate = recalculateConstraintDateMin(task);
            return;

        case FINISH_NO_LATER_THAN:
            constraint = ConstraintDTO.FINISH_NOT_LATER_THAN;
            constraintDate = task.getConstraintDate();
            return;

        default:
            break;
        }

    }

    /**
     * Get the new date based on the task date adding duration.
     *
     * @param task
     *            MPXJ Task to extract data from.
     * @return Date new recalculated date
     */
    private static Date recalculateConstraintDateSum(Task task) {

        return new Date(task.getConstraintDate().getTime()
                + (durationToIntHours(task.getDuration(), properties) * 60 * 60 * 1000));
    }

    /**
     * Get the new date based on the task date and substracting duration.
     *
     * @param task
     *            MPXJ Task to extract data from.
     * @return Date new recalculated date
     */
    private static Date recalculateConstraintDateMin(Task task) {

        return new Date(task.getConstraintDate().getTime()
                - (durationToIntHours(task.getDuration(), properties) * 60 * 60 * 1000));
    }
}