Requirements

First steps

Create a new Java Project (File -> New -> Java Project):

New Project Dialog

New Project Dialog

Click on Next > and select the Libraries tab. Add the ZoneTrak Commons Library by clicking Add External JARs…:

Add ZoneTrak Commons Library to Build Path

Add ZoneTrak Commons Library to Build Path

Repeat this step for the modified swings-ws package.

Your first Plugin

Create a new class (File -> New -> Class). For this introduction, we’re using DemoPlugin as main class in the package zonetrak.plugin.demo.

You should see a default skeleton like this:

package zonetrak.plugin.demo;
 
public class DemoPlugin
{
 
}

Now, we have to tell ZoneTrak that this is the main class which contains the entry point for this plugin. This can be realized by extending the AbstractPlugin class or by implementing the IPlugin interface. We will use the AbstractPlugin class because it might be easier to use. Inheriting from AbstractPlugin forces to implement the method initPlugin().

By implementing the initPlugin() method, we’re finished creating a minimalistic plugin:

package zonetrak.plugin.demo;
 
import zonetrak.common.AbstractPlugin;
 
public class DemoPlugin extends AbstractPlugin
{
	@Override
	public void initPlugin()
	{
		System.out.println("Plugin initialized.");
	}
}

Plugin Installation

Right-click on your project in the Package Explorer and select Export…. Select Java -> JAR file and click Next >. Set the export destination to the plugins directory of your ZoneTrak installation and press Finish. That’s it.

Data Exchange

A plugin needs to share information with the main application which can be done using the IDataManager interface. The AbstractPlugin class implements the methods setDataManager(IDataManager) and getDataManager() which you would need to implement in case you use the IPlugin interface instead of the AbstractPlugin class. setDataManager(IDataManager) is called by the main application’s plugin loader before initPlugin() is called, so you are free to use the data manager anytime in your plugin.

The IDataManager interface is implemented by a class called DataManager. This class stores references to objects of the main application and allows to access them externally (i.e. within the plugin). There is a variety of data objects which can be accessed. You should consider reading the list of exchangable objects to see which objects can be accessed.

For simplicity we will focus on reading data, but writing data is just as easy as this. There is an accessible object identified by entities which has the type ArrayList<IEntity> and contains all (even outdated) entity data the system has collected. With our demo plugin, we will try to find the latest entity data in the list.

package zonetrak.plugin.demo;
 
import java.util.ArrayList;
import java.util.Collections;
 
import org.jdesktop.swingx.mapviewer.GeoPosition;
 
import zonetrak.common.AbstractPlugin;
import zonetrak.common.EntityComparator;
import zonetrak.ifaces.IEntity;
 
public class DemoPlugin extends AbstractPlugin
{
	@Override
	public void initPlugin()
	{
		/**
		 * Casting to generic classes is always
		 * painful and causes "unchecked cast"
		 * warnings. We're using @SuppressWarnings
		 * to stop being disturbed.
		 */
		@SuppressWarnings("unchecked")
		ArrayList<IEntity> entities = (ArrayList<IEntity>)this.getDataManager().getData("entities");
 
		/**
		 * In case entities is not set, the data
		 * manager will return null. We should
		 * not try to access null and we should
		 * ignore empty lists.
		 */
		if (entities == null || entities.size() == 0)
		{
			return;
		}
 
		/**
		 * The class EntityComparator compares
		 * entities by date and is used by
		 * Collections.sort() to reorganize the
		 * list.
		 */
		Collections.sort(entities, new EntityComparator());
 
		/**
		 * Get the last entity (which is the latest).
		 */
		IEntity entity = entities.get(entities.size() - 1);
 
		/**
		 * Get the position information of the
		 * latest entity and print it.
		 */
		GeoPosition position = entity.getPosition();
 
		System.out.println("The last entity was located at:");
		System.out.println("Lat: " + position.getLatitude() + " Lon: " + position.getLongitude());
	}
}

You might notice that this plugin does not work although everything is correct. But why? The question’s answer is really easy. entities is always null. The reason for this is that plugins are initialized before ZoneTrak downloads zone and entity data for the first time.

Catching Events

The problem we recognized in the last section can be easily circumvented by using events raised when data is set.  Like the IDataManager there is an interface called IEventManager. The event manager implements the publish/subscribe communication paradigm1. The data manager introduced in the previous section raises an event everytime when data is set or updated. With the tacit understanding we omit discussing the ISubscriber interface and start with the source code.

package zonetrak.plugin.demo;
 
import java.util.ArrayList;
import java.util.Collections;
 
import org.jdesktop.swingx.mapviewer.GeoPosition;
 
import zonetrak.common.AbstractPlugin;
import zonetrak.common.EntityComparator;
import zonetrak.ifaces.IEntity;
import zonetrak.ifaces.ISubscriber;
 
public class DemoPlugin extends AbstractPlugin implements ISubscriber
{
	@Override
	public void initPlugin()
	{
		this.getEventManager().subscribe("entities", this);
	}
 
	@Override
	public void eventFired(String type, Object... args)
	{
		@SuppressWarnings("unchecked")
		ArrayList<IEntity> entities = (ArrayList<IEntity>)this.getDataManager().getData("entities");
 
		/**
		 * Events are raised even if the value
		 * is null or the list is empty.
		 */
		if (entities == null || entities.size() == 0)
		{
			return;
		}
 
		Collections.sort(entities, new EntityComparator());
 
		IEntity entity = entities.get(entities.size() - 1);
 
		GeoPosition position = entity.getPosition();
 
		System.out.println("The last entity was located at:");
		System.out.println("Lat: " + position.getLatitude() + " Lon: " + position.getLongitude());
 
	}
}

After installing this demo plugin we can observe following text:

The last entity was located at:
Lat: 51.4742 Lon: 6.92028

References

  1. See the article about Plugin Management for more information []

Comments are closed.