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