blob: 926636d53546f2569ee559750eaac370fa446157 [file] [log] [blame]
package org.apache.maven.extensions.eventsound;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineEvent.Type;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import org.apache.maven.eventspy.AbstractEventSpy;
import org.apache.maven.execution.ExecutionEvent;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
@Named
@Singleton
public class SoundPlayingListener extends AbstractEventSpy implements LogEnabled
{
private Logger logger;
private Properties properties = new Properties();
private Path config;
@Override
public void enableLogging( Logger logger )
{
this.logger = logger;
}
@Override
public void init( Context context )
throws Exception
{
String mavenHome = System.getProperty( "maven.home" );
config = Paths.get( mavenHome, "conf/ext/eventsound.properties").normalize();
if ( !Files.isRegularFile( config ) )
{
// TODO write properties file template with all available properties
logger.error( "MISSING " + config.toString() );
}
try ( InputStream is = new FileInputStream( config.toFile() ) )
{
properties.load( is );
}
}
@Override
public void onEvent( Object event )
throws Exception
{
if ( event instanceof ExecutionEvent )
{
ExecutionEvent executionEvent = (ExecutionEvent) event;
if ( !executionEvent.getSession().getRequest().isInteractiveMode() )
{
// prevents activity when using maven-invoker-plugin during ITs
return;
}
if ( executionEvent.getType() == ExecutionEvent.Type.SessionEnded )
{
String key;
if ( executionEvent.getSession().getResult().hasExceptions() )
{
key = "executionEvent.session.failure.audiofile";
}
else
{
key = "executionEvent.session.success.audiofile";
}
String value = properties.getProperty( key );
if ( value != null )
{
Path mediafile = config.getParent().resolve( value );
Thread t = new Thread( new Player( mediafile ) );
t.run();
}
}
}
}
private class Player
implements Runnable
{
private final Path mediafile;
Player( Path mediafile )
{
this.mediafile = mediafile;
}
public void run()
{
final AudioListener listener = new AudioListener();
try ( Clip clip = AudioSystem.getClip();
AudioInputStream ais = AudioSystem.getAudioInputStream( mediafile.toFile() ) )
{
clip.addLineListener( listener );
clip.open( ais );
clip.start();
listener.waitUntilDone();
}
catch ( IOException | UnsupportedAudioFileException | LineUnavailableException e )
{
e.printStackTrace();
}
catch ( InterruptedException e )
{
// noop
}
}
}
/**
* Ensure files is being played until the end
*
* @author Robert Scholte
* @since 1.0.0
*/
static class AudioListener
implements LineListener
{
private boolean done = false;
@Override
public synchronized void update( LineEvent event )
{
Type eventType = event.getType();
if ( eventType == Type.STOP || eventType == Type.CLOSE )
{
done = true;
notifyAll();
}
}
public synchronized void waitUntilDone()
throws InterruptedException
{
while ( !done )
{
wait();
}
}
}
}