Improve Growl exception handling, remove System.out and a few fixes from audit

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1048 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2010-05-13 12:48:10 +00:00
parent 437837e21c
commit a7c218857b
3 changed files with 204 additions and 229 deletions

View File

@ -37,175 +37,144 @@ import javax.imageio.ImageIO;
/** /**
* Growl notification implementation. This uses JNI to send messages to Growl. * Growl notification implementation. This uses JNI to send messages to Growl.
* *
* @author Michael Stringer * @author Michael Stringer
* @version 0.1 * @version 0.1
*/ */
class GrowlNative implements Growl { class GrowlNative implements Growl {
private String appName; private final String appName;
private List<NotificationType> notifications; private final List<NotificationType> notifications;
private List<GrowlCallbackListener> callbackListeners; private final List<GrowlCallbackListener> callbackListeners;
private byte[] imageData; private byte[] imageData;
private native void sendNotification(String appName, String name, private native void sendNotification(String appName, String name,
String title, String message, String callbackContext, byte[] icon); String title, String message, String callbackContext, byte[] icon);
private native void registerApp(String appName, byte[] image, private native void registerApp(String appName, byte[] image,
List<NotificationType> notifications); List<NotificationType> notifications);
/** /**
* Creates a new <code>GrowlNative</code> instance for the specified * Creates a new <code>GrowlNative</code> instance for the specified
* application name. * application name.
* *
* @param appName * @param appName The name of the application sending notifications.
* The name of the application sending notifications.
*/ */
GrowlNative(String appName) { GrowlNative(String appName) {
notifications = new ArrayList<NotificationType>(); notifications = new ArrayList<NotificationType>();
callbackListeners = new ArrayList<GrowlCallbackListener>(); callbackListeners = new ArrayList<GrowlCallbackListener>();
this.appName = appName; this.appName = appName;
} }
@SuppressWarnings({"UnusedDeclaration"})
void fireCallbacks(String callbackContext) { void fireCallbacks(String callbackContext) {
for (GrowlCallbackListener listener : callbackListeners) { for (GrowlCallbackListener listener : callbackListeners) {
listener.notificationWasClicked(callbackContext); listener.notificationWasClicked(callbackContext);
} }
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void register() throws GrowlException { public void register() throws GrowlException {
registerApp(appName, imageData, notifications); registerApp(appName, imageData, notifications);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void addNotification(String name, boolean enabledByDefault) { public void addNotification(String name, boolean enabledByDefault) {
notifications.add(new NotificationType(name, enabledByDefault)); notifications.add(new NotificationType(name, enabledByDefault));
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void addCallbackListener(GrowlCallbackListener listener) { public void addCallbackListener(GrowlCallbackListener listener) {
callbackListeners.add(listener); callbackListeners.add(listener);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setIcon(RenderedImage icon) throws GrowlException { public void setIcon(RenderedImage icon) throws GrowlException {
try { imageData = convertImage(icon);
ByteArrayOutputStream baos = new ByteArrayOutputStream(); }
ImageIO.write(icon, "png", baos);
imageData = baos.toByteArray(); protected byte[] convertImage(RenderedImage icon) throws GrowlException {
} catch (IOException e) { if (icon == null) {
// TODO Auto-generated catch block return null;
e.printStackTrace(); }
} ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ImageIO.write(icon, "png", baos);
} catch (IOException ioe) {
throw new GrowlException("Failed to convert Image", ioe);
}
return baos.toByteArray();
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void sendNotification(String name, String title, String body) public void sendNotification(String name, String title, String body)
throws GrowlException { throws GrowlException {
if (!notifications.contains(new NotificationType(name, false))) { sendNotification(name, title, body, null, null);
System.out.println("contains: " + notifications);
throw new GrowlException("Unregistered notification name [" + name
+ "]");
}
sendNotification(appName, name, title, body, null, null);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void sendNotification(String name, String title, String body, public void sendNotification(String name, String title, String body, RenderedImage icon) throws GrowlException {
RenderedImage icon) throws GrowlException { sendNotification(name, title, body, null, icon);
if (!notifications.contains(new NotificationType(name, false))) {
System.out.println("contains: " + notifications);
throw new GrowlException("Unregistered notification name [" + name
+ "]");
}
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(icon, "png", baos);
byte[] image = baos.toByteArray();
sendNotification(appName, name, title, body, null, image);
} catch (IOException ioe) {
throw new GrowlException("Failed to convert Image", ioe);
}
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void sendNotification(String name, String title, String body, public void sendNotification(String name, String title, String body, String callbackContext) throws GrowlException {
String callbackContext) throws GrowlException { sendNotification(name, title, body, callbackContext, null);
if (!notifications.contains(new NotificationType(name, false))) {
System.out.println("contains: " + notifications);
throw new GrowlException("Unregistered notification name [" + name
+ "]");
}
sendNotification(appName, name, title, body, callbackContext, null);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void sendNotification(String name, String title, String body, public void sendNotification(String name, String title, String body, String callbackContext, RenderedImage icon)
String callbackContext, RenderedImage icon) throws GrowlException { throws GrowlException {
if (!notifications.contains(new NotificationType(name, false))) { if (!notifications.contains(new NotificationType(name, false))) {
System.out.println("contains: " + notifications); throw new GrowlException("Unregistered notification name [" + name + ']');
throw new GrowlException("Unregistered notification name [" + name }
+ "]");
}
try { sendNotification(appName, name, title, body, callbackContext, convertImage(icon));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(icon, "png", baos);
byte[] image = baos.toByteArray();
sendNotification(appName, name, title, body, callbackContext, image);
} catch (IOException ioe) {
throw new GrowlException("Failed to convert Image", ioe);
}
} }
private class NotificationType { private class NotificationType {
private String name; private final String name;
private boolean enabledByDefault; private final boolean enabledByDefault;
public NotificationType(String name, boolean enabledByDefault) { private NotificationType(String name, boolean enabledByDefault) {
this.name = name; this.name = name;
this.enabledByDefault = enabledByDefault; this.enabledByDefault = enabledByDefault;
} }
public String getName() { @SuppressWarnings({"UnusedDeclaration"})
return name; public String getName() {
} return name;
}
public boolean isEnabledByDefault() { @SuppressWarnings({"UnusedDeclaration"})
return enabledByDefault; public boolean isEnabledByDefault() {
} return enabledByDefault;
}
public boolean equals(Object other) { @Override
if (!(other instanceof NotificationType)) { public boolean equals(Object other) {
return false; return (other instanceof NotificationType) &&
} name.equals(((NotificationType) other).name);
}
NotificationType otherType = (NotificationType) other; @Override
public int hashCode() {
return name.equals(otherType.name); return name.hashCode();
} }
} }
} }

View File

@ -32,65 +32,65 @@ import java.util.Map;
/** /**
* Utility class for sending notifications using Growl. * Utility class for sending notifications using Growl.
* *
* @author Michael Stringer * @author Michael Stringer
* @version 0.1 * @version 0.1
*/ */
public final class GrowlUtils { public final class GrowlUtils {
private static final boolean GROWL_LOADED; private static final boolean GROWL_LOADED;
private static Map<String, Growl> instances = new HashMap<String, Growl>(); private static final Map<String, Growl> instances = new HashMap<String, Growl>();
static { static {
boolean loaded = false; boolean loaded = false;
try { try {
System.loadLibrary("growl"); System.loadLibrary("growl");
loaded = true; loaded = true;
} catch (UnsatisfiedLinkError ule) { } catch (UnsatisfiedLinkError ule) {
System.out.println("Failed to load Growl library"); // ignore: growl not available
} }
GROWL_LOADED = loaded; GROWL_LOADED = loaded;
} }
/** /**
* Utility method - should not be instantiated. * Utility method - should not be instantiated.
*/ */
private GrowlUtils() { private GrowlUtils() {
} }
/** /**
* Gets a <code>Growl</code> instance to use for the specified application * Gets a <code>Growl</code> instance to use for the specified application
* name. Multiple calls to this method will return the same instance. * name. Multiple calls to this method will return the same instance.
* *
* @param appName * @param appName The name of the application.
* The name of the application.
* @return The <code>Growl</code> instance to use. * @return The <code>Growl</code> instance to use.
*/ */
public static Growl getGrowlInstance(String appName) { public static Growl getGrowlInstance(String appName) {
Growl instance = instances.get(appName); synchronized (instances) {
Growl instance = instances.get(appName);
if (instance == null) { if (instance == null) {
if (GROWL_LOADED) { if (GROWL_LOADED) {
instance = new GrowlNative(appName); instance = new GrowlNative(appName);
} else { } else {
instance = new DummyGrowl(); instance = new DummyGrowl();
} }
instances.put(appName, instance); instances.put(appName, instance);
} }
return instance; return instance;
}
} }
/** /**
* Gets whether messages can be sent to Growl. If this returns * Gets whether messages can be sent to Growl. If this returns
* <code>false</code> then {@link #getGrowlInstance(String)} will return a * <code>false</code> then {@link #getGrowlInstance(String)} will return a
* dummy object. * dummy object.
* *
* @return <code>true</code> if messages can be sent to Growl. * @return <code>true</code> if messages can be sent to Growl.
*/ */
public static boolean isGrowlLoaded() { public static boolean isGrowlLoaded() {
return GROWL_LOADED; return GROWL_LOADED;
} }
} }

View File

@ -47,7 +47,7 @@ import javax.swing.SwingUtilities;
/** /**
* Simple test class for Growl. * Simple test class for Growl.
* *
* @author Michael Stringer * @author Michael Stringer
* @version 0.1 * @version 0.1
*/ */
@ -55,132 +55,138 @@ public class TestGrowl extends JFrame {
private static final String APP_NAME = "Test Java App"; private static final String APP_NAME = "Test Java App";
private static final String NOTIF_3_CALLBACK = "Notif3"; private static final String NOTIF_3_CALLBACK = "Notif3";
/**
* Test Growl.
*/
public TestGrowl() { public TestGrowl() {
super("Growl for Java"); super("Growl for Java");
setSize(320, 290); setSize(320, 290);
buildComponents(); buildComponents();
setVisible(true); setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE); setDefaultCloseOperation(EXIT_ON_CLOSE);
} }
private void buildComponents() { private void buildComponents() {
getContentPane().setLayout(new GridLayout(6, 1)); getContentPane().setLayout(new GridLayout(6, 1));
Action action = new AbstractAction("Register") { Action action = new AbstractAction("Register") {
public void actionPerformed(ActionEvent ae) { public void actionPerformed(ActionEvent ae) {
try { try {
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME); Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
growl.addNotification("Test Notification 1", true); growl.addNotification("Test Notification 1", true);
growl.addNotification("Test Notification 2", false); growl.addNotification("Test Notification 2", false);
growl.addNotification("Test Notification 3", true); growl.addNotification("Test Notification 3", true);
GrowlCallbackListener listener = new GrowlCallbackListener() { GrowlCallbackListener listener = new GrowlCallbackListener() {
public void notificationWasClicked( public void notificationWasClicked(
final String clickContext) { final String clickContext) {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
if (NOTIF_3_CALLBACK.equals(clickContext)) { if (NOTIF_3_CALLBACK.equals(clickContext)) {
JOptionPane JOptionPane
.showMessageDialog( .showMessageDialog(
TestGrowl.this, TestGrowl.this,
"User clicked on 'Test Notification 3'"); "User clicked on 'Test Notification 3'");
} }
} }
}); });
} }
}; };
growl.addCallbackListener(listener); growl.addCallbackListener(listener);
growl.register(); growl.register();
} catch (GrowlException ge) { } catch (GrowlException ge) {
ge.printStackTrace(); ge.printStackTrace();
} }
} }
}; };
getContentPane().add(new JButton(action)); getContentPane().add(new JButton(action));
action = new AbstractAction("Send 'Test Notification 1'") { action = new AbstractAction("Send 'Test Notification 1'") {
public void actionPerformed(ActionEvent ae) { public void actionPerformed(ActionEvent ae) {
try { try {
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME); Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
growl.sendNotification("Test Notification 1", growl.sendNotification("Test Notification 1",
"Test Notif 1", "This is a test"); "Test Notif 1", "This is a test");
} catch (GrowlException ge) { } catch (GrowlException ge) {
ge.printStackTrace(); ge.printStackTrace();
} }
} }
}; };
getContentPane().add(new JButton(action)); getContentPane().add(new JButton(action));
action = new AbstractAction("Send 'Test Notification 2'") { action = new AbstractAction("Send 'Test Notification 2'") {
public void actionPerformed(ActionEvent ae) { public void actionPerformed(ActionEvent ae) {
try { try {
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME); Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
BufferedImage image = ImageIO.read(TestGrowl.class BufferedImage image = ImageIO.read(TestGrowl.class
.getResource("/images/duke.gif")); .getResource("/images/duke.gif"));
growl.sendNotification("Test Notification 2", growl.sendNotification("Test Notification 2",
"Test Notif 2", "This is another test", image); "Test Notif 2", "This is another test", image);
} catch (GrowlException ge) { } catch (GrowlException ge) {
ge.printStackTrace(); ge.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block e.printStackTrace();
e.printStackTrace(); }
} }
} };
}; getContentPane().add(new JButton(action));
getContentPane().add(new JButton(action));
action = new AbstractAction("Test Callback 'Notification 3'") { action = new AbstractAction("Test Callback 'Notification 3'") {
public void actionPerformed(ActionEvent ae) { public void actionPerformed(ActionEvent ae) {
try { try {
Growl growl = GrowlUtils.getGrowlInstance(APP_NAME); Growl growl = GrowlUtils.getGrowlInstance(APP_NAME);
growl.sendNotification("Test Notification 3", growl.sendNotification("Test Notification 3",
"Callback Test", "Click me - I dares you!", NOTIF_3_CALLBACK); "Callback Test", "Click me - I dares you!", NOTIF_3_CALLBACK);
} catch (GrowlException ge) { } catch (GrowlException ge) {
ge.printStackTrace(); ge.printStackTrace();
} }
} }
}; };
getContentPane().add(new JButton(action)); getContentPane().add(new JButton(action));
action = new AbstractAction("Reg & Test App 2") { action = new AbstractAction("Reg & Test App 2") {
public void actionPerformed(ActionEvent ae) { public void actionPerformed(ActionEvent ae) {
try { try {
Growl growl = GrowlUtils.getGrowlInstance("Other App"); Growl growl = GrowlUtils.getGrowlInstance("Other App");
growl.addNotification("A Notification", true); growl.addNotification("A Notification", true);
BufferedImage image = ImageIO.read(TestGrowl.class BufferedImage image = ImageIO.read(TestGrowl.class
.getResource("/images/duke.gif")); .getResource("/images/duke.gif"));
growl.setIcon(image); growl.setIcon(image);
growl.register(); growl.register();
growl.sendNotification("A Notification", "Testin", growl.sendNotification("A Notification", "Testin",
"Blah de blah blah"); "Blah de blah blah");
} catch (GrowlException ge) { } catch (GrowlException ge) {
ge.printStackTrace(); ge.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block e.printStackTrace();
e.printStackTrace(); }
} }
} };
}; getContentPane().add(new JButton(action));
getContentPane().add(new JButton(action));
action = new AbstractAction("Exit") { action = new AbstractAction("Exit") {
public void actionPerformed(ActionEvent ae) { public void actionPerformed(ActionEvent ae) {
System.exit(0); System.exit(0);
} }
}; };
getContentPane().add(new JButton(action)); getContentPane().add(new JButton(action));
} }
public static final void main(String[] args) { /**
new TestGrowl(); * Test growl.
* @param args args
*/
public static void main(String[] args) {
//noinspection ResultOfObjectAllocationIgnored
new TestGrowl();
} }
} }