Package org.projectforge.gantt

Source Code of org.projectforge.gantt.GanttTaskImpl

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition 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 General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.gantt;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.projectforge.common.DateHolder;
import org.projectforge.common.Matcher;
import org.projectforge.common.NumberHelper;

public class GanttTaskImpl implements GanttTask, Serializable
{
  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(GanttTaskImpl.class);

  private static final long serialVersionUID = -2948691380516113581L;

  /**
   * Maximum supported depth (independent from any display algorithm). This value is only used for the detection of cyclic references!
   */
  public static int MAX_DEPTH = 50;

  private Integer id;

  private Integer predecessorOffset;

  private GanttRelationType relationType;

  private GanttTask predecessor;

  private String description;

  private BigDecimal duration;

  private Date endDate;

  private Date startDate;

  private Integer progress;

  private String title;

  private GanttObjectType type;

  private String workpackageCode;

  private List<GanttTask> children;

  private boolean visible = false;

  private transient Date calculatedStartDate;

  private transient boolean startDateCalculated;

  private transient Date calculatedEndDate;

  private transient boolean endDateCalculated;

  public GanttTaskImpl()
  {
  }

  public GanttTaskImpl(final Integer id)
  {
    this.id = id;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getId()
   */
  public Serializable getId()
  {
    return this.id;
  }

  public GanttTaskImpl setId(final Serializable id)
  {
    this.id = (Integer) id;
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getPredecessorOffset()
   */
  public Integer getPredecessorOffset()
  {
    return predecessorOffset;
  }

  public GanttTaskImpl setPredecessorOffset(final Integer predecessorOffset)
  {
    this.predecessorOffset = predecessorOffset;
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getRelationType()
   */
  public GanttRelationType getRelationType()
  {
    return relationType;
  }

  public GanttTaskImpl setRelationType(GanttRelationType relationType)
  {
    this.relationType = relationType;
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getPredecessor()
   */
  public GanttTask getPredecessor()
  {
    return predecessor;
  }

  public GanttTaskImpl setPredecessor(GanttTask predecessor)
  {
    this.predecessor = predecessor;
    return this;
  }

  public Serializable getPredecessorId()
  {
    if (this.predecessor == null) {
      return null;
    }
    return this.predecessor.getId();
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getDescription()
   */
  public String getDescription()
  {
    return description;
  }

  public GanttTaskImpl setDescription(String description)
  {
    this.description = description;
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getDuration()
   */
  public BigDecimal getDuration()
  {
    return duration;
  }

  public GanttTaskImpl setDuration(final BigDecimal duration)
  {
    this.duration = duration;
    this.startDateCalculated = this.endDateCalculated = false; // Force recalculation (also taking the children into account)
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getEndDate()
   */
  public Date getEndDate()
  {
    return endDate;
  }

  public GanttTaskImpl setEndDate(Date endDate)
  {
    this.endDate = endDate;
    this.startDateCalculated = this.endDateCalculated = false; // Force recalculation (also taking the children into account)
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getStartDate()
   */
  public Date getStartDate()
  {
    return startDate;
  }

  public GanttTaskImpl setStartDate(Date startDate)
  {
    this.startDate = startDate;
    this.startDateCalculated = this.endDateCalculated = false; // Force recalculation (also taking the children into account)
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getTitle()
   */
  public String getTitle()
  {
    return title;
  }

  public GanttTaskImpl setTitle(String title)
  {
    this.title = title;
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getType()
   */
  public GanttObjectType getType()
  {
    return type;
  }

  public GanttTaskImpl setType(GanttObjectType type)
  {
    this.type = type;
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getWorkpackageCode()
   */
  public String getWorkpackageCode()
  {
    return workpackageCode;
  }

  public GanttTaskImpl setWorkpackageCode(String workpackageCode)
  {
    this.workpackageCode = workpackageCode;
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getChildren()
   */
  public List<GanttTask> getChildren()
  {
    return this.children;
  }

  /**
   * Sort all children by calculated start date.
   * @see org.projectforge.gantt.GanttTask#sortChildren()
   */
  public void sortChildren()
  {
    if (this.children == null) {
      return;
    }
    Collections.sort(this.children, GanttUtils.GANTT_OBJECT_COMPARATOR);
    for (final GanttTask child : this.children) {
      child.sortChildren();
    }
  }

  /**
   *
   * @see org.projectforge.gantt.GanttTask#addChild(org.projectforge.gantt.GanttTask)
   */
  public GanttTaskImpl addChild(final GanttTask child)
  {
    if (this.children == null) {
      this.children = new ArrayList<GanttTask>();
    }
    this.children.add(child);
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#removeChild(org.projectforge.gantt.GanttTask)
   */
  @Override
  public void removeChild(final GanttTask ganttObject)
  {
    if (this.children == null) {
      log.error("Can't remove child object because current Gantt activity has no children: " + this);
    } else if (this.children.remove(ganttObject) == false) {
      log.error("Can't remove child object: " + ganttObject + " because it's not a child of the given activity: " + this);
    }
  }

  /**
   * @see org.projectforge.gantt.GanttTask#hasDuration()
   */
  public boolean hasDuration()
  {
    if (getCalculatedStartDate() != null && getCalculatedEndDate() != null) {
      final DateHolder dh = new DateHolder(this.calculatedStartDate);
      return dh.isSameDay(getCalculatedEndDate()) == false;
    }
    return !NumberHelper.isZeroOrNull(this.duration);
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getCalculatedStartDate()
   */
  public Date getCalculatedStartDate()
  {
    if (startDateCalculated == false) {
      calculatedStartDate = GanttUtils.getCalculatedStartDate(this);
      startDateCalculated = true;
    }
    return this.calculatedStartDate;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#setCalculatedStartDate(java.util.Date)
   */
  @Override
  public GanttTaskImpl setCalculatedStartDate(Date calculatedStartDate)
  {
    this.calculatedStartDate = calculatedStartDate;
    return this;
  }

  /**
   *
   * @see org.projectforge.gantt.GanttTask#getCalculatedEndDate()
   */
  public Date getCalculatedEndDate()
  {
    if (endDateCalculated == false) {
      calculatedEndDate = GanttUtils.getCalculatedEndDate(this);
      endDateCalculated = true;
    }
    return this.calculatedEndDate;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#setCalculatedEndDate(java.util.Date)
   */
  @Override
  public GanttTaskImpl setCalculatedEndDate(Date calculatedEndDate)
  {
    this.calculatedEndDate = calculatedEndDate;
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#isStartDateCalculated()
   */
  @Override
  public boolean isStartDateCalculated()
  {
    return this.startDateCalculated == true;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#setStartDateCalculated(boolean)
   */
  @Override
  public GanttTaskImpl setStartDateCalculated(boolean startDateCalculated)
  {
    this.startDateCalculated = startDateCalculated;
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#isEndDateCalculated()
   */
  @Override
  public boolean isEndDateCalculated()
  {
    return this.endDateCalculated;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#setEndDateCalculated(boolean)
   */
  @Override
  public GanttTaskImpl setEndDateCalculated(boolean isEndDateCalculated)
  {
    this.endDateCalculated = isEndDateCalculated;
    return this;
  }

  /**
   * Default: true.
   * @see org.projectforge.gantt.GanttTask#isVisible()
   */
  public boolean isVisible()
  {
    return this.visible;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#setVisible(boolean)
   */
  public GanttTask setVisible(boolean visible)
  {
    this.visible = visible;
    return this;
  }

  /**
   * Sets task visibility and the visibility of all descendants to false.
   */
  public GanttTaskImpl setInvisible()
  {
    this.setVisible(false);
    if (this.children != null) {
      for (GanttTask child : children) {
        ((GanttTaskImpl) child).setInvisible();
      }
    }
    return this;
  }

  /**
   * @see org.projectforge.gantt.GanttTask#getProgress()
   */
  public Integer getProgress()
  {
    return progress;
  }

  public GanttTaskImpl setProgress(Integer progress)
  {
    this.progress = progress;
    return this;
  }

  /**
   * Sets the calculated start and end dates (including the children) to null (recalculation is forced when calculated time will be needed). <br/>
   * Please note: The calculation is only done at the first usage.
   */
  public GanttTaskImpl recalculate()
  {
    this.calculatedStartDate = this.calculatedEndDate = null;
    this.startDateCalculated = this.endDateCalculated = false;
    if (this.children != null) {
      for (final GanttTask child : this.children) {
        ((GanttTaskImpl) child).recalculate();
      }
    }
    return this;
  }

  /**
   * Traverses through the child trees.
   * @return true, if no cyclic references are found (everything seems to be OK), otherwise false.
   */
  public boolean checkCyclicReferences()
  {
    return checkCyclicReferences(0);
  }

  private boolean checkCyclicReferences(final int depth)
  {
    if (depth > MAX_DEPTH) {
      // Maximum of allowed depth exceeded.
      return false;
    }
    if (this.children == null) {
      return true;
    }
    for (final GanttTask child : this.children) {
      if (((GanttTaskImpl) child).checkCyclicReferences(depth + 1) == false) {
        return false;
      }
    }
    return true;
  }

  @Override
  public String toString()
  {
    final ToStringBuilder tos = new ToStringBuilder(this);
    tos.append("id", getId());
    tos.append("title", getTitle());
    if (getChildren() != null) {
      tos.append("children", getChildren());
    }
    return tos.toString();
  }

  public GanttTask findBy(final Matcher<GanttTask> matcher, final Object expression)
  {
    if (matcher.match(this, expression) == true) {
      return this;
    }
    if (this.children != null) {
      for (final GanttTask child : this.children) {
        final GanttTask found = child.findBy(matcher, expression);
        if (found != null) {
          return found;
        }
      }
    }
    return null;
  }

  public GanttTask findById(final Serializable id)
  {
    return findBy(new Matcher<GanttTask>() {
      public boolean match(GanttTask object, Object expression)
      {
        return (object.getId() != null && object.getId().equals(expression) == true);
      }
    }, id);
  }

  public GanttTask findByTitle(final String title)
  {
    return findBy(new Matcher<GanttTask>() {
      public boolean match(GanttTask object, Object expression)
      {
        return (StringUtils.equals(object.getTitle(), (String) expression) == true);
      }
    }, title);
  }

  public GanttTask findByWorkpackageCode(String workpackageCode)
  {
    return findBy(new Matcher<GanttTask>() {
      public boolean match(GanttTask object, Object expression)
      {
        return (StringUtils.equals(object.getWorkpackageCode(), (String) expression) == true);
      }
    }, workpackageCode);
  }

  public GanttTask findParent(final Serializable id)
  {
    return findBy(new Matcher<GanttTask>() {
      public boolean match(GanttTask object, Object expression)
      {
        if (CollectionUtils.isEmpty(object.getChildren()) == true) {
          return false;
        }
        for (final GanttTask child : object.getChildren()) {
          if (child.getId() != null && child.getId().equals(expression) == true) {
            return true;
          }
        }
        return false;
      }
    }, id);
  }

  /**
   * Get the next free id for new Gantt tasks to insert (starting with -1). Positive values are reserved for Gantt tasks related to tasks
   * (of ProjectForge's TaskTree) (the id is equals to the task id).
   * @return
   */
  public int getNextId()
  {
    final Integer id = getNextId(this, -1);
    return id != null ? id : -1;
  }

  private Integer getNextId(final GanttTask node, final int id)
  {
    Integer result = null;
    if (node == null) {
      return null;
    }
    if (node.getId() != null && ((Integer) node.getId()) <= id) {
      result = ((Integer) node.getId()) - 1;
    }
    final List<GanttTask> children = node.getChildren();
    if (children == null) {
      return result;
    }
    for (final GanttTask child : children) {
      final Integer i = getNextId(child, id);
      if (i == null) {
        continue;
      }
      if (result != null && i <= result || result == null && i <= id) {
        result = i;
      }
    }
    return result;
  }
}
TOP

Related Classes of org.projectforge.gantt.GanttTaskImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.