/*==========================================================================*\ | $Id: SendMessageWorkerThread.java,v 1.5 2011/12/25 21:18:26 stedwar2 Exp $ |*-------------------------------------------------------------------------*| | Copyright (C) 2006-2011 Virginia Tech | | This file is part of Web-CAT. | | Web-CAT is free software; you can redistribute it and/or modify | it under the terms of the GNU Affero General Public License as published | by the Free Software Foundation; either version 3 of the License, or | (at your option) any later version. | | Web-CAT is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU Affero General Public License | along with Web-CAT; if not, see <http://www.gnu.org/licenses/>. \*==========================================================================*/ package org.webcat.notifications; import java.io.IOException; import java.util.HashSet; import java.util.Set; import org.apache.log4j.Logger; import org.webcat.core.Application; import org.webcat.core.MutableDictionary; import org.webcat.core.User; import org.webcat.core.messaging.IMessageSettings; import org.webcat.core.messaging.Message; import org.webcat.core.messaging.MessageDescriptor; import org.webcat.jobqueue.WorkerThread; import org.webcat.notifications.protocols.Protocol; import com.webobjects.eocontrol.EOEditingContext; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSDictionary; //------------------------------------------------------------------------- /** * TODO: place a real description here. * * @author Tony Allevato * @author Last changed by: $Author: stedwar2 $ * @version $Revision: 1.5 $, $Date: 2011/12/25 21:18:26 $ */ public class SendMessageWorkerThread extends WorkerThread<SendMessageJob> { //~ Constructors .......................................................... // ---------------------------------------------------------- /** * Initializes a new instance of the SendMessageWorkerThread class. * * @param queueEntity the queue entity */ public SendMessageWorkerThread() { super(SendMessageJob.ENTITY_NAME); } //~ Methods ............................................................... // ---------------------------------------------------------- /** * Implements the logic of the job. */ @Override protected void processJob() throws IOException { sendInternal(); } // ---------------------------------------------------------- /** * Sends the message, after the editing context has been locked. * * @param ec the editing context to use for fetching protocol settings */ private void sendInternal() { SendMessageJob job = currentJob(); if (log.isDebugEnabled()) { log.debug("Starting job: " + job.id() + ": "+ job); } MessageDescriptor descriptor = Message.messageDescriptorForMessageType(job.messageType()); // Broadcast the message to any system-wide messaging protocols that // apply. if (descriptor.isBroadcast()) { IMessageSettings settings; if (job.broadcastProtocolSettings() != null) { settings = job.broadcastProtocolSettings(); } else if (job.broadcastProtocolSettingsSnapshot() != null) { settings = new MessageSettingsSnapshotWrapper( job.broadcastProtocolSettingsSnapshot()); } else { settings = ProtocolSettings.systemSettings(localContext()); } Set<Protocol> protocols = broadcastProtocolsToSend(); for (Protocol protocol : protocols) { try { protocol.sendMessage(job, null, settings); } catch (Exception e) { log.error("The following error occurred when sending " + "the broadcast message \"" + job.title() + "\"", e); } } } // Send the message directly to any users to whom the message applies, // if they have notifications for a particular protocol enabled. NSArray<User> users = job.destinationUsers(); if (users != null) { for (User user : users) { // Sanity check to ensure that messages don't get sent to users // who shouldn't receive them based on their access level. if (user.accessLevel() >= descriptor.accessLevel()) { ProtocolSettings protocolSettings = ProtocolSettings.protocolSettingsForUser(user); Set<Protocol> protocols = userProtocolsToSend(user); for (Protocol protocol : protocols) { try { protocol.sendMessage(job, user, protocolSettings); } catch (Exception e) { log.error("The following error occurred when " + "sending the direct message \"" + job.title() + "\" to user " + user.name(), e); } } } } } // Mail the message to system administrators if necessary. if (job.isSevere()) { sendMailToSysAdmins(); } if (log.isDebugEnabled()) { log.debug("Finished job: " + job.id() + ": "+ job); } } // ---------------------------------------------------------- /** * Sends this message to the system notification e-mail addresses that are * specified in the installation wizard. */ private void sendMailToSysAdmins() { SendMessageJob job = currentJob(); StringBuffer body = new StringBuffer(); body.append(job.fullBody()); body.append("\n\n"); @SuppressWarnings("unchecked") NSDictionary<String, String> links = job.links(); if (links != null && links.count() > 0) { body.append("Links:\n"); for (String key : links.allKeys()) { String url = links.objectForKey(key); body.append(key); body.append(": "); body.append(url); body.append("\n"); } } Application.sendAdminEmail( job.title(), body.toString(), job.attachmentsAsList()); } // ---------------------------------------------------------- /** * Gets the set of protocols that the system administrator has enabled for * this type of message. * * @return the set of Protocols that the system administrator has enabled * for broadcast messages */ private Set<Protocol> broadcastProtocolsToSend() { SendMessageJob job = currentJob(); String messageType = job.messageType(); Set<Protocol> protocolsToSend = new HashSet<Protocol>(); NSArray<Protocol> protocols = MessageDispatcher.sharedDispatcher().registeredProtocols(true); for (Protocol protocol : protocols) { if (protocol.isEnabledByDefault()) { protocolsToSend.add(protocol); } } NSArray<BroadcastMessageSubscription> subscriptions = BroadcastMessageSubscription.subscriptionsForMessageType( localContext(), messageType); for (BroadcastMessageSubscription subscription : subscriptions) { String type = subscription.protocolType(); Protocol protocol = MessageDispatcher.sharedDispatcher().protocolWithName( type, true); if (protocol != null) { if (subscription.isEnabled()) { protocolsToSend.add(protocol); } else { protocolsToSend.remove(protocol); } } else { log.warn("Attempted to send broadcast message via " + "unregistered protocol: " + type); } } return protocolsToSend; } // ---------------------------------------------------------- /** * Gets the set of protocols that the specified user has enabled for a * particular message type. * * @param user the User who will be receiving a message * @param ec the editing context * @return the set of Protocols that this user has enabled */ private Set<Protocol> userProtocolsToSend(User user) { SendMessageJob job = currentJob(); String messageType = job.messageType(); EOEditingContext ec = user.editingContext(); Set<Protocol> protocolsToSend = new HashSet<Protocol>(); NSArray<Protocol> protocols = MessageDispatcher.sharedDispatcher().registeredProtocols(false); for (Protocol protocol : protocols) { if (protocol.isEnabledByDefault()) { protocolsToSend.add(protocol); } } NSArray<UserMessageSubscription> subscriptions = UserMessageSubscription.subscriptionsForMessageTypeAndUser( ec, messageType, user); for (UserMessageSubscription subscription : subscriptions) { String type = subscription.protocolType(); Protocol protocol = MessageDispatcher.sharedDispatcher().protocolWithName( type, false); if (protocol != null) { if (subscription.isEnabled()) { protocolsToSend.add(protocol); } else { protocolsToSend.remove(protocol); } } else { log.warn("Attempted to send direct message via " + "unregistered protocol: " + type); } } return protocolsToSend; } // ---------------------------------------------------------- /* @Override protected void resetJob() { } // ---------------------------------------------------------- @Override protected String additionalSuspensionInfo() { return null; }*/ // ---------------------------------------------------------- private class MessageSettingsSnapshotWrapper implements IMessageSettings { // ---------------------------------------------------------- public MessageSettingsSnapshotWrapper(MutableDictionary snapshot) { this.snapshot = snapshot; } // ---------------------------------------------------------- public MutableDictionary settingsSnapshot() { return snapshot; } // ---------------------------------------------------------- public Object settingForKey(String key) { return snapshot.objectForKey(key); } // ---------------------------------------------------------- public String stringSettingForKey(String key, String defaultValue) { String value = (String) settingForKey(key); return value == null ? defaultValue : value; } // ---------------------------------------------------------- public boolean booleanSettingForKey(String key, boolean defaultValue) { Boolean value = (Boolean) settingForKey(key); return value == null ? defaultValue : value; } // ---------------------------------------------------------- public int intSettingForKey(String key, int defaultValue) { Number value = (Number) settingForKey(key); return value == null ? defaultValue : value.intValue(); } // ---------------------------------------------------------- public double doubleSettingForKey(String key, double defaultValue) { Number value = (Number) settingForKey(key); return value == null ? defaultValue : value.doubleValue(); } private MutableDictionary snapshot; } //~ Static/instance variables ............................................. private static final Logger log = Logger.getLogger( SendMessageWorkerThread.class); }