/*
 *  Copyright 2007 Nate Drake
 * 
 *  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 net.slimeslurp.growl;

import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.BuildEvent;

import com.binaryblizzard.growl.Growl;
import com.binaryblizzard.growl.GrowlException;
import com.binaryblizzard.growl.GrowlNotification;
import com.binaryblizzard.growl.GrowlRegistrations;

/**
 * BuildListener that displays information on the current build
 * via Growl/JGrowl.
 *
 *
 * TODO:
 * o Read some things from a properties file (i.e. host, passwd, etc.)
 *
 * @author ndrake
 *
 */
public class GrowlListener implements BuildListener {

    private static final String APP_NAME = "Ant";
    private static final String GROWL_HOST = "localhost";
    private static final String GROWL_PASSWD = null;
    private Growl growl;

    public GrowlListener() {
        try {

            // Register with Growl/JGrowl
            growl = new Growl();

            growl.addGrowlHost(GROWL_HOST, GROWL_PASSWD);
            GrowlRegistrations registrations = growl.getRegistrations(APP_NAME);
            registrations.registerNotification(APP_NAME, true);
        } catch(GrowlException e) {
            e.printStackTrace();
        }
    }

    /**
     * Called when the build is started.
     *
     * @param event
     */
    public void buildStarted(BuildEvent event) {
        sendMessage("Build starting...",
                    GrowlNotification.NORMAL);
    }

    /**
     * Called when the build is finished.
     *
     * @param event
     */
    public void buildFinished(BuildEvent event) {
        Throwable t = event.getException();
        String projectName = event.getProject().getName();
        if (t != null) {
            sendMessage("Build failed: " + t.toString(), 
                        GrowlNotification.HIGH);
            return;
        }
        sendMessage("Build finished for " + projectName, 
                    GrowlNotification.NORMAL);
    }

    // Other messages are currently ignored
    public void messageLogged(BuildEvent event) { }
    public void targetFinished(BuildEvent event) {}
    public void targetStarted(BuildEvent event) {}
    public void taskFinished(BuildEvent event) {}
    public void taskStarted(BuildEvent event) {}


    /**
     * Send a message to Growl/JGrowl.
     *
     * @param msg The message
     * @param priority The message priority
     */
    protected void sendMessage(String msg, int priority) {
        try {
            growl.sendNotification(new GrowlNotification(APP_NAME, 
                                                         APP_NAME, 
                                                         msg, 
                                                         APP_NAME, 
                                                         false, 
                                                         priority));
        } catch(GrowlException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        GrowlListener gl = new GrowlListener();
        gl.sendMessage("Testing Testing", GrowlNotification.NORMAL);
    }
}
@@ -637,16 +637,45 @@
 growl;%0A%0A
+import java.util.Hashtable;%0A%0A
 import o
@@ -1386,16 +1386,89 @@
 growl;%0A%0A
+    private static final String FINISHED_STICKY_NAME = %22gbl.endsticky%22;%0A%0A
     publ
@@ -2078,32 +2078,39 @@
 ification.NORMAL
+, false
 );%0A    %7D%0A%0A    /*
@@ -2337,24 +2337,343 @@
 .getName();%0A
+        Hashtable props = event.getProject().getProperties();%0A        boolean sticky = false;%0A%0A        // Check if this message should be sticky or not%0A        if(props != null && props.containsKey(FINISHED_STICKY_NAME)) %7B%0A            sticky = Boolean.parseBoolean((String)props.get(FINISHED_STICKY_NAME));%0A        %7D %0A%0A
         if (
@@ -2789,16 +2789,24 @@
 ion.HIGH
+, sticky
 );%0A     
@@ -2924,32 +2924,40 @@
 ification.NORMAL
+, sticky
 );%0A    %7D%0A%0A    //
@@ -3378,16 +3378,78 @@
 riority%0A
+     * @param sticky If true, notification should be %22sticky%22%0A
      */%0A
@@ -3503,16 +3503,32 @@
 priority
+, boolean sticky
 ) %7B%0A    
@@ -3861,21 +3861,22 @@
         
-false
+sticky
 , %0A     
@@ -4184,16 +4184,23 @@
 n.NORMAL
+, false
 );%0A    %7D

Check for a property called gbl.endsticky to determine if the Build Finished notification should be sticky