/* * Copyright 2015 Tomi Virtanen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.tltv.gantt.client.shared; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.tltv.gantt.client.ArrowElement; import com.google.gwt.user.client.rpc.GwtTransient; public class Step extends AbstractStep { private Step predecessor; private List<SubStep> subSteps = new LinkedList<SubStep>(); @GwtTransient transient private Set<SubStepObserverProxy> subStepObserver = new HashSet<SubStepObserverProxy>(); public Step() { } public Step(String caption) { super(caption); } public Step(String caption, CaptionMode captionMode) { super(caption, captionMode); } public Step(String caption, CaptionMode captionMode, SubStep... subSteps) { super(caption, captionMode); addSubSteps(subSteps); } /** Get predecessor step for this step. */ public Step getPredecessor() { return predecessor; } /** * Set predecessor step for this step. Predecessor is visualized by 'arrow' * between the predecessor step and this step. 'Arrow' will be painted * starting from the end of the predecessor step and ends pointing to start * of this step. This relation is editable by default if Gantt is not in * read-only mode. * <p> * Visual look of the arrow can be customized by implementing GWT widget * which implements {@link ArrowElement} interface. * * @param predecessor * Predecesor step */ public void setPredecessor(Step predecessor) { this.predecessor = predecessor; } /** Get unmodifiable list of sub steps in this step. */ public List<SubStep> getSubSteps() { return Collections.unmodifiableList(subSteps); } /** Add new sub step. */ public boolean addSubStep(SubStep subStep) { if (subStep != null) { subStep.setOwner(this); boolean added = subSteps.add(subStep); if (added && subStepObserver != null) { for (SubStepObserverProxy obs : subStepObserver) { obs.onAddSubStep(subStep); } } return added; } return false; } /** Add new sub steps. */ public void addSubSteps(SubStep... subSteps) { if (subSteps != null) { addSubSteps(Arrays.asList(subSteps)); } } /** Add new sub steps. */ public void addSubSteps(List<SubStep> subSteps) { if (subSteps != null) { for (SubStep s : subSteps) { addSubStep(s); } } } /** * Remove given sub-step. Sub step is actually identified by its UID * {@link AbstractStep#getUid()}. */ public boolean removeSubStep(SubStep subStep) { if (subStep == null) { return false; } boolean removed = subSteps.remove(subStep); if (removed && subStepObserver != null) { for (SubStepObserverProxy obs : subStepObserver) { obs.onRemoveSubStep(subStep); } } return removed; } /** Get unmodifiable list of SubStepObservers. */ public Set<SubStepObserverProxy> getSubStepObservers() { return Collections.unmodifiableSet(subStepObserver); } /** * Add new {@link SubStepObserverProxy} for this step. Observer notifies * about structure changes of sub-steps. */ public void addSubStepObserver(SubStepObserverProxy subStepObserver) { this.subStepObserver.add(subStepObserver); } /** Remove {@link SubStepObserverProxy} from this step. */ public void removeSubStepObserver(SubStepObserverProxy subStepObserver) { this.subStepObserver.remove(subStepObserver); } /** Get smallest sub-step start date from this step. */ public long getMinStartDateBySubSteps() { Long min = null; for (SubStep subStep : getSubSteps()) { if (min == null) { min = subStep.getStartDate(); } else { min = Math.min(min, subStep.getStartDate()); } } return min; } /** * Get largest sub-step end date from this step. */ public long getMaxEndDateBySubSteps() { Long max = null; for (SubStep subStep : getSubSteps()) { if (max == null) { max = subStep.getEndDate(); } else { max = Math.max(max, subStep.getEndDate()); } } return max; } }