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 * Antoine Taillefer 016 */ 017package org.nuxeo.ecm.platform.task.core.service; 018 019import java.io.Serializable; 020import java.util.ArrayList; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024import org.apache.commons.lang.StringUtils; 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.DocumentNotFoundException; 030import org.nuxeo.ecm.core.api.IdRef; 031import org.nuxeo.ecm.core.api.InstanceRef; 032import org.nuxeo.ecm.core.api.NuxeoPrincipal; 033import org.nuxeo.ecm.core.api.event.CoreEventConstants; 034import org.nuxeo.ecm.core.api.event.DocumentEventCategories; 035import org.nuxeo.ecm.core.event.Event; 036import org.nuxeo.ecm.core.event.EventContext; 037import org.nuxeo.ecm.core.event.EventProducer; 038import org.nuxeo.ecm.core.event.impl.DocumentEventContext; 039import org.nuxeo.ecm.core.event.impl.EventContextImpl; 040import org.nuxeo.ecm.platform.ec.notification.NotificationConstants; 041import org.nuxeo.ecm.platform.task.Task; 042import org.nuxeo.ecm.platform.task.TaskEventNames; 043import org.nuxeo.ecm.platform.task.TaskService; 044import org.nuxeo.runtime.api.Framework; 045 046/** 047 * Helper for notifying task related events. 048 * 049 * @since 5.6 050 */ 051public final class TaskEventNotificationHelper { 052 053 private final static Log log = LogFactory.getLog(TaskEventNotificationHelper.class); 054 055 056 public static void notifyEvent(CoreSession coreSession, DocumentModel document, NuxeoPrincipal principal, Task task, 057 String eventId, Map<String, Serializable> properties, String comment, String category) { 058 // Default category 059 if (category == null) { 060 category = DocumentEventCategories.EVENT_DOCUMENT_CATEGORY; 061 } 062 if (properties == null) { 063 properties = new HashMap<String, Serializable>(); 064 } 065 066 EventContext eventContext = null; 067 if (document != null) { 068 properties.put(CoreEventConstants.REPOSITORY_NAME, document.getRepositoryName()); 069 properties.put(CoreEventConstants.SESSION_ID, coreSession.getSessionId()); 070 properties.put(CoreEventConstants.DOC_LIFE_CYCLE, document.getCurrentLifeCycleState()); 071 eventContext = new DocumentEventContext(coreSession, principal, document); 072 } else { 073 eventContext = new EventContextImpl(coreSession, principal); 074 } 075 properties.put(DocumentEventContext.COMMENT_PROPERTY_KEY, comment); 076 properties.put(DocumentEventContext.CATEGORY_PROPERTY_KEY, category); 077 properties.put(TaskService.TASK_INSTANCE_EVENT_PROPERTIES_KEY, new InstanceRef(task.getDocument(), coreSession.getPrincipal())); 078 String disableNotif = task.getVariable(TaskEventNames.DISABLE_NOTIFICATION_SERVICE); 079 if (disableNotif != null && Boolean.TRUE.equals(Boolean.valueOf(disableNotif))) { 080 properties.put(TaskEventNames.DISABLE_NOTIFICATION_SERVICE, Boolean.TRUE); 081 } 082 eventContext.setProperties(properties); 083 084 Event event = eventContext.newEvent(eventId); 085 getEventProducer().fireEvent(event); 086 } 087 088 /** 089 * @since 7.2 090 */ 091 public static void notifyTaskEnded(CoreSession coreSession, NuxeoPrincipal principal, Task task, String comment, 092 String eventName, Map<String, Serializable> extraEventProperties) { 093 094 // try to resolve document when notifying 095 DocumentModel document = null; 096 097 List<String> docIds = new ArrayList<String>(); 098 docIds.addAll(task.getTargetDocumentsIds()); 099 // handle compatibility with tasks created before 5.8 100 String docId = task.getTargetDocumentId(); 101 if (!docIds.contains(docId)) { 102 docIds.add(docId); 103 } 104 // also handle compatibility with deprecated jbpm tasks 105 String docIdVar = task.getVariable(TaskService.VariableName.documentId.name()); 106 if (!docIds.contains(docIdVar)) { 107 docIds.add(docIdVar); 108 } 109 String docRepo = task.getVariable(TaskService.VariableName.documentRepositoryName.name()); 110 List<DocumentModel> documents = new ArrayList<DocumentModel>(); 111 if (coreSession.getRepositoryName().equals(docRepo)) { 112 try { 113 for (String id : docIds) { 114 document = coreSession.getDocument(new IdRef(id)); 115 documents.add(document); 116 } 117 } catch (DocumentNotFoundException e) { 118 log.error(String.format("Could not fetch document with id '%s:%s' for notification", docRepo, docId), 119 e); 120 } 121 } else { 122 log.error(String.format( 123 "Could not resolve document for notification: " 124 + "document is on repository '%s' and given session is on " + "repository '%s'", 125 docRepo, coreSession.getRepositoryName())); 126 } 127 128 final Map<String, Serializable> eventProperties = new HashMap<String, Serializable>(); 129 ArrayList<String> notificationRecipients = new ArrayList<String>(); 130 notificationRecipients.add(task.getInitiator()); 131 notificationRecipients.addAll(task.getActors()); 132 eventProperties.put(NotificationConstants.RECIPIENTS_KEY, notificationRecipients); 133 if (extraEventProperties != null) { 134 eventProperties.putAll(extraEventProperties); 135 } 136 boolean taskEndedByDelegatedActor = task.getDelegatedActors() != null 137 && task.getDelegatedActors().contains(principal.getName()); 138 for (DocumentModel doc : documents) { 139 notifyEvent(coreSession, doc, principal, task, eventName, eventProperties, comment, null); 140 if (taskEndedByDelegatedActor) { 141 notifyEvent(coreSession, doc, principal, task, eventName, eventProperties, 142 String.format("Task ended by an delegated actor '%s' ", principal.getName()) 143 + (!StringUtils.isEmpty(comment) ? " with the following comment: " + comment : ""), 144 null); 145 } 146 } 147 } 148 149 public static EventProducer getEventProducer() { 150 return Framework.getLocalService(EventProducer.class); 151 } 152}