001/*
002 * (C) Copyright 2012 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, Antoine Taillefer
016 */
017package org.nuxeo.ecm.platform.task.web;
018
019import java.util.ArrayList;
020import java.util.List;
021
022import org.jboss.seam.ScopeType;
023import org.jboss.seam.annotations.Factory;
024import org.jboss.seam.annotations.In;
025import org.jboss.seam.annotations.Name;
026import org.jboss.seam.annotations.Observer;
027import org.jboss.seam.annotations.Scope;
028import org.jboss.seam.annotations.intercept.BypassInterceptors;
029import org.jboss.seam.core.Events;
030import org.jboss.seam.faces.FacesMessages;
031import org.jboss.seam.international.LocaleSelector;
032import org.jboss.seam.international.StatusMessage;
033import org.nuxeo.ecm.core.api.CoreSession;
034import org.nuxeo.ecm.core.api.DocumentModel;
035import org.nuxeo.ecm.core.api.NuxeoPrincipal;
036import org.nuxeo.ecm.platform.contentview.seam.ContentViewActions;
037import org.nuxeo.ecm.platform.task.Task;
038import org.nuxeo.ecm.platform.task.TaskEventNames;
039import org.nuxeo.ecm.platform.task.TaskService;
040import org.nuxeo.ecm.platform.task.core.helpers.TaskActorsHelper;
041import org.nuxeo.ecm.platform.task.dashboard.DashBoardItem;
042import org.nuxeo.ecm.platform.task.dashboard.DashBoardItemImpl;
043import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
044import org.nuxeo.ecm.platform.ui.web.invalidations.AutomaticDocumentBasedInvalidation;
045import org.nuxeo.ecm.platform.ui.web.invalidations.DocumentContextBoundActionBean;
046import org.nuxeo.ecm.webapp.helpers.EventNames;
047import org.nuxeo.ecm.webapp.helpers.ResourcesAccessor;
048
049/**
050 * Seam component holding tasks actions created using the {@link TaskService} in document context cache.
051 *
052 * @author Anahide Tchertchian
053 */
054@Name("taskActions")
055@Scope(ScopeType.CONVERSATION)
056@AutomaticDocumentBasedInvalidation
057public class TaskActionsBean extends DocumentContextBoundActionBean {
058
059    private static final long serialVersionUID = 1L;
060
061    /**
062     * @since 7.2
063     */
064    public static final String TASKS_CACHE_RESET = "tasksCacheReset";
065
066    @In(create = true, required = false)
067    protected transient CoreSession documentManager;
068
069    @In(create = true)
070    protected ContentViewActions contentViewActions;
071
072    @In(create = true)
073    protected transient TaskService taskService;
074
075    @In(create = true)
076    protected transient NavigationContext navigationContext;
077
078    @In(create = true, required = false)
079    protected FacesMessages facesMessages;
080
081    @In(create = true)
082    protected ResourcesAccessor resourcesAccessor;
083
084    @In(create = true)
085    protected transient LocaleSelector localeSelector;
086
087    protected List<Task> tasks;
088
089    protected List<DashBoardItem> items;
090
091    protected String comment;
092
093    @Factory(value = "currentSingleTasks", scope = ScopeType.EVENT)
094    public List<Task> getCurrentDocumentTasks() {
095        if (tasks == null) {
096            tasks = new ArrayList<Task>();
097            DocumentModel currentDocument = navigationContext.getCurrentDocument();
098            if (currentDocument != null) {
099                NuxeoPrincipal principal = (NuxeoPrincipal) documentManager.getPrincipal();
100                List<String> actors = new ArrayList<String>();
101                actors.addAll(TaskActorsHelper.getTaskActors(principal));
102                tasks = taskService.getTaskInstances(currentDocument, actors, true, documentManager);
103            }
104        }
105        return tasks;
106    }
107
108    @Factory(value = "currentDashBoardItems", scope = ScopeType.EVENT)
109    public List<DashBoardItem> getCurrentDashBoardItems() {
110        if (items == null) {
111            items = new ArrayList<DashBoardItem>();
112            for (Task task : getCurrentDocumentTasks()) {
113                DashBoardItem item = new DashBoardItemImpl(task, navigationContext.getCurrentDocument(),
114                        localeSelector.getLocale());
115                items.add(item);
116            }
117        }
118        return items;
119    }
120
121    @Factory(value = "currentDashBoardItemsExceptPublishingTasks", scope = ScopeType.EVENT)
122    public List<DashBoardItem> getCurrentDashBoardItemsExceptPublishingTasks() {
123        if (items == null) {
124            items = new ArrayList<DashBoardItem>();
125            for (Task task : getCurrentDocumentTasks()) {
126                String taskType = task.getVariable(Task.TaskVariableName.taskType.name());
127                if (!"publish_moderate".equals(taskType)) {
128                    DashBoardItem item = new DashBoardItemImpl(task, navigationContext.getCurrentDocument(),
129                            localeSelector.getLocale());
130                    items.add(item);
131                }
132            }
133        }
134        return items;
135    }
136
137    public String getComment() {
138        return comment;
139    }
140
141    public void setComment(String comment) {
142        this.comment = comment;
143    }
144
145    public void acceptTask(Task task) {
146        acceptTask(task, getComment());
147        setComment(null);
148    }
149
150    public void acceptTask(Task task, String comment) {
151        String seamEventName = taskService.acceptTask(documentManager, (NuxeoPrincipal) documentManager.getPrincipal(),
152                task, comment);
153        if (seamEventName != null) {
154            Events.instance().raiseEvent(seamEventName);
155        }
156    }
157
158    public void rejectTask(Task task) {
159        String userComment = getComment();
160        if (userComment != null && !"".equals(userComment)) {
161            rejectTask(task, userComment);
162            setComment(null);
163        } else {
164            facesMessages.add(StatusMessage.Severity.ERROR,
165                    resourcesAccessor.getMessages().get("label.review.task.enterComment"));
166        }
167
168    }
169
170    public void rejectTask(Task task, String comment) {
171        String seamEventName = taskService.rejectTask(documentManager, (NuxeoPrincipal) documentManager.getPrincipal(),
172                task, comment);
173        if (seamEventName != null) {
174            Events.instance().raiseEvent(seamEventName);
175        }
176    }
177
178    @Override
179    public void resetBeanCache(DocumentModel newCurrentDocumentModel) {
180        resetCache();
181    }
182
183    @Observer(value = { TaskEventNames.WORKFLOW_ENDED, TaskEventNames.WORKFLOW_NEW_STARTED,
184            TaskEventNames.WORKFLOW_TASK_START, TaskEventNames.WORKFLOW_TASK_STOP,
185            TaskEventNames.WORKFLOW_TASK_REJECTED, TaskEventNames.WORKFLOW_USER_ASSIGNMENT_CHANGED,
186            TaskEventNames.WORKFLOW_TASK_REASSIGNED, TaskEventNames.WORKFLOW_TASK_DELEGATED,
187            TaskEventNames.WORKFLOW_TASK_COMPLETED, TaskEventNames.WORKFLOW_TASK_REMOVED,
188            TaskEventNames.WORK_ITEMS_LIST_LOADED, TaskEventNames.WORKFLOW_TASKS_COMPUTED,
189            TaskEventNames.WORKFLOW_ABANDONED, TaskEventNames.WORKFLOW_CANCELED, EventNames.DOMAIN_SELECTION_CHANGED,
190            "documentPublicationRejected", "documentPublished" }, create = false)
191    @BypassInterceptors
192    public void resetCache() {
193        tasks = null;
194        items = null;
195        Events.instance().raiseEvent(TASKS_CACHE_RESET);
196    }
197
198    /**
199     * @since 7.2
200     */
201    @Observer({ TASKS_CACHE_RESET })
202    public void resetTasksCache() {
203        contentViewActions.refreshOnSeamEvent(TASKS_CACHE_RESET);
204        contentViewActions.resetPageProviderOnSeamEvent(TASKS_CACHE_RESET);
205    }
206
207}