After writing the installer.def.xml file for your new sensor, the next step is to implement a subclass of the SensorInstaller abstract class with your sensor-specific installation functionality. This subclass should be located in the "installer" directory. Our FooSensor SensorInstaller subclass would thus be called "FooSensorInstaller" with the following path:
C:\hackydev-svn\hackySensor_FooSensor\src\org\hackystat\sensor\foosensor\installer\FooSensorInstaller.java
The SensorInstaller superclass contains several abstract methods that must be provided with a sensor specific implementation in your subclass. These abstract methods are listed in Table 21.1, “SensorInstaller Abstract Methods”.
Table 21.1. SensorInstaller Abstract Methods
| Abstract Method | Description |
|---|---|
| install | The method that is called to install a sensor. See Section 21.3.3.1, “Overriding the Install Method” for an example. |
| update | The method that is called to update a sensor. See Section 21.3.3.2, “Overriding the Update Method” for an example. |
| remove | Removes a sensor from the user's system. See Section 21.3.3.3, “Overriding the Remove Method” for an example. |
| isInstalled | The method that checks if a sensor is installed. See Section 21.3.3.4, “Overriding the isInstalled Method” for an example. |
| isEnabled | Returns if a sensor is turned on. See Section 21.3.3.5, “Overriding the isEnabled Method” for an example. |
Provided below is example code of the AntSensorInstaller. This SensorInstaller was picked because it is characteristics of a large number of sensor installers in Hackystat. For examples of alternative ways to write a SensorInstaller, please take a look at the EclipseSensorInstaller or the VisualStudioSensorInstaller.
Example 21.3, “The AntSensorInstaller Install Method” is a typical install code example.
Example 21.3. The AntSensorInstaller Install Method
public void install () throws InstallerException, ModelException {
try {
// make sure paths correct before installing sensor to the directory
this.validateAllSensorPaths();
Path path = this.pathManager.getPath("ANT_HOME");
// check and install sensorshell.jar if needed
this.updateSensorshell(path.getLocation() + "/lib");
// download sensor and get the new version number
this.downloadToTempDir();
this.removeOldSensor(path.getLocation() + "/lib");
this.moveSensorFile(this.getSensorJarfileName(), path.getLocation() + "/lib");
this.sensor.setVersion(Version.getServerVersion());
ConfigPersistor.getInstance().write(); // Write new information to hackyinstaller.xml.
}
catch (MalformedURLException e) {
throw new InstallerException("Url to sensor is invalid.", e);
}
catch (DownloadException e) {
throw new InstallerException(e.getMessage(), e);
}
catch (IOException e) {
throw new InstallerException("Error contacting server for sensor files.", e);
}
catch (SAXException e) {
throw new InstallerException("Could not retrieve version of sensor downloaded.", e);
}
catch (Exception e) {
throw new InstallerException(e.getMessage(), e);
}
finally {
Directory.deleteDir(this.sensorTempDir); // cleans up temporary directory
}
}
Example 21.4, “The AntSensorInstaller Update Method” is a typical update code example. For the Ant sensor installer, the update method calls the install method because it is easier to download a new copy of the sensor jar file, which is very small in size, than to update the current jar file. If the sensor you are installing requires a different update procedure, the update method is where it should be done.
Example 21.4. The AntSensorInstaller Update Method
public void update () throws ModelException, InstallerException {
if (!this.hasLatestVersion()) {
this.install();
}
}
Example 21.5, “The AntSensorInstaller remove Method” is a typical remove code example. The AntSensorInstaller removes the sensor by finding the location of the sensor.ant.jar file and deletes it. The information associated with the sensor, such as the version number, is then cleared.
Example 21.5. The AntSensorInstaller remove Method
public void remove () throws ModelException, InstallerException {
try {
Path path = this.pathManager.getPath("ANT_HOME");
File buildSensor = new File(path.getLocation() + this.relativeToolPath);
// Check if sensor exists
if (buildSensor.exists()) {
boolean removed = buildSensor.delete();
if (!removed) {
throw new SensorRemoveException("Error removing build sensor. File may be in use.");
}
else { // clears information about the sensor
// Set version of sensor blank
this.sensor.setVersion("");
// Write new information to hackyinstaller.xml.
ConfigPersistor configHandler = ConfigPersistor.getInstance();
configHandler.write();
}
}
else {
throw new SensorRemoveException("Build sensor does not appear to be installed.");
}
}
catch (SensorRemoveException e) {
throw new InstallerException(e.getMessage(), e);
}
}
Example 21.6, “The AntSensorInstaller isInstalled Method” is a typical isInstalled code example. For the Ant sensor installer, the isInstalled method verifys if the sensor.ant.jar file exists in the directory specified by the user. If it does not exist, false is returned.
Example 21.6. The AntSensorInstaller isInstalled Method
public boolean isInstalled () throws ModelException {
boolean isInstalled = false;
Path path = this.pathManager.getPath("ANT_HOME");
File buildSensor = new File(path.getLocation() + this.relativeToolPath);
if (buildSensor.exists()) {
isInstalled = true;
}
return isInstalled;
}
Example 21.7, “The AntSensorInstaller isEnabled Method” is a typical isEnabled code example. To check if a sensor is enabled, a simple check of the 'ENABLE_ANT_SENSOR' property is implemented. All hackystat sensors are associated with an 'ENABLE.SENSOR_NAME.SENSOR' property that is found in the user.home/.hackystat/sensor.properties file. The PropertyManager is the object that contains a list of all the properties that are associated with a sensor.