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