001    package org.hackystat.sensorshell.command;
002    
003    import java.util.Date;
004    import java.util.Timer;
005    import java.util.TimerTask;
006    
007    import org.hackystat.sensorshell.SensorShellException;
008    import org.hackystat.sensorshell.SensorShellProperties;
009    import org.hackystat.sensorshell.SingleSensorShell;
010    import org.hackystat.utilities.stacktrace.StackTrace;
011    
012    /**
013     * Implements the AutoSend facility, which automatically sends all SensorData to the Sensorbase
014     * at regular intervals as specified in the sensorshell.autosend.timeinterval property.
015     * @author Philip Johnson
016     */
017    public class AutoSendCommand extends Command {
018      
019      /** The timer that enables periodic sending. */
020      private Timer timer = null;
021      /** The autosend command task for this shell. */
022      private AutoSendCommandTask task = null;
023      
024      /**
025       * Creates the AutoSendCommand and starts a timer-based process running that wakes up and 
026       * invokes send based upon the value of the SensorShellProperties autosend timeinterval.
027       * @param shell The sensorshell. 
028       * @param properties The sensorproperties. 
029       */
030      public AutoSendCommand(SingleSensorShell shell, SensorShellProperties properties) {
031        super(shell, properties);
032        double minutes = properties.getAutoSendTimeInterval();
033        // Don't set up a timer if minutes value is close to 0.
034        if (minutes < 0.009) {
035          this.shell.println("AutoSend disabled.");
036        }
037        else {
038          // Otherwise set up a timer with the newly specified value.
039          this.timer = new Timer(true);
040          int milliseconds = (int) (minutes * 60 * 1000);
041          this.task = new AutoSendCommandTask(shell);
042          this.timer.schedule(task, milliseconds, milliseconds);
043          this.shell.println("AutoSend time interval set to " + (int) (minutes * 60) + " seconds");
044        }
045      }
046      
047      /**
048       * Cancels the timer if there is one. 
049       */
050      public void quit() {
051        if (this.timer != null) {
052          this.timer.cancel();
053        }
054      }
055    
056      
057      /**
058       * Returns the exception that was thrown during autosend, or null if none was thrown.
059       * @return The exception if one was thrown previously, or null if none was thrown. 
060       */
061      public SensorShellException getException() {
062        return (this.task == null) ? null : this.task.getException();
063      }
064      
065      /**
066       * Inner class providing a timer-based command to invoke the send() method of the SensorShell.
067       * @author Philip M. Johnson
068       */
069      private static class AutoSendCommandTask extends TimerTask {
070        
071        /** The sensor shell. */
072        private SingleSensorShell shell;
073        /** The exception that was thrown by this task. */
074        private SensorShellException exception = null;
075        /** The time at which the exception was thrown. */
076        private Date exceptionTime = null;
077        
078        /**
079         * Creates the TimerTask.
080         * @param shell The sensorshell.
081         */
082        public AutoSendCommandTask(SingleSensorShell shell) {
083          this.shell = shell;
084        }
085    
086        /** Invoked periodically by the timer in AutoSendCommand. */
087        @Override
088        public void run() {
089          this.shell.println("Timer-based invocation of send().");
090          try {
091            this.shell.send();
092          }
093          catch (SensorShellException e) {
094            this.shell.getLogger().info("Error in timer-based invocation: " + StackTrace.toString(e));
095            this.exceptionTime = new Date();
096            this.exception = e;
097          }
098        }
099        
100        /**
101         * The exception that was thrown during the run() method of this task.
102         * @return The thrown exception, or null if no exception was thrown.
103         * 
104         */
105        public SensorShellException getException() {
106          return this.exception;
107        }
108        
109        /**
110         * The time that an exception was thrown during the run() method of this task.
111         * @return The thrown exception time, or null if no exception was thrown. 
112         * 
113         */
114        public Date getExceptionTime() {
115          return this.exceptionTime;
116        }
117        
118      }
119    }