org.projectforge.web.task.TaskTreeBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.projectforge.web.task.TaskTreeBuilder.java

Source

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2013 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.web.task;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.table.HeadersToolbar;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.NoRecordsToolbar;
import org.apache.wicket.extensions.markup.html.repeater.tree.AbstractTree;
import org.apache.wicket.extensions.markup.html.repeater.tree.TableTree;
import org.apache.wicket.extensions.markup.html.repeater.tree.content.Folder;
import org.apache.wicket.extensions.markup.html.repeater.tree.table.NodeBorder;
import org.apache.wicket.extensions.markup.html.repeater.tree.table.NodeModel;
import org.apache.wicket.extensions.markup.html.repeater.tree.table.TreeColumn;
import org.apache.wicket.extensions.markup.html.repeater.tree.theme.WindowsTheme;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.OddEvenItem;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.projectforge.access.AccessChecker;
import org.projectforge.fibu.AuftragsPositionVO;
import org.projectforge.registry.Registry;
import org.projectforge.task.TaskDao;
import org.projectforge.task.TaskFilter;
import org.projectforge.task.TaskNode;
import org.projectforge.task.TaskTree;
import org.projectforge.user.ProjectForgeGroup;
import org.projectforge.user.UserGroupCache;
import org.projectforge.web.calendar.DateTimeFormatter;
import org.projectforge.web.core.PriorityFormatter;
import org.projectforge.web.fibu.ISelectCallerPage;
import org.projectforge.web.fibu.OrderPositionsPanel;
import org.projectforge.web.user.UserFormatter;
import org.projectforge.web.user.UserPropertyColumn;
import org.projectforge.web.wicket.AbstractListPage;
import org.projectforge.web.wicket.AbstractSecuredPage;
import org.projectforge.web.wicket.CellItemListener;
import org.projectforge.web.wicket.CellItemListenerPropertyColumn;
import org.projectforge.web.wicket.DatePropertyColumn;
import org.projectforge.web.wicket.ListSelectActionPanel;

/**
 * @author Kai Reinhard (k.reinhard@micromata.de)
 * 
 */
public class TaskTreeBuilder implements Serializable {
    private static final long serialVersionUID = -2425308275690643856L;

    private final Behavior theme = new WindowsTheme();

    private Integer highlightedTaskNodeId;

    private boolean selectMode, showRootNode, showCost, showOrders;

    private AccessChecker accessChecker;

    private TaskFormatter taskFormatter;

    private PriorityFormatter priorityFormatter;

    private UserFormatter userFormatter;

    private DateTimeFormatter dateTimeFormatter;

    private UserGroupCache userGroupCache;

    private TableTree<TaskNode, String> tree;

    private AbstractSecuredPage parentPage;

    private ISelectCallerPage caller;

    private String selectProperty;

    /**
     * @param id
     */
    public TaskTreeBuilder() {
    }

    @SuppressWarnings("serial")
    public AbstractTree<TaskNode> createTree(final String id, final AbstractSecuredPage parentPage,
            final TaskFilter taskFilter) {
        this.parentPage = parentPage;
        final List<IColumn<TaskNode, String>> columns = createColumns();

        tree = new TableTree<TaskNode, String>(id, columns,
                new TaskTreeProvider(taskFilter).setShowRootNode(showRootNode), Integer.MAX_VALUE,
                TaskTreeExpansion.getExpansionModel()) {
            private static final long serialVersionUID = 1L;

            @Override
            protected Component newContentComponent(final String id, final IModel<TaskNode> model) {
                return TaskTreeBuilder.this.newContentComponent(id, this, model);
            }

            @Override
            protected Item<TaskNode> newRowItem(final String id, final int index, final IModel<TaskNode> model) {
                return new OddEvenItem<TaskNode>(id, index, model);
            }
        };
        tree.getTable().addTopToolbar(new HeadersToolbar<String>(tree.getTable(), null));
        tree.getTable().addBottomToolbar(new NoRecordsToolbar(tree.getTable()));
        tree.add(new Behavior() {
            @Override
            public void onComponentTag(final Component component, final ComponentTag tag) {
                theme.onComponentTag(component, tag);
            }

            @Override
            public void renderHead(final Component component, final IHeaderResponse response) {
                theme.renderHead(component, response);
            }
        });
        tree.getTable().add(AttributeModifier.append("class", "tableTree"));
        return tree;
    }

    /**
     * @return
     */
    @SuppressWarnings("serial")
    private List<IColumn<TaskNode, String>> createColumns() {
        final TaskTree taskTree = getTaskTree();
        final CellItemListener<TaskNode> cellItemListener = new CellItemListener<TaskNode>() {
            public void populateItem(final Item<ICellPopulator<TaskNode>> item, final String componentId,
                    final IModel<TaskNode> rowModel) {
                final TaskNode taskNode = rowModel.getObject();
                TaskListPage.appendCssClasses(item, taskNode.getTask(), highlightedTaskNodeId);
            }
        };
        final List<IColumn<TaskNode, String>> columns = new ArrayList<IColumn<TaskNode, String>>();

        columns.add(new TreeColumn<TaskNode, String>(new ResourceModel("task")) {
            @Override
            public void populateItem(final Item<ICellPopulator<TaskNode>> cellItem, final String componentId,
                    final IModel<TaskNode> rowModel) {
                final RepeatingView view = new RepeatingView(componentId);
                cellItem.add(view);
                final TaskNode taskNode = rowModel.getObject();
                if (selectMode == false) {
                    view.add(new ListSelectActionPanel(view.newChildId(), rowModel, TaskEditPage.class,
                            taskNode.getId(), parentPage, ""));
                } else {
                    view.add(new ListSelectActionPanel(view.newChildId(), rowModel, caller, selectProperty,
                            taskNode.getId(), ""));
                }
                AbstractListPage.addRowClick(cellItem);
                final NodeModel<TaskNode> nodeModel = (NodeModel<TaskNode>) rowModel;
                final Component nodeComponent = getTree().newNodeComponent(view.newChildId(),
                        nodeModel.getWrappedModel());
                nodeComponent.add(new NodeBorder(nodeModel.getBranches()));
                view.add(nodeComponent);
                cellItemListener.populateItem(cellItem, componentId, rowModel);
            }
        });
        columns.add(new CellItemListenerPropertyColumn<TaskNode>(new ResourceModel("task.consumption"), null,
                "task", cellItemListener) {
            @Override
            public void populateItem(final Item<ICellPopulator<TaskNode>> item, final String componentId,
                    final IModel<TaskNode> rowModel) {
                final TaskNode node = rowModel.getObject();
                item.add(TaskListPage.getConsumptionBarPanel(tree, componentId, getTaskTree(), selectMode, node));
                cellItemListener.populateItem(item, componentId, rowModel);
            }
        });
        if (showCost == true) {
            columns.add(new CellItemListenerPropertyColumn<TaskNode>(new ResourceModel("fibu.kost2"), null,
                    "task.kost2", cellItemListener) {
                @Override
                public void populateItem(final Item<ICellPopulator<TaskNode>> item, final String componentId,
                        final IModel<TaskNode> rowModel) {
                    final Label label = TaskListPage.getKostLabel(componentId, getTaskTree(),
                            rowModel.getObject().getTask());
                    item.add(label);
                    cellItemListener.populateItem(item, componentId, rowModel);
                }
            });
        }
        if (taskTree.hasOrderPositionsEntries() == true && showOrders == true) {
            columns.add(new CellItemListenerPropertyColumn<TaskNode>(new ResourceModel("fibu.auftrag.auftraege"),
                    null, null, cellItemListener) {
                @Override
                public void populateItem(final Item<ICellPopulator<TaskNode>> item, final String componentId,
                        final IModel<TaskNode> rowModel) {
                    final TaskNode taskNode = rowModel.getObject();
                    final Set<AuftragsPositionVO> orderPositions = taskTree
                            .getOrderPositionEntries(taskNode.getId());
                    if (CollectionUtils.isEmpty(orderPositions) == true) {
                        final Label label = new Label(componentId, ""); // Empty label.
                        item.add(label);
                    } else {
                        final OrderPositionsPanel orderPositionsPanel = new OrderPositionsPanel(componentId) {
                            @Override
                            protected void onBeforeRender() {
                                super.onBeforeRender();
                                // Lazy initialization because getString(...) of OrderPositionsPanel fails if panel.init(orderPositions) is called directly
                                // after instantiation.
                                init(orderPositions);
                            };
                        };
                        item.add(orderPositionsPanel);
                    }
                    cellItemListener.populateItem(item, componentId, rowModel);
                }
            });
        }
        columns.add(new CellItemListenerPropertyColumn<TaskNode>(new ResourceModel("shortDescription"), null,
                "task.shortDescription", cellItemListener));
        if (accessChecker.isLoggedInUserMemberOfGroup(ProjectForgeGroup.FINANCE_GROUP) == true) {
            columns.add(new DatePropertyColumn<TaskNode>(dateTimeFormatter,
                    parentPage.getString("task.protectTimesheetsUntil.short"), null, "task.protectTimesheetsUntil",
                    cellItemListener));
        }
        columns.add(new CellItemListenerPropertyColumn<TaskNode>(new ResourceModel("task.reference"), null,
                "reference", cellItemListener));
        columns.add(new CellItemListenerPropertyColumn<TaskNode>(new ResourceModel("priority"), null, "priority",
                cellItemListener) {
            @Override
            public void populateItem(final Item<ICellPopulator<TaskNode>> item, final String componentId,
                    final IModel<TaskNode> rowModel) {
                final Label label = TaskListPage.getPriorityLabel(componentId, priorityFormatter,
                        rowModel.getObject().getTask());
                item.add(label);
                cellItemListener.populateItem(item, componentId, rowModel);
            }
        });
        columns.add(new CellItemListenerPropertyColumn<TaskNode>(new ResourceModel("task.status"), null, "status",
                cellItemListener) {
            @Override
            public void populateItem(final Item<ICellPopulator<TaskNode>> item, final String componentId,
                    final IModel<TaskNode> rowModel) {
                final Label label = TaskListPage.getStatusLabel(componentId, taskFormatter,
                        rowModel.getObject().getTask());
                item.add(label);
                cellItemListener.populateItem(item, componentId, rowModel);
            }
        });
        final UserPropertyColumn<TaskNode> userPropertyColumn = new UserPropertyColumn<TaskNode>(
                parentPage.getString("task.assignedUser"), null, "task.responsibleUserId", cellItemListener)
                        .withUserFormatter(userFormatter).setUserGroupCache(userGroupCache);
        columns.add(userPropertyColumn);
        return columns;
    }

    protected void addColumn(final WebMarkupContainer parent, final Component component, final String cssStyle) {
        if (cssStyle != null) {
            component.add(AttributeModifier.append("style", new Model<String>(cssStyle)));
        }
        parent.add(component);
    }

    /**
     * @param id
     * @param model
     * @return
     */
    @SuppressWarnings("serial")
    protected Component newContentComponent(final String id, final TableTree<TaskNode, String> tree,
            final IModel<TaskNode> model) {
        return new Folder<TaskNode>(id, tree, model) {

            @Override
            protected IModel<?> newLabelModel(final IModel<TaskNode> model) {
                return new PropertyModel<String>(model, "task.title");
            }
        };
    }

    /**
     * @param selectMode the selectMode to set
     * @return this for chaining.
     */
    public TaskTreeBuilder setSelectMode(final boolean selectMode) {
        this.selectMode = selectMode;
        return this;
    }

    /**
     * @param showRootNode the showRootNode to set
     * @return this for chaining.
     */
    public TaskTreeBuilder setShowRootNode(final boolean showRootNode) {
        this.showRootNode = showRootNode;
        return this;
    }

    /**
     * @param showCost the showCost to set
     * @return this for chaining.
     */
    public TaskTreeBuilder setShowCost(final boolean showCost) {
        this.showCost = showCost;
        return this;
    }

    /**
     * @param showOrders the showOrders to set
     * @return this for chaining.
     */
    public TaskTreeBuilder setShowOrders(final boolean showOrders) {
        this.showOrders = showOrders;
        return this;
    }

    public TaskTreeBuilder set(final AccessChecker accessChecker, final TaskDao taskDao,
            final TaskFormatter taskFormatter, final PriorityFormatter priorityFormatter,
            final UserFormatter userFormatter, final DateTimeFormatter dateTimeFormatter,
            final UserGroupCache userGroupCache) {
        this.accessChecker = accessChecker;
        this.taskFormatter = taskFormatter;
        this.priorityFormatter = priorityFormatter;
        this.userFormatter = userFormatter;
        this.dateTimeFormatter = dateTimeFormatter;
        this.userGroupCache = userGroupCache;
        this.dateTimeFormatter = dateTimeFormatter;
        return this;
    }

    /**
     * @param caller the caller to set
     * @return this for chaining.
     */
    public TaskTreeBuilder setCaller(final ISelectCallerPage caller) {
        this.caller = caller;
        return this;
    }

    /**
     * @param selectProperty the selectProperty to set
     * @return this for chaining.
     */
    public TaskTreeBuilder setSelectProperty(final String selectProperty) {
        this.selectProperty = selectProperty;
        return this;
    }

    /**
     * @param highlightedTaskNodeId the highlightedTaskNodeId to set
     * @return this for chaining.
     */
    public TaskTreeBuilder setHighlightedTaskNodeId(final Integer highlightedTaskNodeId) {
        this.highlightedTaskNodeId = highlightedTaskNodeId;
        final TaskNode node = getTaskTree().getTaskNodeById(highlightedTaskNodeId);
        if (node == null) {
            // Shouldn't occur.
            return this;
        }
        // Open all ancestor nodes of the highlighted node:
        final Set<TaskNode> set = TaskTreeExpansion.getExpansionModel().getObject();
        TaskNode parent = node.getParent();
        while (parent != null) {
            set.add(parent);
            parent = parent.getParent();
        }
        return this;
    }

    private TaskTree getTaskTree() {
        return Registry.instance().getTaskTree();
    }
}