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 }