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}