The interactive interface to SensorShell is very useful for illustrating the features of the SensorShell, and for sensors who communicate with the SensorShell through a subprocess. Sensors written in Java can simply create instances of the SensorShell directly.
To use the Java interface to sensorshell, be sure that sensorshell.jar is on the CLASSPATH when the tool is running.
Example 16.4, “Sample Java interface code fragment for SensorShell” illustrates the use of the Java interface to SensorShell.
Example 16.4. Sample Java interface code fragment for SensorShell
// [1] Create the SensorShell (once per session, at the beginning)
SensorProperties sensorProps = new SensorProperties("Ant");
this.shell = new SensorShell(sensorProps, false, "Ant");
// [2] Set the default tool type (once per session, at the beginning)
String[] toolArgs = {"set", "tool=Ant"};
this.shell.doCommand(new Date(), "DevEvent", Arrays.asList(toolArgs));
// [3] DevEvent 'add' command requires 'path' and 'type' arguments.
List argList = new ArrayList();
argList.add("add");
argList.add("path=" + this.path);
argList.add("type=" + this.type);
// [4] Let's add an optional 'location' property to this sensor data instance.
SensorDataPropertyMap pMap = new SensorDataPropertyMap();
pMap.put("location", "office");
// Now add the property map (encoding as a string)
argList.add("pMap=", pMap.encode());
// [5] Now invoke the 'add' command, passing the args.
this.shell.doCommand(new Date(), "DevEvent", argList);
// [6] Send the data (once per session, at the end)
this.shell.send();
The first section of this code fragment creates a "SensorProperties" instance, which represents the contents of the sensor.properties file in the user's .hackystat directory, and provides access to things like the hackystat host and user key. The SensorProperties constructor takes a string indicating the name of the tool, which is used to determine if the sensor for that tool is enabled by the user. Next, a SensorShell instance is constructed. This constructor takes the SensorProperties instance, a boolean indicating if the SensorShell is being invoked interactively (it's not), and finally the name of the tool that constructed this instance (to be sent to the log file associated with this SensorShell for documentation and debugging purposes).
The second section invokes the "set" command to define the default "tool" attribute for all future invocations of DevEvent sensor data in this SensorShell session. This code indicates that the tool is "Ant".
The third section creates a List instance containing the DevEvent command to be invoked ("add"), and two additional elements containing the string key-value pairs representing the required entryattributes for a DevEvent ("path" and "type"). Although the "tool" entryattribute is required, we don't have to supply it each time we create sensor data since we used the "set" command to specify a default tool value.
The fourth section adds an optional property ("location") to this sensor data. This is accomplished by creating an instance of SensorDataPropertyMap, adding the optional property key-value pair to it, and then adding the String encoding of this property map to the argList.
The fifth section actually invokes the sensorshell with the final version of the arguments. Each sensor data instance requires a timestamp representing the time at which the corresponding data was collected.
The final section of this code fragment shows how to invoke the send method to send all accumulated data to the server. Note that it is the responsibility of the tool to invoke the send method as part of its cleanup activities before exiting. When writing a tool sensor, you don't generally want to invoke send() after each addition of sensor data to the SensorShell; that would defeat the buffering capability of the sensorshell.
This code fragment should provide the basic idea behind the Java interface to SensorShell. For a more in-depth explanation, see the upcoming chapter on sensor design, or consult any of the existing hackySensor code.