001/*
002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Anahide Tchertchian
016 */
017package org.nuxeo.ecm.platform.task.providers;
018
019import java.io.Serializable;
020import java.util.ArrayList;
021import java.util.List;
022import java.util.Locale;
023import java.util.Map;
024
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.nuxeo.ecm.core.api.CoreSession;
028import org.nuxeo.ecm.core.api.DocumentModel;
029import org.nuxeo.ecm.core.api.LifeCycleConstants;
030import org.nuxeo.ecm.core.api.NuxeoException;
031import org.nuxeo.ecm.core.api.NuxeoPrincipal;
032import org.nuxeo.ecm.platform.query.api.AbstractPageProvider;
033import org.nuxeo.ecm.platform.query.api.PageProvider;
034import org.nuxeo.ecm.platform.task.Task;
035import org.nuxeo.ecm.platform.task.TaskService;
036import org.nuxeo.ecm.platform.task.dashboard.DashBoardItem;
037import org.nuxeo.ecm.platform.task.dashboard.DashBoardItemImpl;
038import org.nuxeo.runtime.api.Framework;
039
040/**
041 * Page provider for {@link DashBoardItem} elements.
042 * <p>
043 * Useful for content views displaying users' tasks.
044 * <p>
045 * WARNING: this page provider does not handle sorting, and its pagination management is not efficient (done in post
046 * filter).
047 * <p>
048 * This page provider requires the property {@link #CORE_SESSION_PROPERTY} to be filled with a core session. It also
049 * accepts an optional property {@link #FILTER_DOCS_FROM_TRASH}, defaulting to true.
050 *
051 * @since 5.5
052 */
053public class UserTaskPageProvider extends AbstractPageProvider<DashBoardItem> implements PageProvider<DashBoardItem> {
054
055    private static final long serialVersionUID = 1L;
056
057    private static final Log log = LogFactory.getLog(UserTaskPageProvider.class);
058
059    public static final String CORE_SESSION_PROPERTY = "coreSession";
060
061    public static final String FILTER_DOCS_FROM_TRASH = "filterDocumentsFromTrash";
062
063    protected List<DashBoardItem> userTasks;
064
065    protected List<DashBoardItem> pageTasks;
066
067    @Override
068    public List<DashBoardItem> getCurrentPage() {
069        if (pageTasks == null) {
070            pageTasks = new ArrayList<DashBoardItem>();
071            if (userTasks == null) {
072                getAllTasks();
073            }
074            if (!hasError()) {
075                long resultsCount = userTasks.size();
076                setResultsCount(resultsCount);
077                // post-filter the results "by hand" to handle pagination
078                long pageSize = getMinMaxPageSize();
079                if (pageSize == 0) {
080                    pageTasks.addAll(userTasks);
081                } else {
082                    // handle offset
083                    long offset = getCurrentPageOffset();
084                    if (offset <= resultsCount) {
085                        for (int i = Long.valueOf(offset).intValue(); i < resultsCount && i < offset + pageSize; i++) {
086                            pageTasks.add(userTasks.get(i));
087                        }
088                    }
089                }
090            }
091        }
092        return pageTasks;
093    }
094
095    protected Locale getLocale() {
096        String locale = (String) getProperties().get("locale");
097        if (locale != null) {
098            return new Locale(locale);
099        }
100        return null;
101    }
102
103    protected void getAllTasks() {
104        error = null;
105        errorMessage = null;
106        userTasks = new ArrayList<DashBoardItem>();
107        CoreSession coreSession = getCoreSession();
108        boolean filterTrashDocs = getFilterDocumentsInTrash();
109        NuxeoPrincipal pal = (NuxeoPrincipal) coreSession.getPrincipal();
110        TaskService taskService = Framework.getService(TaskService.class);
111        List<Task> tasks = taskService.getAllCurrentTaskInstances(coreSession, getSortInfos());
112        if (tasks != null) {
113            for (Task task : tasks) {
114                if (task.hasEnded() || task.isCancelled()) {
115                    continue;
116                }
117                DocumentModel doc = taskService.getTargetDocumentModel(task, coreSession);
118                if (doc != null) {
119                    if (filterTrashDocs && LifeCycleConstants.DELETED_STATE.equals(doc.getCurrentLifeCycleState())) {
120                        continue;
121                    } else {
122                        userTasks.add(new DashBoardItemImpl(task, doc, getLocale()));
123                    }
124                } else {
125                    log.warn(String.format("User '%s' has a task of type '%s' on a " + "missing or deleted document",
126                            pal.getName(), task.getName()));
127                }
128            }
129        }
130    }
131
132    protected boolean getFilterDocumentsInTrash() {
133        Map<String, Serializable> props = getProperties();
134        if (props.containsKey(FILTER_DOCS_FROM_TRASH)) {
135            return Boolean.TRUE.equals(Boolean.valueOf((String) props.get(FILTER_DOCS_FROM_TRASH)));
136        }
137        return true;
138    }
139
140    protected CoreSession getCoreSession() {
141        Map<String, Serializable> props = getProperties();
142        CoreSession coreSession = (CoreSession) props.get(CORE_SESSION_PROPERTY);
143        if (coreSession == null) {
144            throw new NuxeoException("cannot find core session");
145        }
146        return coreSession;
147    }
148
149    /**
150     * This page provider does not support sort for now => override what may be contributed in the definition
151     */
152    @Override
153    public boolean isSortable() {
154        return false;
155    }
156
157    @Override
158    protected void pageChanged() {
159        pageTasks = null;
160        super.pageChanged();
161    }
162
163    @Override
164    public void refresh() {
165        userTasks = null;
166        pageTasks = null;
167        super.refresh();
168    }
169
170}