/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.sparkimpl.preference.notifications;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.plugin.Plugin;
import org.jivesoftware.spark.ui.ContactGroup;
import org.jivesoftware.spark.ui.ContactItem;
import org.jivesoftware.spark.ui.ContactList;
import org.jivesoftware.spark.util.SwingTimerTask;
import org.jivesoftware.spark.util.TaskEngine;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.plugin.alerts.SparkToaster;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.HashSet;
import java.util.Set;
import java.util.TimerTask;
/**
* Adds a simple notification system to alert users to presence changes.
*
* @author Derek DeMoro
*/
public class NotificationPlugin implements Plugin, PacketListener {
private Set<String> onlineUsers = new HashSet<String>();
private LocalPreferences preferences;
public void initialize() {
// Add the preferences
NotificationsPreference notifications = new NotificationsPreference();
SparkManager.getPreferenceManager().addPreference(notifications);
notifications.load();
final TimerTask registerTask = new SwingTimerTask() {
public void doRun() {
registerListener();
}
};
TaskEngine.getInstance().schedule(registerTask, 5000);
}
private void registerListener() {
preferences = SettingsManager.getLocalPreferences();
// Iterate through all online users and add them to the list.
ContactList contactList = SparkManager.getWorkspace().getContactList();
for (ContactGroup contactGroup : contactList.getContactGroups()) {
for (ContactItem item : contactGroup.getContactItems()) {
if (item != null && item.getJID() != null && item.getPresence().isAvailable()) {
String bareJID = StringUtils.parseBareAddress(item.getJID());
onlineUsers.add(bareJID);
}
}
}
// Add Presence Listener
SparkManager.getConnection().addPacketListener(this, new PacketTypeFilter(Presence.class));
}
public void processPacket(Packet packet) {
final Presence presence = (Presence)packet;
String jid = presence.getFrom();
if (jid == null) {
return;
}
// Make sure the user is in the contact list.
ContactItem contactItem = SparkManager.getWorkspace().getContactList().getContactItemByJID(jid);
if (contactItem == null) {
return;
}
jid = StringUtils.parseBareAddress(jid);
boolean isOnline = onlineUsers.contains(jid);
if (presence.isAvailable()) {
if (preferences.isOnlineNotificationsOn()) {
if (!isOnline) {
notifyUserOnline(jid, presence);
}
}
onlineUsers.add(jid);
}
else {
if (preferences.isOfflineNotificationsOn() && isOnline) {
notifyUserOffline(jid, presence);
}
onlineUsers.remove(jid);
}
}
public void shutdown() {
}
public boolean canShutDown() {
return true;
}
public void uninstall() {
SparkManager.getConnection().removePacketListener(this);
}
/**
* Notify client that a user has come online.
*
* @param jid the jid of the user that has come online.
* @param presence Presence of the online user.
*/
private void notifyUserOnline(final String jid, final Presence presence) {
try {
EventQueue.invokeAndWait(new Runnable(){
public void run() {
SparkToaster toaster = new SparkToaster();
toaster.setDisplayTime(5000);
toaster.setBorder(BorderFactory.createBevelBorder(0));
toaster.setCustomAction(new ChatAction(jid));
NotificationAlertUI alertUI = new NotificationAlertUI(jid, true, presence);
toaster.setToasterHeight((int)alertUI.getPreferredSize().getHeight() + 40);
int width = (int)alertUI.getPreferredSize().getWidth() + 40;
if (width < 300) {
width = 300;
}
toaster.setToasterWidth(width);
toaster.showToaster("", alertUI);
toaster.hideTitle();
}
});
}
catch(Exception ex) {
Log.error(ex);
}
}
/**
* Notify client that a user has gone offline.
*
* @param jid the jid of the user who has gone offline.
* @param presence of the offline user.
*/
private void notifyUserOffline(final String jid, final Presence presence) {
try {
EventQueue.invokeAndWait(new Runnable(){
public void run() {
SparkToaster toaster = new SparkToaster();
toaster.setCustomAction(new ChatAction(jid));
toaster.setDisplayTime(5000);
toaster.setBorder(BorderFactory.createBevelBorder(0));
NotificationAlertUI alertUI = new NotificationAlertUI(jid, false, presence);
toaster.setToasterHeight((int)alertUI.getPreferredSize().getHeight() + 40);
int width = (int)alertUI.getPreferredSize().getWidth() + 40;
if (width < 300) {
width = 300;
}
toaster.setToasterWidth(width);
toaster.showToaster("", alertUI);
toaster.hideTitle();
}
});
}
catch(Exception ex) {
Log.error(ex);
}
}
private class ChatAction extends AbstractAction {
private static final long serialVersionUID = 4752515615833181939L;
private String jid;
public ChatAction(String jid) {
this.jid = jid;
}
public void actionPerformed(ActionEvent e) {
String nickname = SparkManager.getUserManager().getUserNicknameFromJID(jid);
SparkManager.getChatManager().activateChat(jid, nickname);
}
}
}