001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.tools.ant.taskdefs.optional.sound;
020:
021: import java.io.File;
022: import java.util.Random;
023: import java.util.Vector;
024: import org.apache.tools.ant.BuildException;
025: import org.apache.tools.ant.Project;
026: import org.apache.tools.ant.Task;
027:
028: /**
029: * Plays a sound file at the end of the build, according to whether the build failed or succeeded.
030: *
031: * There are three attributes to be set:
032: *
033: * <code>source</code>: the location of the audio file to be played
034: * <code>duration</code>: play the sound file continuously until "duration" milliseconds has expired
035: * <code>loops</code>: the number of times the sound file should be played until stopped
036: *
037: * I have only tested this with .WAV and .AIFF sound file formats. Both seem
038: * to work fine.
039: *
040: * plans for the future:
041: * - use the midi api to define sounds (or drum beat etc) in xml and have
042: * Ant play them back
043: *
044: */
045:
046: public class SoundTask extends Task {
047:
048: private BuildAlert success = null;
049: private BuildAlert fail = null;
050:
051: /**
052: * add a sound when the build succeeds
053: * @return a BuildAlert to be configured
054: */
055: public BuildAlert createSuccess() {
056: success = new BuildAlert();
057: return success;
058: }
059:
060: /**
061: * add a sound when the build fails
062: * @return a BuildAlert to be configured
063: */
064: public BuildAlert createFail() {
065: fail = new BuildAlert();
066: return fail;
067: }
068:
069: /** Constructor for SoundTask. */
070: public SoundTask() {
071: }
072:
073: /**
074: * Initialize the task.
075: */
076: public void init() {
077: }
078:
079: /**
080: * Execute the task.
081: */
082: public void execute() {
083:
084: AntSoundPlayer soundPlayer = new AntSoundPlayer();
085:
086: if (success == null) {
087: log("No nested success element found.", Project.MSG_WARN);
088: } else {
089: soundPlayer.addBuildSuccessfulSound(success.getSource(),
090: success.getLoops(), success.getDuration());
091: }
092:
093: if (fail == null) {
094: log("No nested failure element found.", Project.MSG_WARN);
095: } else {
096: soundPlayer.addBuildFailedSound(fail.getSource(), fail
097: .getLoops(), fail.getDuration());
098: }
099:
100: getProject().addBuildListener(soundPlayer);
101:
102: }
103:
104: /**
105: * A class to be extended by any BuildAlert's that require the output
106: * of sound.
107: */
108: public class BuildAlert {
109: private File source = null;
110: private int loops = 0;
111: private Long duration = null;
112:
113: /**
114: * Sets the duration in milliseconds the file should be played; optional.
115: * @param duration the duration in millisconds
116: */
117: public void setDuration(Long duration) {
118: this .duration = duration;
119: }
120:
121: /**
122: * Sets the location of the file to get the audio; required.
123: *
124: * @param source the name of a sound-file directory or of the audio file
125: */
126: public void setSource(File source) {
127: this .source = source;
128: }
129:
130: /**
131: * Sets the number of times the source file should be played; optional.
132: *
133: * @param loops the number of loops to play the source file
134: */
135: public void setLoops(int loops) {
136: this .loops = loops;
137: }
138:
139: /**
140: * Gets the location of the file to get the audio.
141: * @return the file location
142: */
143: public File getSource() {
144: File nofile = null;
145: // Check if source is a directory
146: if (source.exists()) {
147: if (source.isDirectory()) {
148: // get the list of files in the dir
149: String[] entries = source.list();
150: Vector files = new Vector();
151: for (int i = 0; i < entries.length; i++) {
152: File f = new File(source, entries[i]);
153: if (f.isFile()) {
154: files.addElement(f);
155: }
156: }
157: if (files.size() < 1) {
158: throw new BuildException(
159: "No files found in directory " + source);
160: }
161: int numfiles = files.size();
162: // get a random number between 0 and the number of files
163: Random rn = new Random();
164: int x = rn.nextInt(numfiles);
165: // set the source to the file at that location
166: this .source = (File) files.elementAt(x);
167: }
168: } else {
169: log(source + ": invalid path.", Project.MSG_WARN);
170: this .source = nofile;
171: }
172: return this .source;
173: }
174:
175: /**
176: * Sets the number of times the source file should be played.
177: *
178: * @return the number of loops to play the source file
179: */
180: public int getLoops() {
181: return this .loops;
182: }
183:
184: /**
185: * Gets the duration in milliseconds the file should be played.
186: * @return the duration in milliseconds
187: */
188: public Long getDuration() {
189: return this.duration;
190: }
191: }
192: }
|