001    /*
002     * $RCSfile: Task.java,v $ 
003     *
004     * Created on September 30, 2002, 10:02 AM
005     *
006     * This file is part of the STAR Scheduler.
007     * Copyright (c) 2002-2006 STAR Collaboration - Brookhaven National Laboratory
008     *
009     * STAR Scheduler is free software; you can redistribute it and/or modify
010     * it under the terms of the GNU General Public License as published by
011     * the Free Software Foundation; either version 2 of the License, or
012     * (at your option) any later version.
013     *
014     * STAR Scheduler is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017     * GNU General Public License for more details.
018     *
019     * You should have received a copy of the GNU General Public License
020     * along with STAR Scheduler; if not, write to the Free Software
021     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022     */
023    package gov.bnl.star.offline.scheduler.util;
024    
025    
026    /** A task that is going to be executed in a separate thread while displaying a
027     * character every second on the standard output.
028     *
029     * @author  Gabriele Carcassi
030     * @version $Revision: 1.9 $ $Date: 2006/11/21 00:41:29 $
031     */
032    public class Task extends Thread {
033        private char waitingDot;
034        private int msPause = 1000;
035        private int msTimeout;
036    
037        /** The exit status of the process. */
038        protected int exitStatus;
039    
040        /** A new task to be executed in background. The character displayed while waiting
041         * will be a '.'
042         */
043        public Task() {
044            this('.', 0);
045        }
046    
047        /** A new task to be executed in background. The character displayed while waiting
048         * will be the one specified
049         * @param waitingDot character to display every second while waiting for the task to finish
050         */
051        public Task(char waitingDot) {
052            this(waitingDot, 0);
053        }
054    
055        /** A new task to be executed in background with a timeout. If after the timeout the
056         * task hasn't finished it will be considered as failed.
057         * @param msTimeout timeout in milliseconds
058         */
059        public Task(int msTimeout) {
060            this('.', msTimeout);
061        }
062    
063        /** A new task to be executed in background with a timeout. The character displayed
064         * while waiting will be the one specified. If after the timeout the task hasn't
065         * finished it will be considered as failed. The
066         * @param waitingDot character to display every second while waiting for the task to finish
067         * @param msTimeout timeout in milliseconds
068         */
069        public Task(char waitingDot, int msTimeout) {
070            this.waitingDot = waitingDot;
071            this.msTimeout = msTimeout;
072        }
073    
074        /** Returns the condition on which the task finished. Return value 0 means no errors.
075         * @return for success 0, else for failure
076         */
077        public int getExitStatus() {
078            return exitStatus;
079        }
080    
081        /** Starts the task and wait for the result. While waiting, some dots are displayed
082         * to give the user the impression that the job didn't hang.
083         */
084        public void execute() {
085            start();
086    
087            long startTime = System.currentTimeMillis();
088    
089            while (isAlive()) {
090                try {
091                    Thread.sleep(msPause);
092    
093                    if (isAlive()) {
094                        System.out.print(waitingDot);
095                    }
096    
097                    long elapsedTime = System.currentTimeMillis() - startTime;
098    
099                    if ((msTimeout > 0) && (elapsedTime > msTimeout)) {
100                        this.destroy();
101                    }
102                } catch (Exception e) {
103                    throw new RuntimeException("Thread was interrupted");
104                }
105            }
106        }
107    }