001package com.dpillay.tools.tail4j.core;
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
009public class TailExecutor {
010        public <T, S> void execute(List<TailedReader<T, S>> tailedFiles,
011                        TailPrinter<T> printer) {
012                ExecutorService executor = Executors.newFixedThreadPool(tailedFiles
013                                .size() + 1);
014                TaskChecker<T> taskCheck = new TaskChecker<T>(executor);
015                for (TailedReader<T, S> tailedFile : tailedFiles) {
016                        Future<T> future = executor.submit(tailedFile);
017                        taskCheck.getFutures().add(future);
018                }
019                new Thread(taskCheck).start();
020                executor.submit(printer);
021        }
022
023        private static class TaskChecker<T> implements Runnable {
024                private List<Future<T>> futures = new ArrayList<Future<T>>();
025                private ExecutorService executorService = null;
026
027                public TaskChecker(ExecutorService executorService) {
028                        super();
029                        this.executorService = executorService;
030                }
031
032                public List<Future<T>> getFutures() {
033                        return futures;
034                }
035
036                @Override
037                public void run() {
038                        while (!this.isDone()) {
039                                try {
040                                        Thread.sleep(200);
041                                } catch (InterruptedException e) {
042                                        // FIXME
043                                }
044                        }
045                        this.executorService.shutdownNow();
046                }
047
048                public boolean isDone() {
049                        for (Future<T> future : this.futures) {
050                                if (!(future.isCancelled() || future.isDone())) {
051                                        return false;
052                                }
053                        }
054                        return true;
055                }
056        }
057}