Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 270   Methods: 14
NCLOC: 110   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AntSoundPlayer.java 0% 0% 0% 0%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 
 55   
 package org.apache.tools.ant.taskdefs.optional.sound;
 56   
 
 57   
 // ant includes
 58   
 import java.io.File;
 59   
 import java.io.IOException;
 60   
 import javax.sound.sampled.AudioFormat;
 61   
 import javax.sound.sampled.AudioInputStream;
 62   
 import javax.sound.sampled.AudioSystem;
 63   
 import javax.sound.sampled.Clip;
 64   
 import javax.sound.sampled.DataLine;
 65   
 import javax.sound.sampled.Line;
 66   
 import javax.sound.sampled.LineEvent;
 67   
 import javax.sound.sampled.LineListener;
 68   
 import javax.sound.sampled.LineUnavailableException;
 69   
 import javax.sound.sampled.UnsupportedAudioFileException;
 70   
 import org.apache.tools.ant.BuildEvent;
 71   
 import org.apache.tools.ant.BuildListener;
 72   
 import org.apache.tools.ant.Project;
 73   
 
 74   
 
 75   
 
 76   
 /**
 77   
  * This class is designed to be used by any AntTask that requires audio output.
 78   
  *
 79   
  * It implements the BuildListener interface to listen for BuildEvents and could
 80   
  * be easily extended to provide audio output upon any specific build events occuring.
 81   
  *
 82   
  * I have only tested this with .WAV and .AIFF sound file formats. Both seem to work fine.
 83   
  *
 84   
  * @author Nick Pellow
 85   
  * @version $Revision: 1.11 $, $Date: 2003/02/10 14:14:26 $
 86   
  */
 87   
 
 88   
 public class AntSoundPlayer implements LineListener, BuildListener {
 89   
 
 90   
     private File fileSuccess = null;
 91   
     private int loopsSuccess = 0;
 92   
     private Long durationSuccess = null;
 93   
 
 94   
     private File fileFail = null;
 95   
     private int loopsFail = 0;
 96   
     private Long durationFail = null;
 97   
 
 98  0
     public AntSoundPlayer() {
 99   
 
 100   
     }
 101   
 
 102   
     /**
 103   
      * @param source the location of the audio file to be played when the build is successful
 104   
      * @param loops the number of times the file should be played when the build is successful
 105   
      * @param duration the number of milliseconds the file should be played when the build is successful
 106   
      */
 107  0
     public void addBuildSuccessfulSound(File file, int loops, Long duration) {
 108  0
         this.fileSuccess = file;
 109  0
         this.loopsSuccess = loops;
 110  0
         this.durationSuccess = duration;
 111   
     }
 112   
 
 113   
 
 114   
     /**
 115   
      * @param fileName the location of the audio file to be played when the build fails
 116   
      * @param loops the number of times the file should be played when the build is fails
 117   
      * @param duration the number of milliseconds the file should be played when the build fails
 118   
      */
 119  0
     public void addBuildFailedSound(File fileFail, int loopsFail, Long durationFail) {
 120  0
         this.fileFail = fileFail;
 121  0
         this.loopsFail = loopsFail;
 122  0
         this.durationFail = durationFail;
 123   
     }
 124   
 
 125   
     /**
 126   
      * Plays the file for duration milliseconds or loops.
 127   
      */
 128  0
     private void play(Project project, File file, int loops, Long duration) {
 129   
 
 130  0
         Clip audioClip = null;
 131   
 
 132  0
         AudioInputStream audioInputStream = null;
 133   
 
 134   
 
 135  0
         try {
 136  0
             audioInputStream = AudioSystem.getAudioInputStream(file);
 137   
         } catch (UnsupportedAudioFileException uafe) {
 138  0
             project.log("Audio format is not yet supported: " 
 139   
                 + uafe.getMessage());
 140   
         } catch (IOException ioe) {
 141  0
             ioe.printStackTrace();
 142   
         }
 143   
 
 144  0
         if (audioInputStream != null) {
 145  0
             AudioFormat format = audioInputStream.getFormat();
 146  0
             DataLine.Info   info = new DataLine.Info(Clip.class, format,
 147   
                                              AudioSystem.NOT_SPECIFIED);
 148  0
             try {
 149  0
                 audioClip = (Clip) AudioSystem.getLine(info);
 150  0
                 audioClip.addLineListener(this);
 151  0
                 audioClip.open(audioInputStream);
 152   
             } catch (LineUnavailableException e) {
 153  0
                 project.log("The sound device is currently unavailable");
 154  0
                 return;
 155   
             } catch (IOException e) {
 156  0
                 e.printStackTrace();
 157   
             }
 158   
 
 159  0
             if (duration != null) {
 160  0
                 playClip(audioClip, duration.longValue());
 161   
             } else {
 162  0
                 playClip(audioClip, loops);
 163   
             }
 164  0
             audioClip.drain();
 165  0
             audioClip.close();
 166   
         } else {
 167  0
             project.log("Can't get data from file " + file.getName());
 168   
         }
 169   
     }
 170   
 
 171  0
     private void playClip(Clip clip, int loops) {
 172   
 
 173  0
         clip.loop(loops);
 174  0
         while (clip.isRunning()) {
 175   
         }
 176   
     }
 177   
 
 178  0
     private void playClip(Clip clip, long duration) {
 179  0
         clip.loop(Clip.LOOP_CONTINUOUSLY);
 180  0
         try {
 181  0
             Thread.sleep(duration);
 182   
         } catch (InterruptedException e) {
 183   
         }
 184   
     }
 185   
 
 186   
     /**
 187   
      * This is implemented to listen for any line events and closes the
 188   
      * clip if required.
 189   
      */
 190  0
     public void update(LineEvent event) {
 191  0
         if (event.getType().equals(LineEvent.Type.STOP)) {
 192  0
             Line line = event.getLine();
 193  0
             line.close();
 194  0
         } else if (event.getType().equals(LineEvent.Type.CLOSE)) {
 195   
             /*
 196   
              *  There is a bug in JavaSound 0.90 (jdk1.3beta).
 197   
              *  It prevents correct termination of the VM.
 198   
              *  So we have to exit ourselves.
 199   
              */
 200   
             //System.exit(0);
 201   
         }
 202   
     }
 203   
 
 204   
 
 205   
     /**
 206   
      *  Fired before any targets are started.
 207   
      */
 208  0
     public void buildStarted(BuildEvent event){
 209   
     }
 210   
 
 211   
     /**
 212   
      *  Fired after the last target has finished. This event
 213   
      *  will still be thrown if an error occured during the build.
 214   
      *
 215   
      *  @see BuildEvent#getException()
 216   
      */
 217  0
     public void buildFinished(BuildEvent event){
 218  0
         if (event.getException() == null && fileSuccess != null) {
 219   
             // build successfull!
 220  0
             play(event.getProject(), fileSuccess, loopsSuccess, durationSuccess);
 221  0
         } else if (event.getException() != null && fileFail != null) {
 222  0
             play(event.getProject(), fileFail, loopsFail, durationFail);
 223   
         }
 224   
     }
 225   
 
 226   
     /**
 227   
      *  Fired when a target is started.
 228   
      *
 229   
      *  @see BuildEvent#getTarget()
 230   
      */
 231  0
     public void targetStarted(BuildEvent event){
 232   
     }
 233   
 
 234   
     /**
 235   
      *  Fired when a target has finished. This event will
 236   
      *  still be thrown if an error occured during the build.
 237   
      *
 238   
      *  @see BuildEvent#getException()
 239   
      */
 240  0
     public void targetFinished(BuildEvent event){
 241   
     }
 242   
 
 243   
     /**
 244   
      *  Fired when a task is started.
 245   
      *
 246   
      *  @see BuildEvent#getTask()
 247   
      */
 248  0
     public void taskStarted(BuildEvent event){
 249   
     }
 250   
 
 251   
     /**
 252   
      *  Fired when a task has finished. This event will still
 253   
      *  be throw if an error occured during the build.
 254   
      *
 255   
      *  @see BuildEvent#getException()
 256   
      */
 257  0
     public void taskFinished(BuildEvent event){
 258   
     }
 259   
 
 260   
     /**
 261   
      *  Fired whenever a message is logged.
 262   
      *
 263   
      *  @see BuildEvent#getMessage()
 264   
      *  @see BuildEvent#getPriority()
 265   
      */
 266  0
     public void messageLogged(BuildEvent event){
 267   
     }
 268   
 }
 269   
 
 270