/* * This file is part of LibrePlan * * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e * Desenvolvemento Tecnolóxico de Galicia * Copyright (C) 2010-2011 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.resourceload; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.apache.commons.collections4.comparators.NullComparator; import org.apache.commons.lang3.Validate; import org.joda.time.LocalDate; import org.zkoss.ganttz.data.GanttDate; import org.zkoss.ganttz.util.Interval; public class LoadTimeLine { @SuppressWarnings("unchecked") private static final Comparator<GanttDate> nullSafeComparator = new NullComparator<>(false); private final String conceptName; private final List<LoadPeriod> loadPeriods; private final TimeLineRole<?> timeLineRole; private final String type; private final List<LoadTimeLine> children; public LoadTimeLine(String conceptName, List<LoadPeriod> loadPeriods, TimeLineRole<?> role) { Validate.notEmpty(conceptName); Validate.notNull(loadPeriods); this.loadPeriods = LoadPeriod.sort(loadPeriods); this.conceptName = conceptName; this.type = ""; this.timeLineRole = role; this.children = Collections.unmodifiableList(new ArrayList<LoadTimeLine>()); } public LoadTimeLine(String conceptName, List<LoadPeriod> loadPeriods, String type, TimeLineRole<?> role) { Validate.notEmpty(conceptName); Validate.notNull(loadPeriods); this.loadPeriods = LoadPeriod.sort(loadPeriods); this.conceptName = conceptName; this.timeLineRole = role; this.type = type; this.children = Collections.unmodifiableList(new ArrayList<LoadTimeLine>()); } public LoadTimeLine(LoadTimeLine main, List<LoadTimeLine> children) { Validate.notEmpty(main.getConceptName()); Validate.notNull(main.getLoadPeriods()); this.loadPeriods = LoadPeriod.sort(main.getLoadPeriods()); this.conceptName = main.getConceptName(); this.timeLineRole = main.getRole(); this.type = main.getType(); Validate.notNull(children); this.children = Collections.unmodifiableList(new ArrayList<>(children)); } public static Comparator<LoadTimeLine> byStartAndEndDate() { return new Comparator<LoadTimeLine>() { @Override public int compare(LoadTimeLine o1, LoadTimeLine o2) { int result = nullSafeComparator.compare(o1.getStartPeriod(), o2.getStartPeriod()); if ( result == 0 ) { return nullSafeComparator.compare(o1.getEndPeriod(), o2.getEndPeriod()); } return result; } }; } public List<LoadPeriod> getLoadPeriods() { return loadPeriods; } public String getConceptName() { return conceptName; } public TimeLineRole<?> getRole() { return timeLineRole; } private LoadPeriod getFirst() { return loadPeriods.get(0); } private LoadPeriod getLast() { return loadPeriods.get(loadPeriods.size() - 1); } public GanttDate getStartPeriod() { return isEmpty() ? null : getFirst().getStart(); } public boolean isEmpty() { return loadPeriods.isEmpty(); } public GanttDate getEndPeriod() { return isEmpty() ? null : getLast().getEnd(); } public String getType() { return this.type; } public static Interval getIntervalFrom(List<LoadTimeLine> timeLines) { GanttDate start = null; GanttDate end = null; for (LoadTimeLine loadTimeLine : timeLines) { if ( !loadTimeLine.isEmpty() ) { Validate.notNull(loadTimeLine.getStart()); start = min(start, loadTimeLine.getStart()); Validate.notNull(loadTimeLine.getEnd()); end = max(end, loadTimeLine.getEnd()); } } if ( timeLines.isEmpty() || start == null || end == null ) { LocalDate localDateNow = new LocalDate(); return new Interval(localDateNow, localDateNow.plusYears(5)); } return new Interval(start.toLocalDate(), end.asExclusiveEnd()); } private static GanttDate max(GanttDate one, GanttDate other) { if ( one == null ) { return other; } if ( other == null ) { return one; } return one.compareTo(other) > 0 ? one : other; } private static GanttDate min(GanttDate one, GanttDate other) { if ( one == null ) { return other; } if ( other == null ) { return one; } return one.compareTo(other) < 0 ? one : other; } public boolean hasChildren() { return !children.isEmpty(); } public List<LoadTimeLine> getChildren() { return children; } public List<LoadTimeLine> getAllChildren() { List<LoadTimeLine> result = new ArrayList<>(); for (LoadTimeLine child : children) { result.add(child); result.addAll(child.getAllChildren()); } return result; } public GanttDate getStart() { GanttDate result = getStartPeriod(); for (LoadTimeLine loadTimeLine : getChildren()) { GanttDate start = loadTimeLine.getStart(); if ( start != null ) { result = result == null || result.compareTo(start) > 0 ? start : result; } } return result; } public GanttDate getEnd() { GanttDate result = getEndPeriod(); for (LoadTimeLine loadTimeLine : getChildren()) { GanttDate end = loadTimeLine.getEnd(); if ( end != null ) { result = result == null || result.compareTo(end) < 0 ? end : result; } } return result; } }