001package ca.bc.webarts.tools.mythtv;
002
003import java.util.ArrayList;
004import java.util.List;
005import java.util.concurrent.ExecutorService;
006import java.util.concurrent.Executors;
007import java.util.concurrent.Future;
008
009import com.dpillay.tools.tail4j.core.*;
010
011public class MythTVTailExecutor
012{
013  public <T, S> void execute(List<TailedReader<T, S>> tailedFiles,TailDoer<T> doer)
014  {
015    ExecutorService executor = Executors.newFixedThreadPool(tailedFiles.size() + 1);
016    TaskChecker<T> taskCheck = new TaskChecker<T>(executor);
017    for (TailedReader<T, S> tailedFile : tailedFiles)
018    {
019      Future<T> future = executor.submit(tailedFile);
020      taskCheck.getFutures().add(future);
021    }
022    new Thread(taskCheck).start();
023    executor.submit(doer);
024  }
025
026  private static class TaskChecker<T> implements Runnable
027  {
028    private List<Future<T>> futures = new ArrayList<Future<T>>();
029    private ExecutorService executorService = null;
030
031    public TaskChecker(ExecutorService executorService)
032    {
033      super();
034      this.executorService = executorService;
035    }
036
037    public List<Future<T>> getFutures()
038    {
039      return futures;
040    }
041
042    @Override
043    public void run()
044    {
045      while (!this.isDone())
046      {
047        try {
048          Thread.sleep(200);
049        }
050        catch (InterruptedException e)
051        {
052          // FIXME
053        }
054      }
055      this.executorService.shutdownNow();
056    }
057
058    public boolean isDone()
059    {
060      for (Future<T> future : this.futures)
061      {
062        if (!(future.isCancelled() || future.isDone()))
063        {
064          return false;
065        }
066      }
067      return true;
068    }
069  }
070}