Plugins getting started

From JReality Wiki
Jump to: navigation, search

Introduction

JavaDoc: de.jtem.jreworkspace.plugin


The plugin system of jReality is an extension of the jTEM project jRWorksapce.


A plug-in is an extension to the jreality viewer JRViewer. In fact the viewer itself is a collection of plug-ins too. Technically a plug-in is a java class which extends a certain abstract class Plugin. By convention the name of the class should contain the word "plugin" either in the class name or the package name.


The API of the Plugin class is shown here:

/**
 * The base class for all plug-ins of the jRWorkspace plug-in 
 * mechanism.
 * The order of calls in the life cycle of a plug-in is
 * 1. - restoreStates(Controller c)
 * 2. - install(Controller c)
 * 3. - uninstall(Controller c)
 * 4. - storeStates(Controller c)
 * 
 * @author Stefan Sechelmann
 */
public abstract class Plugin {
	/**
	 * Returns an instance of {@link PluginInfo}
	 * @return plug-in information
	 * @see {@link PluginInfo}
	 */
	public abstract PluginInfo getPluginInfo();
	/**
	 * Is called if the plug-in is installed 
	 * @param c the applications {@link Controller}
	 * @throws Exception
	 * @see {@link Controller}
	 */
	public void install(Controller c) throws Exception{
	}
	/**
	 * Id called when this plug-in is about to be uninstalled
	 * @param c this applications {@link Controller}
	 * @throws Exception
	 * @see {@link Controller}
	 */
	public void uninstall(Controller c) throws Exception {
	}
	/**
	 * Is called before the installation of this plug-in. 
	 * @param c this applications {@link Controller}
	 * @throws Exception
	 * @see {@link Controller}
	 */
	public void restoreStates(Controller c) throws Exception {
	}
	/**
	 * Is called after this plug-in has been uninstalled.
	 * @param cthis applications {@link Controller}
	 * @throws Exception
	 * @see {@link Controller}
	 */
	public void storeStates(Controller c) throws Exception {
	}
...
}


Plug-in Info

The first abstract Method in Plugin is the getPluginInfo() method. Here the author should provide information about the plugin by returning an instance of PluginInfo. Available fields are name, vendor name, vendor email, a documentation url, and an icon. The field isDynamic is used in conjunction with a Controller that is capable of dynamically loading and unloading plug-ins. Such a controller is not part of the jreality release.


/**
 * This class holds information about a plug-in. Every plug-in class
 * has to return an instance of this class in their getPluginInfo
 * method.
 * @author Stefan Sechelmann
 */
public class PluginInfo {
	public String 
		/**
		 * The plug-in name
		 */
		name = "unnamed",
		/**
		 * The vendor name of the plug-in
		 */
		vendorName = "unknown",
		/**
		 * An email address of this plug-ins vendor
		 */
		email = "unknown";
	public Icon 
		/**
		 * An icon which will be the plug-ins icon 
		 * in the application
		 */
		icon = null;
	public URL 
		/**
		 * An URL to the Documentation of the plug-in.
		 */
		documentationURL = null;
	public boolean
		/**
		 * Indicates if this plug-in is meant to be dynamically 
		 * installed or uninstalled
		 */
		isDynamic = true;
...	
}


The Controller

The Controller is the heart of a plug-in driven application. For a jReality application it can be obtained by the JRViewer class which handles all default plug-in registration and startup procedures. The controller manages the communication between plug-ins by simply letting them query the plug-in list through invoking the getPlugin() method. It is also resposible for property storage and loading.


/**
 * The Controller interface of the jRWorkspace plug-in mechanism.
 * It manages the communication between plug-ins through the getPlugin() 
 * methods.
 * A plug-in that needs another plug-in to work with should call 
 * getPlugin() with the plug-ins class as argument. 
 * @author Stefan Sechelmann
 */
public interface Controller {
	/**
	 * Returns an instance of the plug-in class clazz, if there
	 * is a plug-in of this class available. If the result is available
	 * but not yet installed it will be installed.
	 * @param <T> the class type of the plug-in to get
	 * @param clazz the class
	 * @return a plug-in or null if there is no plug-in of type class<T>
	 */
	public <T extends Plugin> T getPlugin(Class<T> clazz);
	/**
	 * Returns all plug-ins for which the following expression 
	 * evaluates to true
	 * pClass.isAssignableFrom(plug-in)
	 * @param <T> the plug-in class type
	 * @param pClass the class of type T
	 * @return A list of plug-ins 
	 */
	public <T> List<T> getPlugins(Class<T> pClass);
	/**
	 * Stores the property with the given key and context class
	 * @param context the context class e.g. the plug-in class 
	 * which stores the value
	 * @param key a key string
	 * @param property the property to save
	 * @return The old value of this property
	 */
	public Object storeProperty(Class<?> context, String key, Object property);
	/**
	 * Retrieves a property from this Controller.
	 * @param <T> The property type
	 * @param context A context
	 * @param key the key name of the property to retrieve
	 * @param defaultValue a default value, which is returned if the 
	 * property was not saved before
	 * @return the stored property or defaultValue
	 */
	public <T> T getProperty(Class<?> context, String key, T defaultValue);
	/**
	 * Deletes a property from this controller
	 * @param <T> The property type
	 * @param context A context
	 * @param key The key name of the property to delete
	 * @return The deleted value or null if the key was not found
	 */
	public <T> T deleteProperty(Class<?> context, String key);
	/**
	 * Returns true if the controller believes this plug-in is active
	 * @param p the plug-in
	 * @return active
	 */
	public boolean isActive(Plugin p);
}


Installation

Right before installation of the plug-in the restoreStates() method is invoked to load properties from a property map. Then the install() method is invoked during startup and contains the plugin initialization code. A typical plugin retrieves information about other plugins it wants to communicate with and any GUI code should be placed here.

Uninstallation

Uninstallation is the inverse process of installation which means that all changes to the system should be undone. The states of the plug-in can be saves in the storeStates() method right after the uninstall method has been invoked by the Controller.


Example

This example plug-in adds geometry to the scene once it gets installed and removes this geometry in it's uninstall method. To achieve this the getPlugin(Class<? extends Plugin>) method is invoked with the Scene.class as argument. The Scene is one of the default plug-ins registered on the Controller in a JRViewer environment. The geometry then is added to the Scene's content component. This component by convention is the parent of all content in the viewer scene graph.


public class GettingStartedExample extends Plugin {
	private Scene 
		scene = null; 
	private SceneGraphComponent
		cubeNode = new SceneGraphComponent("A colored cube");
	
	public GettingStartedExample() {
		cubeNode.setGeometry(Primitives.coloredCube());
	}
	@Override
	public PluginInfo getPluginInfo() {
		PluginInfo info = new PluginInfo();
		info.name = "Getting Started Example Plug-In";
		info.vendorName = "jReality Group";
		info.email = "webmaster@jReality.de";
		info.isDynamic = true;
		return info;
	}
	@Override
	public void install(Controller c) throws Exception {
		super.install(c);
		scene = c.getPlugin(Scene.class);
		SceneGraphComponent content = scene.getContentComponent();
		content.addChild(cubeNode);
	}
	@Override
	public void uninstall(Controller c) throws Exception {
		SceneGraphComponent content = scene.getContentComponent();
		content.removeChild(cubeNode);
		super.uninstall(c);
	}
	
	public static void main(String[] args) {
		JRViewer v = new JRViewer();
		v.registerPlugin(new ContentTools());
		v.registerPlugin(new GettingStartedExample());
		v.startup();
		v.encompassEuclidean();
	}
}


This is the result of the code above. The toolbar is generated by the ContentTools plug-in.

The Plugin Getting Started Example


Previous: Developer Tutorial#Plugins Developer Tutorial#Plugins: Contents Next: The JRViewer plug-in set