Adding Growl plugin to Spark.

git-svn-id: http://svn.igniterealtime.org/svn/repos/spark/trunk@4907 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Derek DeMoro
2006-08-14 21:00:30 +00:00
committed by derek
parent 43af708432
commit 81bfcd4250
8 changed files with 773 additions and 1 deletions

View File

@ -17,7 +17,7 @@ public class JiveInfo {
}
public static String getVersion() {
return "1.1.9.7";
return "2.0.0.1";
}
public static String getOS() {

View File

@ -0,0 +1,49 @@
<project name="growl" default="jar" basedir=".">
<property name="client.dir" value="../.."/>
<property name="client.lib.dir" value="${client.dir}/libs"/>
<property name="client.classes.dir" value="${client.dir}/target/classes"/>
<property name="apple.plugin.classes" value="../apple/classes"/>
<property name="target.dir" value="${basedir}/target"/>
<property name="classes.dir" value="${basedir}/classes"/>
<property name="src.dir" value="${basedir}/src"/>
<property name="jar.file" value="${client.dir}/target/build/plugins/growl.jar"/>
<path id="lib.classpath">
<fileset dir="${client.lib.dir}" includes="**/*.jar"/>
<pathelement location="/System/Library/Java"/>
<pathelement location="${client.classes.dir}"/>
<pathelement location="${apple.plugin.classes}"/>
</path>
<target name="clean">
<delete dir="${target.dir}"/>
<delete dir="${classes.dir}"/>
<delete dir="${target.dir}"/>
</target>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}"
destdir="${classes.dir}"
classpathref="lib.classpath"
source="1.4"
debug="true"
target="1.4"/>
</target>
<target name="jar.classes" depends="compile">
<mkdir dir="${target.dir}/lib"/>
<jar basedir="${classes.dir}" file="${target.dir}/lib/growl.jar"/>
</target>
<target name="jar" depends="clean,jar.classes">
<copy todir="${target.dir}">
<fileset dir="${src.dir}" includes="**/*.xml"/>
</copy>
<jar basedir="${target.dir}" file="${jar.file}" update="false"/>
</target>
</project>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4" relativePaths="true" type="JAVA_MODULE">
<component name="ModuleRootManager" />
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/target/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="file:///System/Library/Java" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module" module-name="Spark" />
<orderEntry type="module" module-name="apple" />
<orderEntryProperties />
</component>
<component name="VcsManagerConfiguration">
<option name="ACTIVE_VCS_NAME" value="svn" />
<option name="USE_PROJECT_VCS" value="false" />
</component>
</module>

View File

@ -0,0 +1,465 @@
/**
* Growl.java
*
* Version:
* $Id:$
*
* Revisions:
* $Log:$
*
*/
package com.growl;
import com.apple.cocoa.foundation.NSDistributedNotificationCenter;
import com.apple.cocoa.foundation.NSArray;
import com.apple.cocoa.foundation.NSDictionary;
import com.apple.cocoa.foundation.NSMutableDictionary;
import com.apple.cocoa.foundation.NSData;
import com.apple.cocoa.application.NSImage;
/**
* A class that encapsulates the "work" of talking to growl
*
* @author Karl Adam
*/
public class Growl {
// defines
/** The name of the growl registration notification for DNC. */
public static final String GROWL_APP_REGISTRATION = "GrowlApplicationRegistrationNotification";
// Ticket Defines
/** Ticket key for the application name. */
public static final String GROWL_APP_NAME = "ApplicationName";
/** Ticket key for the application icon. */
public static final String GROWL_APP_ICON = "ApplicationIcon";
/** Ticket key for the default notifactions. */
public static final String GROWL_NOTIFICATIONS_DEFAULT = "DefaultNotifications";
/** Ticket key for all notifactions. */
public static final String GROWL_NOTIFICATIONS_ALL = "AllNotifications";
// Notification Defines
/** The name of the growl notification for DNC. */
public static final String GROWL_NOTIFICATION = "GrowlNotification";
/** Notification key for the name. */
public static final String GROWL_NOTIFICATION_NAME = "NotificationName";
/** Notification key for the title. */
public static final String GROWL_NOTIFICATION_TITLE = "NotificationTitle";
/** Notification key for the description. */
public static final String GROWL_NOTIFICATION_DESCRIPTION = "NotificationDescription";
/** Notification key for the icon. */
public static final String GROWL_NOTIFICATION_ICON = "NotificationIcon";
/** Notification key for the application icon. */
public static final String GROWL_NOTIFICATION_APP_ICON = "NotificationAppIcon";
/** Notification key for the sticky flag. */
public static final String GROWL_NOTIFICATION_STICKY = "NotificationSticky";
// Actual instance data
private boolean registered; // We should only register once
private String appName; // "Application" Name
private NSData appImageData; // "application" Icon
private NSDictionary regDict; // Registration Dictionary
private NSArray allNotes; // All notifications
private NSArray defNotes; // Default Notifications
private NSDistributedNotificationCenter theCenter;
//************ Constructors **************//
/**
* Convenience method to contruct a growl instance, defers to Growl(String
* inAppName, NSData inImageData, NSArray inAllNotes, NSArray inDefNotes,
* boolean registerNow) with empty arrays for your notifications.
*
*
* @param inAppName - The Name of your "application"
* @param inImage - The NSImage Icon for your Application
*
*/
public Growl(String inAppName, NSImage inImage) {
this(inAppName,
inImage.TIFFRepresentation(),
new NSArray(),
new NSArray(),
false);
}
/**
* Convenience method to contruct a growl instance, defers to Growl(String
* inAppName, NSData inImageData, NSArray inAllNotes, NSArray inDefNotes,
* boolean registerNow) with empty arrays for your notifications.
*
* @param inAppName - The Name of your "Application"
* @param inImageData - The NSData for your NSImage
*/
public Growl(String inAppName, NSData inImageData) {
this(inAppName,
inImageData,
new NSArray(),
new NSArray(),
false);
}
/**
* Convenience method to contruct a growl instance, defers to Growl(String
* inAppName, NSData inImageData, NSArray inAllNotes, NSArray inDefNotes,
* boolean registerNow) with empty arrays for your notifications.
*
* @param inAppName - The Name of your "Application"
* @param inImagePath - The path to your icon
*
*/
public Growl(String inAppName, String inImagePath) {
this(inAppName,
new NSImage(inImagePath, false).TIFFRepresentation(),
new NSArray(),
new NSArray(),
false);
}
/**
* Convenience method to contruct a growl instance, defers to Growl(String
* inAppName, NSData inImageData, NSArray inAllNotes, NSArray inDefNotes,
* boolean registerNow) with the arrays passed here and empty Data for the icon.
*
* @param inAppName - The Name of your "Application"
* @param inAllNotes - A String Array with the name of all your notifications
* @param inDefNotes - A String Array with the na,es of the Notifications on
* by default
*/
public Growl(String inAppName, String [] inAllNotes, String [] inDefNotes) {
this(inAppName,
new NSData(),
new NSArray(inAllNotes),
new NSArray(inDefNotes),
false);
}
/**
* Convenience method to contruct a growl instance, defers to Growl(String
* inAppName, NSData inImageData, NSArray inAllNotes, NSArray inDefNotes,
* boolean registerNow) with empty arrays for your notifications.
*
* @param inAppName - The Name of your "Application"
* @param inImageData - The Data of your "Application"'s icon
* @param inAllNotes - The NSArray of Strings of all your Notifications
* @param inDefNotes - The NSArray of Strings of your default Notifications
* @param registerNow - Since we have all the necessary info we can go ahead
* and register
*/
public Growl(String inAppName, NSData inImageData, NSArray inAllNotes,
NSArray inDefNotes, boolean registerNow) {
appName = inAppName;
appImageData = inImageData;
allNotes = inAllNotes;
defNotes = inDefNotes;
theCenter = (NSDistributedNotificationCenter)NSDistributedNotificationCenter.defaultCenter();
if (registerNow) {
register();
}
}
//************ Commonly Used Methods **************//
/**
* Register all our notifications with Growl, this should only be called
* once.
* @return <code>true</code>.
*/
public boolean register() {
if (!registered) {
// Construct our dictionary
// Make the arrays of objects then keys
Object [] objects = { appName, allNotes, defNotes, appImageData };
String [] keys = { GROWL_APP_NAME,
GROWL_NOTIFICATIONS_ALL,
GROWL_NOTIFICATIONS_DEFAULT,
GROWL_APP_ICON};
// Make the Dictionary
regDict = new NSDictionary(objects, keys);
theCenter.postNotification(GROWL_APP_REGISTRATION, // notificationName
(String)null, // anObject
regDict, // userInfoDictionary
true); // deliverImmediately
}
return true;
}
/**
* The fun part is actually sending those notifications we worked so hard for
* so here we let growl know about things we think the user would like, and growl
* decides if that is the case.
*
* @param inNotificationName - The name of one of the notifications we told growl
* about.
* @param inIconData - The NSData for the icon for this notification, can be null
* @param inTitle - The Title of our Notification as Growl will show it
* @param inDescription - The Description of our Notification as Growl will
* display it
* @param inExtraInfo - Growl is flexible and allows Display Plugins to do as they
* please with thier own special keys and values, you may use
* them here. These may be ignored by either the user's
* preferences or the current Display Plugin. This can be null
* @param inSticky - Whether the Growl notification should be sticky
*
* @throws Exception When a notification is not known
*/
public void notifyGrowlOf(String inNotificationName, NSData inIconData,
String inTitle, String inDescription,
NSDictionary inExtraInfo, boolean inSticky) throws Exception {
NSMutableDictionary noteDict = new NSMutableDictionary();
if (!allNotes.containsObject(inNotificationName)) {
throw new Exception("Undefined Notification attempted");
}
noteDict.setObjectForKey(inNotificationName, GROWL_NOTIFICATION_NAME);
noteDict.setObjectForKey(inTitle, GROWL_NOTIFICATION_TITLE);
noteDict.setObjectForKey(inDescription, GROWL_NOTIFICATION_DESCRIPTION);
noteDict.setObjectForKey(appName, GROWL_APP_NAME);
if (inIconData != null) {
noteDict.setObjectForKey(inIconData, GROWL_NOTIFICATION_ICON);
}
if (inSticky) {
noteDict.setObjectForKey(new Integer(1), GROWL_NOTIFICATION_STICKY);
}
if (inExtraInfo != null) {
noteDict.addEntriesFromDictionary(inExtraInfo);
}
theCenter.postNotification(GROWL_NOTIFICATION,
(String)null,
noteDict,
true);
}
/**
* Convenience method that defers to notifyGrowlOf(String inNotificationName,
* NSData inIconData, String inTitle, String inDescription,
* NSDictionary inExtraInfo, boolean inSticky)
* This is primarily for compatibility with older code
*
* @param inNotificationName - The name of one of the notifications we told growl
* about.
* @param inIconData - The NSData for the icon for this notification, can be null
* @param inTitle - The Title of our Notification as Growl will show it
* @param inDescription - The Description of our Notification as Growl will
* display it
* @param inExtraInfo - Growl is flexible and allows Display Plugins to do as
* they please with their own special keys and values, you
* may use them here. These may be ignored by either the
* user's preferences or the current Display Plugin. This
* can be null.
*
* @throws Exception When a notification is not known
*
*/
public void notifyGrowlOf(String inNotificationName, NSData inIconData,
String inTitle, String inDescription,
NSDictionary inExtraInfo) throws Exception {
notifyGrowlOf(inNotificationName, inIconData, inTitle, inDescription,
inExtraInfo, false);
}
/**
* Convenienve method that defers to notifyGrowlOf(String inNotificationName,
* NSData inIconData, String inTitle, String inDescription,
* NSDictionary inExtraInfo) with null passed for icon and extraInfo arguments
*
* @param inNotificationName - The name of one of the notifications we told growl
* about.
* @param inTitle - The Title of our Notification as Growl will show it
* @param inDescription - The Description of our Notification as Growl will
* display it
*
* @throws Exception When a notification is not known
*/
public void notifyGrowlOf(String inNotificationName, String inTitle,
String inDescription) throws Exception {
notifyGrowlOf(inNotificationName, (NSData)null,
inTitle, inDescription, (NSDictionary)null, false);
}
/**
* Convenience method that defers to notifyGrowlOf(String inNotificationName,
* NSData inIconData, String inTitle, String inDescription,
* NSDictionary inExtraInfo, boolean inSticky)
* with null passed for icon and extraInfo arguments
*
* @param inNotificationName - The name of one of the notifications we told growl
* about.
* @param inTitle - The Title of our Notification as Growl will show it
* @param inDescription - The Description of our Notification as Growl will
* display it
* @param inSticky - Whether our notification should be sticky
*
* @throws Exception When a notification is not known
*
*/
public void notifyGrowlOf(String inNotificationName, String inTitle,
String inDescription, boolean inSticky) throws Exception {
notifyGrowlOf(inNotificationName, (NSData)null,
inTitle, inDescription, (NSDictionary)null, inSticky);
}
/**
* Defers to notifyGrowlOf(String inNotificationName, NSData inIconData,
* String inTitle, String inDescription, NSDictionary inExtraInfo) with null
* passed for icon and extraInfo arguments
*
* @param inNotificationName - The name of one of the notifications we told growl
* about.
* @param inImage - The notification image.
* @param inTitle - The Title of our Notification as Growl will show it
* @param inDescription - The Description of our Notification as Growl will
* display it
* @param inExtraInfo - Look above for info
*
* @throws Exception When a notification is not known
*
*/
public void notifyGrowlOf(String inNotificationName, NSImage inImage,
String inTitle, String inDescription,
NSDictionary inExtraInfo) throws Exception {
notifyGrowlOf(inNotificationName, inImage.TIFFRepresentation(),
inTitle, inDescription, inExtraInfo, false);
}
/**
* Convenienve method that defers to notifyGrowlOf(String inNotificationName,
* NSData inIconData, String inTitle, String inDescription,
* NSDictionary inExtraInfo) with null passed for extraInfo
*
* @param inNotificationName - The name of one of the notifications we told growl
* about.
* @param inImagePath - Path to the image for this notification
* @param inTitle - The Title of our Notification as Growl will show it
* @param inDescription - The Description of our Notification as Growl will
* display it
*
* @throws Exception When a notification is not known
*/
public void notifyGrowlOf(String inNotificationName, String inImagePath,
String inTitle, String inDescription) throws Exception {
notifyGrowlOf(inNotificationName,
new NSImage(inImagePath, false).TIFFRepresentation(),
inTitle, inDescription, (NSDictionary)null, false);
}
//************ Accessors **************//
/**
* Accessor for The currently set "Application" Name
*
* @return String - Application Name
*/
public String applicationName() {
return appName;
}
/**
* Accessor for the Array of allowed Notifications returned an NSArray
*
* @return the array of allowed notifications.
*/
public NSArray allowedNotifications() {
return allNotes;
}
/**
* Accessor for the Array of default Notifications returned as an NSArray
*
* @return the array of default notifications.
*/
public NSArray defaultNotifications() {
return defNotes;
}
//************ Mutators **************//
/**
* Sets The name of the Application talking to growl
*
* @param inAppName - The Application Name
*/
public void setApplicationName(String inAppName) {
appName = inAppName;
}
/**
* Set the list of allowed Notifications
*
* @param inAllNotes - The array of allowed Notifications
*/
public void setAllowedNotifications(NSArray inAllNotes) {
allNotes = inAllNotes;
}
/**
* Set the list of allowed Notifications
*
* @param inAllNotes - The array of allowed Notifications
*
*/
public void setAllowedNotifications(String[] inAllNotes) {
allNotes = new NSArray(inAllNotes);
}
/**
* Set the list of Default Notfiications
*
* @param inDefNotes - The default Notifications
*
* @throws Exception when an element of the array is not in the
* allowedNotifications
*/
public void setDefaultNotifications(NSArray inDefNotes) throws Exception {
int stop = inDefNotes.count();
int i = 0;
for(i = 0; i < stop; i++) {
if (!allNotes.containsObject(inDefNotes.objectAtIndex(i))) {
throw new Exception("Array Element not in Allowed Notifications");
}
}
defNotes = inDefNotes;
}
/**
* Set the list of Default Notfiications
*
* @param inDefNotes - The default Notifications
*
* @throws Exception when an element of the array is not in the
* allowedNotifications
*
*/
public void setDefaultNotifications(String [] inDefNotes) throws Exception {
int stop = inDefNotes.length;
int i = 0;
for(i = 0; i < stop; i++) {
if (! allNotes.containsObject(inDefNotes[i])) {
throw new Exception("Array Element not in Allowed Notifications");
}
}
defNotes = new NSArray(inDefNotes);
}
}

View File

@ -0,0 +1,123 @@
/**
* $Revision: 22540 $
* $Date: 2005-10-10 08:44:25 -0700 (Mon, 10 Oct 2005) $
*
* Copyright (C) 1999-2005 Jive Software. All rights reserved.
*
* This software is the proprietary information of Jive Software.
* Use is subject to license terms.
*/
package com.jivesoftware.spark.plugin.growl;
import com.apple.cocoa.application.NSImage;
import com.apple.cocoa.foundation.NSData;
import com.growl.Growl;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.packet.VCard;
import org.jivesoftware.spark.ui.MessageListener;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.SparkManager;
import javax.swing.*;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* @author Andrew Wright
*/
public class GrowlMessageListener implements MessageListener {
private Growl growl;
public GrowlMessageListener() {
String[] notes = {"Message Received"};
growl = new Growl("Spark", notes, notes);
growl.register();
}
public void messageReceived(final ChatRoom room, final Message message) {
if (!SparkManager.getMainWindow().isFocused()) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
String name = SparkManager.getUserManager().getUserNicknameFromJID(message.getFrom());
// Since it looks the method can return null do this in case
if (name == null) {
name = StringUtils.parseName(message.getFrom());
}
VCard vCard = null;
try {
vCard = SparkManager.getVCardManager().getVCard(
StringUtils.parseBareAddress(message.getFrom()));
}
catch (Exception e) {
// vcard can time out so ignore
}
NSImage image = null;
if (vCard != null) {
byte[] bytes = vCard.getAvatar();
if (bytes != null) {
try {
NSData data = new NSData(bytes);
image = new NSImage(data);
}
catch (Exception e) {
// just incase there is an error i didn't intend
}
}
}
if (image == null) {
image = getImage("/images/message-32x32.png");
}
growl.notifyGrowlOf("Message Received", image, name, message.getBody(), null);
}
catch (Exception e) {
Logger.logError(e.getMessage(), e);
}
}
});
}
}
public void messageSent(ChatRoom room, Message message) {
// Ignore
}
/**
* Creates a {@link com.apple.cocoa.application.NSImage} from a string that points to an image in the class
*
* @param image classpath path of an image
* @return an cocoa image object
*/
private NSImage getImage(String image) {
InputStream in = this.getClass().getResourceAsStream(image);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buff = new byte[10 * 1024];
int len;
try {
while ((len = in.read(buff)) != -1) {
out.write(buff, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
Logger.logError(e.getMessage(), e);
}
NSData data = new NSData(out.toByteArray());
return new NSImage(data);
}
}

View File

@ -0,0 +1,45 @@
/**
* $Revision: 22540 $
* $Date: 2005-10-10 08:44:25 -0700 (Mon, 10 Oct 2005) $
*
* Copyright (C) 1999-2005 Jive Software. All rights reserved.
*
* This software is the proprietary information of Jive Software.
* Use is subject to license terms.
*/
package com.jivesoftware.spark.plugin.growl;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.plugin.Plugin;
/**
* Provides support for Growl Notifications on Mac OS X. Growl can be acquired at
* http://growl.info
*
*
* @author Andrew Wright
*/
public class GrowlPlugin implements Plugin {
private GrowlRoomListener growlListener;
public void initialize() {
growlListener = new GrowlRoomListener();
SparkManager.getChatManager().addChatRoomListener(growlListener);
}
public void shutdown() {
SparkManager.getChatManager().removeChatRoomListener(growlListener);
}
public boolean canShutDown() {
return true;
}
public void uninstall() {
SparkManager.getChatManager().removeChatRoomListener(growlListener);
}
}

View File

@ -0,0 +1,50 @@
/**
* $Revision: 22540 $
* $Date: 2005-10-10 08:44:25 -0700 (Mon, 10 Oct 2005) $
*
* Copyright (C) 1999-2005 Jive Software. All rights reserved.
*
* This software is the proprietary information of Jive Software.
* Use is subject to license terms.
*/
package com.jivesoftware.spark.plugin.growl;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.ChatRoomListener;
/**
* @author Andrew Wright
*/
public class GrowlRoomListener implements ChatRoomListener {
private GrowlMessageListener growlMessageListener;
public GrowlRoomListener() {
growlMessageListener = new GrowlMessageListener();
}
public void chatRoomOpened(ChatRoom room) {
room.addMessageListener(growlMessageListener);
}
public void chatRoomLeft(ChatRoom room) {
// Do nothing
}
public void chatRoomClosed(ChatRoom room) {
// Do nothing
}
public void chatRoomActivated(ChatRoom room) {
// Do nothing
}
public void userHasJoined(ChatRoom room, String userid) {
// Do nothing
}
public void userHasLeft(ChatRoom room, String userid) {
// Do nothing
}
}

View File

@ -0,0 +1,10 @@
<plugin>
<name>Growl Plugin</name>
<version>1.0</version>
<author>Andrew Wright</author>
<homePage>http://www.jivesoftware.com</homePage>
<email>andrew@jivesoftware.com</email>
<description>Provides Growl notifications on Mac OS X.(http://growl.info)</description>
<class>org.jivesoftware.spark.plugin.growl.GrowlPlugin</class>
<minSparkVersion>2.0.0.1</minSparkVersion>
</plugin>