<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.c2b2.columbia.edu/workbench/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Watkinson</id>
		<title>geWorkbench - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.c2b2.columbia.edu/workbench/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Watkinson"/>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php/Special:Contributions/Watkinson"/>
		<updated>2026-04-30T05:38:31Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.27.7</generator>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Properties&amp;diff=3815</id>
		<title>Properties</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Properties&amp;diff=3815"/>
				<updated>2006-11-20T21:24:59Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Components often want to store and retrieve configuration settings between invocations. An API is provided for this purpose.&lt;br /&gt;
&lt;br /&gt;
Configuration is handled by the setting and getting of properties using the [{{SERVER}}/workbench/api/org/geworkbench/engine/properties/PropertyManager.html &amp;lt;tt&amp;gt;org.geworkbench.engine.properties.PropertyManager&amp;lt;/tt&amp;gt;] class. A singleton instance is available to process requests.&lt;br /&gt;
&lt;br /&gt;
The two important methods of this class are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public void setProperty(Class componentClass, String key, String value) throws IOException;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public String getProperty(Class componentClass, String key, String defaultValue) throws IOException;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first parameter to both methods can be the &amp;lt;code&amp;gt;Class&amp;lt;/code&amp;gt; object of any class in your component. This is used to determine where the configuration will be stored. This class is mapped back to the component that it is associated with. The &amp;lt;code&amp;gt;defaultValue&amp;lt;/code&amp;gt; parameter of &amp;lt;code&amp;gt;getProperty&amp;lt;/code&amp;gt; will be the returned result if there is no known value for the specified key.&lt;br /&gt;
&lt;br /&gt;
Here is an example use of the properties manager:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PropertiesManager.getInstance().setProperty(getClass(), &amp;quot;test&amp;quot;, &amp;quot;value&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and later...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
String value = PropertiesManager.getInstance().getProperty(getClass(), &amp;quot;test&amp;quot;, &amp;quot;Default Value&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Setting the property will automatically cause the value to be saved to disk. The configuration file is an XML file stored in a &amp;lt;code&amp;gt;conf&amp;lt;/code&amp;gt; subdirectory of the component's working directory.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Properties&amp;diff=3786</id>
		<title>Properties</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Properties&amp;diff=3786"/>
				<updated>2006-10-12T22:02:11Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Components often want to store and retrieve configuration settings between invocations. An API is provided for this purpose.&lt;br /&gt;
&lt;br /&gt;
Configuration is handled by the setting and getting of properties using the [{{SERVER}}/workbench/api/org/geworkbench/engine/properties/PropertyManager.html &amp;lt;tt&amp;gt;org.geworkbench.engine.properties.PropertyManager&amp;lt;/tt&amp;gt;] class. A singleton instance is available to process requests.&lt;br /&gt;
&lt;br /&gt;
The two important methods of this class are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public void setProperty(Class componentClass, String key, String value) throws IOException;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public String getProperty(Class componentClass, String key, String defaultValue) throws IOException;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first parameter to both methods can be the &amp;lt;code&amp;gt;Class&amp;lt;/code&amp;gt; object of any class in your component. This is used to determine where the configuration will be stored. The &amp;lt;code&amp;gt;defaultValue&amp;lt;/code&amp;gt; parameter of &amp;lt;code&amp;gt;getProperty&amp;lt;/code&amp;gt; will be the returned result if there is no known value for the specified key.&lt;br /&gt;
&lt;br /&gt;
Here is an example use of the properties manager:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PropertiesManager.getInstance().setProperty(getClass(), &amp;quot;test&amp;quot;, &amp;quot;value&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and later...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
String value = PropertiesManager.getInstance().getProperty(getClass(), &amp;quot;test&amp;quot;, &amp;quot;Default Value&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Setting the property will automatically cause the value to be saved to disk. The configuration file is an XML file stored in a &amp;lt;code&amp;gt;conf&amp;lt;/code&amp;gt; subdirectory of the component's working directory.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Properties&amp;diff=3785</id>
		<title>Properties</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Properties&amp;diff=3785"/>
				<updated>2006-10-12T21:55:44Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Components often want to store and retrieve configuration settings between invocations. An API is provided for this purpose.&lt;br /&gt;
&lt;br /&gt;
Configuration is handled by the setting and getting of properties using the [{{SERVER}}/workbench/api/org/geworkbench/engine/properties/PropertyManager.html &amp;lt;tt&amp;gt;org.geworkbench.engine.properties.PropertyManager&amp;lt;/tt&amp;gt;] class. A singleton instance is available to process requests.&lt;br /&gt;
&lt;br /&gt;
The two important methods of this class are:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public void setProperty(Class component, String key, String value) throws IOException&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
public String getProperty(Class component, String key, String defaultValue) throws IOException&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Properties&amp;diff=3784</id>
		<title>Properties</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Properties&amp;diff=3784"/>
				<updated>2006-10-12T21:52:36Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Components often want to store and retrieve configuration settings between invocations. An API is provided for this purpose.&lt;br /&gt;
&lt;br /&gt;
Configuration is handled by the setting and getting of properties using the&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Design_Documentation&amp;diff=3783</id>
		<title>Design Documentation</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Design_Documentation&amp;diff=3783"/>
				<updated>2006-10-12T21:49:49Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DevelopersTopNav}}&lt;br /&gt;
&lt;br /&gt;
* [[Framework | Component architecture framework]]: a high level description of how component instantiation and communication are handled within geWorkbench.&lt;br /&gt;
* [[Properties | Configuration properties]]: A description of how to set and get configuration properties for your component.&lt;br /&gt;
&lt;br /&gt;
Coming soon:&lt;br /&gt;
* BISON.&lt;br /&gt;
* Use cases.&lt;br /&gt;
* Design docs for various plugin components.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2853</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2853"/>
				<updated>2006-03-15T20:07:13Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Visual Plugins and GUIFramework */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentRegistry.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;]. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called [{{SERVER}}/workbench/api/org/geworkbench/engine/config/PluginDescriptor.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt;]. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentResource.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt;] class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the [{{SERVER}}/workbench/api/org/geworkbench/events/ProjectEvent.html &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt;] type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SynchModel.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt;] interface. Four implementations are provided with geWorkbench (all in the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/package-summary.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt;] package):&lt;br /&gt;
&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Synchronous.html &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt;] - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Asynchronous.html &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;]  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Overflow.html &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt;] - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SwingModel.html &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt;] - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface [{{SERVER}}/workbench/api/org/geworkbench/bison/datastructure/biocollections/DSDataSet.html &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;]. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a [{{SERVER}}/workbench/api/org/geworkbench/events/ProjectNodeAddedEvent.html &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt;] from another component. This events are usually generated as the result of an analysis by the publishing component.&lt;br /&gt;
&lt;br /&gt;
The conceppt of data sets is central to geWorkbench development. Many plugins can be characterized by the types of data sets they process and the types of data sets that they produce.&lt;br /&gt;
&lt;br /&gt;
== Visual Plugins and GUIFramework ==&lt;br /&gt;
&lt;br /&gt;
Many plugins have a visual representation. This visual intention is advertised to the framework by the plugin implementing [{{SERVER}}/workbench/api/org/geworkbench/engine/config/VisualPlugin.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.VisualPlugin&amp;lt;/tt&amp;gt;]. Some plugins, such as file parsers and analyses, do not require a visual representation, and so do not implement this interface.&lt;br /&gt;
&lt;br /&gt;
Those that implement VisualPlugin will have extra directives included in the configuration file to indicate how they should be laid out in the interface. These directives are passed on from the configuration engine to the rendering framework. The rendering framework is itself configurable, and is a class that extends [{{SERVER}}/workbench/api/org/geworkbench/engine/config/GUIFramework.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.GUIFramework&amp;lt;/tt&amp;gt;]. The default and most full-featured implementation of GUIFramework is [{{SERVER}}/workbench/api/org/geworkbench/engine/skin/Skin.html &amp;lt;tt&amp;gt;org.geworkbench.engine.skin.Skin&amp;lt;/tt&amp;gt;]. This implementation supports four layout areas (''Project'', ''Selection'', ''Command'' and ''Visual''). It also supports an annotation system for determining which visual components to display based on the selected data set in the Project Panel.&lt;br /&gt;
&lt;br /&gt;
Visual plugins may annotate their class definition with [{{SERVER}}/workbench/api/org/geworkbench/engine/management/AcceptTypes.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.AcceptTypes&amp;lt;/tt&amp;gt;]. If the annotation is omitted, then the visual plugin will always be rendered by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. The annotation takes an array of class objects, each of which must be assignable to &amp;lt;tt&amp;gt;DSDataSet&amp;lt;/tt&amp;gt;. For example, here is how the ''Color Mosaic Panel'' is annotated:&lt;br /&gt;
&lt;br /&gt;
 @AcceptTypes({DSMicroarraySet.class, DSSignificanceResultSet.class}) public class ColorMosaicPanel implements VisualPlugin ...&lt;br /&gt;
&lt;br /&gt;
When the Project Panel generates a &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; resulting from a data set node being selected, the type of the data set is examined by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. Each component that has a type in its @AcceptTypes annotation that is assignable from the selected data set type is made visible in the interface. Additionally, all unannotated components are also made visible. Annotated components without a type assignable from the selected d ata set are hidden. This way, the user is only presented with relevant components upon selection of a data set node.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2852</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2852"/>
				<updated>2006-03-15T20:06:46Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Visual Plugins and GUIFramework */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentRegistry.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;]. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called [{{SERVER}}/workbench/api/org/geworkbench/engine/config/PluginDescriptor.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt;]. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentResource.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt;] class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the [{{SERVER}}/workbench/api/org/geworkbench/events/ProjectEvent.html &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt;] type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SynchModel.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt;] interface. Four implementations are provided with geWorkbench (all in the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/package-summary.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt;] package):&lt;br /&gt;
&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Synchronous.html &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt;] - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Asynchronous.html &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;]  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Overflow.html &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt;] - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SwingModel.html &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt;] - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface [{{SERVER}}/workbench/api/org/geworkbench/bison/datastructure/biocollections/DSDataSet.html &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;]. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a [{{SERVER}}/workbench/api/org/geworkbench/events/ProjectNodeAddedEvent.html &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt;] from another component. This events are usually generated as the result of an analysis by the publishing component.&lt;br /&gt;
&lt;br /&gt;
The conceppt of data sets is central to geWorkbench development. Many plugins can be characterized by the types of data sets they process and the types of data sets that they produce.&lt;br /&gt;
&lt;br /&gt;
== Visual Plugins and GUIFramework ==&lt;br /&gt;
&lt;br /&gt;
Many plugins have a visual representation. This visual intention is advertised to the framework by the plugin implementing [{{SERVER}}/workbench/api/org/geworkbench/engine/config/VisualPlugin.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.VisualPlugin&amp;lt;/tt&amp;gt;]. Some plugins, such as file parsers and analyses, do not require a visual representation, and so do not implement this interface.&lt;br /&gt;
&lt;br /&gt;
Those that implement VisualPlugin will have extra directives included in the configuration file to indicate how they should be laid out in the interface. These directives are passed on from the configuration engine to the rendering framework. The rendering framework is itself configurable, and is a class that extends [{{SERVER}}/workbench/api/org/geworkbench/engine/config/GUIFramework.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.GUIFramework&amp;lt;/tt&amp;gt;]. The default and most full-featured implementation of GUIFramework is [{{SERVER}}/workbench/api/org/geworkbench/engine/Skin.html &amp;lt;tt&amp;gt;org.geworkbench.engine.Skin&amp;lt;/tt&amp;gt;]. This implementation supports four layout areas (''Project'', ''Selection'', ''Command'' and ''Visual''). It also supports an annotation system for determining which visual components to display based on the selected data set in the Project Panel.&lt;br /&gt;
&lt;br /&gt;
Visual plugins may annotate their class definition with [{{SERVER}}/workbench/api/org/geworkbench/engine/management/AcceptTypes.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.AcceptTypes&amp;lt;/tt&amp;gt;]. If the annotation is omitted, then the visual plugin will always be rendered by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. The annotation takes an array of class objects, each of which must be assignable to &amp;lt;tt&amp;gt;DSDataSet&amp;lt;/tt&amp;gt;. For example, here is how the ''Color Mosaic Panel'' is annotated:&lt;br /&gt;
&lt;br /&gt;
 @AcceptTypes({DSMicroarraySet.class, DSSignificanceResultSet.class}) public class ColorMosaicPanel implements VisualPlugin ...&lt;br /&gt;
&lt;br /&gt;
When the Project Panel generates a &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; resulting from a data set node being selected, the type of the data set is examined by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. Each component that has a type in its @AcceptTypes annotation that is assignable from the selected data set type is made visible in the interface. Additionally, all unannotated components are also made visible. Annotated components without a type assignable from the selected d ata set are hidden. This way, the user is only presented with relevant components upon selection of a data set node.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2851</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2851"/>
				<updated>2006-03-15T20:06:13Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Visual Plugins and GUIFramework */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentRegistry.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;]. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called [{{SERVER}}/workbench/api/org/geworkbench/engine/config/PluginDescriptor.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt;]. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentResource.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt;] class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the [{{SERVER}}/workbench/api/org/geworkbench/events/ProjectEvent.html &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt;] type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SynchModel.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt;] interface. Four implementations are provided with geWorkbench (all in the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/package-summary.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt;] package):&lt;br /&gt;
&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Synchronous.html &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt;] - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Asynchronous.html &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;]  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Overflow.html &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt;] - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SwingModel.html &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt;] - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface [{{SERVER}}/workbench/api/org/geworkbench/bison/datastructure/biocollections/DSDataSet.html &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;]. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a [{{SERVER}}/workbench/api/org/geworkbench/events/ProjectNodeAddedEvent.html &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt;] from another component. This events are usually generated as the result of an analysis by the publishing component.&lt;br /&gt;
&lt;br /&gt;
The conceppt of data sets is central to geWorkbench development. Many plugins can be characterized by the types of data sets they process and the types of data sets that they produce.&lt;br /&gt;
&lt;br /&gt;
== Visual Plugins and GUIFramework ==&lt;br /&gt;
&lt;br /&gt;
Many plugins have a visual representation. This visual intention is advertised to the framework by the plugin implementing [{{SERVER}}/workbench/api/org/geworkbench/engine/config/VisualPlugin.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.VisualPlugin&amp;lt;/tt&amp;gt;]. Some plugins, such as file parsers and analyses, do not require a visual representation, and so do not implement this interface.&lt;br /&gt;
&lt;br /&gt;
Those that implement VisualPlugin will have extra directives included in the configuration file to indicate how they should be laid out in the interface. These directives are passed on from the configuration engine to the rendering framework. The rendering framework is itself configurable, and is a class that extends [{{SERVER}}/workbench/api/org/geworkbench/engine/config/GUIFramework.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.GUIFramework&amp;lt;/tt&amp;gt;]. The default and most full-featured implementation of GUIFramework is [{{SERVER}}/workbench/api/org/geworkbench/engine/config/Skin.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.Skin&amp;lt;/tt&amp;gt;]. This implementation supports four layout areas (''Project'', ''Selection'', ''Command'' and ''Visual''). It also supports an annotation system for determining which visual components to display based on the selected data set in the Project Panel.&lt;br /&gt;
&lt;br /&gt;
Visual plugins may annotate their class definition with [{{SERVER}}/workbench/api/org/geworkbench/engine/management/AcceptTypes.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.AcceptTypes&amp;lt;/tt&amp;gt;]. If the annotation is omitted, then the visual plugin will always be rendered by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. The annotation takes an array of class objects, each of which must be assignable to &amp;lt;tt&amp;gt;DSDataSet&amp;lt;/tt&amp;gt;. For example, here is how the ''Color Mosaic Panel'' is annotated:&lt;br /&gt;
&lt;br /&gt;
 @AcceptTypes({DSMicroarraySet.class, DSSignificanceResultSet.class}) public class ColorMosaicPanel implements VisualPlugin ...&lt;br /&gt;
&lt;br /&gt;
When the Project Panel generates a &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; resulting from a data set node being selected, the type of the data set is examined by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. Each component that has a type in its @AcceptTypes annotation that is assignable from the selected data set type is made visible in the interface. Additionally, all unannotated components are also made visible. Annotated components without a type assignable from the selected d ata set are hidden. This way, the user is only presented with relevant components upon selection of a data set node.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2850</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2850"/>
				<updated>2006-03-15T20:05:00Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* The Project Panel and Data Sets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentRegistry.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;]. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called [{{SERVER}}/workbench/api/org/geworkbench/engine/config/PluginDescriptor.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt;]. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentResource.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt;] class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the [{{SERVER}}/workbench/api/org/geworkbench/events/ProjectEvent.html &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt;] type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SynchModel.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt;] interface. Four implementations are provided with geWorkbench (all in the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/package-summary.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt;] package):&lt;br /&gt;
&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Synchronous.html &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt;] - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Asynchronous.html &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;]  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Overflow.html &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt;] - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SwingModel.html &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt;] - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface [{{SERVER}}/workbench/api/org/geworkbench/bison/datastructure/biocollections/DSDataSet.html &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;]. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a [{{SERVER}}/workbench/api/org/geworkbench/events/ProjectNodeAddedEvent.html &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt;] from another component. This events are usually generated as the result of an analysis by the publishing component.&lt;br /&gt;
&lt;br /&gt;
The conceppt of data sets is central to geWorkbench development. Many plugins can be characterized by the types of data sets they process and the types of data sets that they produce.&lt;br /&gt;
&lt;br /&gt;
== Visual Plugins and GUIFramework ==&lt;br /&gt;
&lt;br /&gt;
Many plugins have a visual representation. This visual intention is advertised to the framework by the plugin implementing &amp;lt;tt&amp;gt;org.geworkbench.engine.config.VisualPlugin&amp;lt;/tt&amp;gt;. Some plugins, such as file parsers and analyses, do not require a visual representation, and so do not implement this interface.&lt;br /&gt;
&lt;br /&gt;
Those that implement VisualPlugin will have extra directives included in the configuration file to indicate how they should be laid out in the interface. These directives are passed on from the configuration engine to the rendering framework. The rendering framework is itself configurable, and is a class that extends &amp;lt;tt&amp;gt;org.geworkbench.engine.config.GUIFramework&amp;lt;/tt&amp;gt;. The default and most full-featured implementation of GUIFramework is &amp;lt;tt&amp;gt;org.geworkbench.engine.config.Skin&amp;lt;/tt&amp;gt;. This implementation supports four layout areas (''Project'', ''Selection'', ''Command'' and ''Visual''). It also supports an annotation system for determining which visual components to display based on the selected data set in the Project Panel.&lt;br /&gt;
&lt;br /&gt;
Visual plugins may annotate their class definition with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.AcceptTypes&amp;lt;/tt&amp;gt;. If the annotation is omitted, then the visual plugin will always be rendered by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. The annotation takes an array of class objects, each of which must be assignable to &amp;lt;tt&amp;gt;DSDataSet&amp;lt;/tt&amp;gt;. For example, here is how the ''Color Mosaic Panel'' is annotated:&lt;br /&gt;
&lt;br /&gt;
 @AcceptTypes({DSMicroarraySet.class, DSSignificanceResultSet.class}) public class ColorMosaicPanel implements VisualPlugin ...&lt;br /&gt;
&lt;br /&gt;
When the Project Panel generates a &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; resulting from a data set node being selected, the type of the data set is examined by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. Each component that has a type in its @AcceptTypes annotation that is assignable from the selected data set type is made visible in the interface. Additionally, all unannotated components are also made visible. Annotated components without a type assignable from the selected d ata set are hidden. This way, the user is only presented with relevant components upon selection of a data set node.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2849</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2849"/>
				<updated>2006-03-15T19:51:01Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Synchronization Models */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentRegistry.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;]. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called [{{SERVER}}/workbench/api/org/geworkbench/engine/config/PluginDescriptor.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt;]. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentResource.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt;] class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the [{{SERVER}}/workbench/api/org/geworkbench/events/ProjectEvent.html &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt;] type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SynchModel.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt;] interface. Four implementations are provided with geWorkbench (all in the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/package-summary.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt;] package):&lt;br /&gt;
&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Synchronous.html &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt;] - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Asynchronous.html &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;]  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/Overflow.html &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt;] - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SwingModel.html &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt;] - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt; from another component. This events are usually generated as the result of an analysis by the publishing component.&lt;br /&gt;
&lt;br /&gt;
The conceppt of data sets is central to geWorkbench development. Many plugins can be characterized by the types of data sets they process and the types of data sets that they produce.&lt;br /&gt;
&lt;br /&gt;
== Visual Plugins and GUIFramework ==&lt;br /&gt;
&lt;br /&gt;
Many plugins have a visual representation. This visual intention is advertised to the framework by the plugin implementing &amp;lt;tt&amp;gt;org.geworkbench.engine.config.VisualPlugin&amp;lt;/tt&amp;gt;. Some plugins, such as file parsers and analyses, do not require a visual representation, and so do not implement this interface.&lt;br /&gt;
&lt;br /&gt;
Those that implement VisualPlugin will have extra directives included in the configuration file to indicate how they should be laid out in the interface. These directives are passed on from the configuration engine to the rendering framework. The rendering framework is itself configurable, and is a class that extends &amp;lt;tt&amp;gt;org.geworkbench.engine.config.GUIFramework&amp;lt;/tt&amp;gt;. The default and most full-featured implementation of GUIFramework is &amp;lt;tt&amp;gt;org.geworkbench.engine.config.Skin&amp;lt;/tt&amp;gt;. This implementation supports four layout areas (''Project'', ''Selection'', ''Command'' and ''Visual''). It also supports an annotation system for determining which visual components to display based on the selected data set in the Project Panel.&lt;br /&gt;
&lt;br /&gt;
Visual plugins may annotate their class definition with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.AcceptTypes&amp;lt;/tt&amp;gt;. If the annotation is omitted, then the visual plugin will always be rendered by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. The annotation takes an array of class objects, each of which must be assignable to &amp;lt;tt&amp;gt;DSDataSet&amp;lt;/tt&amp;gt;. For example, here is how the ''Color Mosaic Panel'' is annotated:&lt;br /&gt;
&lt;br /&gt;
 @AcceptTypes({DSMicroarraySet.class, DSSignificanceResultSet.class}) public class ColorMosaicPanel implements VisualPlugin ...&lt;br /&gt;
&lt;br /&gt;
When the Project Panel generates a &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; resulting from a data set node being selected, the type of the data set is examined by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. Each component that has a type in its @AcceptTypes annotation that is assignable from the selected data set type is made visible in the interface. Additionally, all unannotated components are also made visible. Annotated components without a type assignable from the selected d ata set are hidden. This way, the user is only presented with relevant components upon selection of a data set node.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2848</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2848"/>
				<updated>2006-03-15T19:49:03Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentRegistry.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;]. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called [{{SERVER}}/workbench/api/org/geworkbench/engine/config/PluginDescriptor.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt;]. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentResource.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt;] class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the [{{SERVER}}/workbench/api/org/geworkbench/events/ProjectEvent.html &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt;] type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the [{{SERVER}}/workbench/api/org/geworkbench/engine/management/SynchModel.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt;] interface. Four implementations are provided with geWorkbench (all in the &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt; package):&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt; - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt; - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt; - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt; from another component. This events are usually generated as the result of an analysis by the publishing component.&lt;br /&gt;
&lt;br /&gt;
The conceppt of data sets is central to geWorkbench development. Many plugins can be characterized by the types of data sets they process and the types of data sets that they produce.&lt;br /&gt;
&lt;br /&gt;
== Visual Plugins and GUIFramework ==&lt;br /&gt;
&lt;br /&gt;
Many plugins have a visual representation. This visual intention is advertised to the framework by the plugin implementing &amp;lt;tt&amp;gt;org.geworkbench.engine.config.VisualPlugin&amp;lt;/tt&amp;gt;. Some plugins, such as file parsers and analyses, do not require a visual representation, and so do not implement this interface.&lt;br /&gt;
&lt;br /&gt;
Those that implement VisualPlugin will have extra directives included in the configuration file to indicate how they should be laid out in the interface. These directives are passed on from the configuration engine to the rendering framework. The rendering framework is itself configurable, and is a class that extends &amp;lt;tt&amp;gt;org.geworkbench.engine.config.GUIFramework&amp;lt;/tt&amp;gt;. The default and most full-featured implementation of GUIFramework is &amp;lt;tt&amp;gt;org.geworkbench.engine.config.Skin&amp;lt;/tt&amp;gt;. This implementation supports four layout areas (''Project'', ''Selection'', ''Command'' and ''Visual''). It also supports an annotation system for determining which visual components to display based on the selected data set in the Project Panel.&lt;br /&gt;
&lt;br /&gt;
Visual plugins may annotate their class definition with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.AcceptTypes&amp;lt;/tt&amp;gt;. If the annotation is omitted, then the visual plugin will always be rendered by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. The annotation takes an array of class objects, each of which must be assignable to &amp;lt;tt&amp;gt;DSDataSet&amp;lt;/tt&amp;gt;. For example, here is how the ''Color Mosaic Panel'' is annotated:&lt;br /&gt;
&lt;br /&gt;
 @AcceptTypes({DSMicroarraySet.class, DSSignificanceResultSet.class}) public class ColorMosaicPanel implements VisualPlugin ...&lt;br /&gt;
&lt;br /&gt;
When the Project Panel generates a &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; resulting from a data set node being selected, the type of the data set is examined by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. Each component that has a type in its @AcceptTypes annotation that is assignable from the selected data set type is made visible in the interface. Additionally, all unannotated components are also made visible. Annotated components without a type assignable from the selected d ata set are hidden. This way, the user is only presented with relevant components upon selection of a data set node.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2847</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2847"/>
				<updated>2006-03-15T19:47:07Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is [{{SERVER}}/workbench/api/org/geworkbench/engine/management/ComponentRegistry.html &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;]. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called [{{SERVER}}/workbench/api/org/geworkbench/engine/config/PluginDescriptor.html &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt;]. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt; interface. Four implementations are provided with geWorkbench (all in the &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt; package):&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt; - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt; - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt; - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt; from another component. This events are usually generated as the result of an analysis by the publishing component.&lt;br /&gt;
&lt;br /&gt;
The conceppt of data sets is central to geWorkbench development. Many plugins can be characterized by the types of data sets they process and the types of data sets that they produce.&lt;br /&gt;
&lt;br /&gt;
== Visual Plugins and GUIFramework ==&lt;br /&gt;
&lt;br /&gt;
Many plugins have a visual representation. This visual intention is advertised to the framework by the plugin implementing &amp;lt;tt&amp;gt;org.geworkbench.engine.config.VisualPlugin&amp;lt;/tt&amp;gt;. Some plugins, such as file parsers and analyses, do not require a visual representation, and so do not implement this interface.&lt;br /&gt;
&lt;br /&gt;
Those that implement VisualPlugin will have extra directives included in the configuration file to indicate how they should be laid out in the interface. These directives are passed on from the configuration engine to the rendering framework. The rendering framework is itself configurable, and is a class that extends &amp;lt;tt&amp;gt;org.geworkbench.engine.config.GUIFramework&amp;lt;/tt&amp;gt;. The default and most full-featured implementation of GUIFramework is &amp;lt;tt&amp;gt;org.geworkbench.engine.config.Skin&amp;lt;/tt&amp;gt;. This implementation supports four layout areas (''Project'', ''Selection'', ''Command'' and ''Visual''). It also supports an annotation system for determining which visual components to display based on the selected data set in the Project Panel.&lt;br /&gt;
&lt;br /&gt;
Visual plugins may annotate their class definition with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.AcceptTypes&amp;lt;/tt&amp;gt;. If the annotation is omitted, then the visual plugin will always be rendered by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. The annotation takes an array of class objects, each of which must be assignable to &amp;lt;tt&amp;gt;DSDataSet&amp;lt;/tt&amp;gt;. For example, here is how the ''Color Mosaic Panel'' is annotated:&lt;br /&gt;
&lt;br /&gt;
 @AcceptTypes({DSMicroarraySet.class, DSSignificanceResultSet.class}) public class ColorMosaicPanel implements VisualPlugin ...&lt;br /&gt;
&lt;br /&gt;
When the Project Panel generates a &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; resulting from a data set node being selected, the type of the data set is examined by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. Each component that has a type in its @AcceptTypes annotation that is assignable from the selected data set type is made visible in the interface. Additionally, all unannotated components are also made visible. Annotated components without a type assignable from the selected d ata set are hidden. This way, the user is only presented with relevant components upon selection of a data set node.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2845</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2845"/>
				<updated>2006-03-14T21:02:37Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Visual Plugins and GUIFramework */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt; interface. Four implementations are provided with geWorkbench (all in the &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt; package):&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt; - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt; - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt; - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt; from another component. This events are usually generated as the result of an analysis by the publishing component.&lt;br /&gt;
&lt;br /&gt;
The conceppt of data sets is central to geWorkbench development. Many plugins can be characterized by the types of data sets they process and the types of data sets that they produce.&lt;br /&gt;
&lt;br /&gt;
== Visual Plugins and GUIFramework ==&lt;br /&gt;
&lt;br /&gt;
Many plugins have a visual representation. This visual intention is advertised to the framework by the plugin implementing &amp;lt;tt&amp;gt;org.geworkbench.engine.config.VisualPlugin&amp;lt;/tt&amp;gt;. Some plugins, such as file parsers and analyses, do not require a visual representation, and so do not implement this interface.&lt;br /&gt;
&lt;br /&gt;
Those that implement VisualPlugin will have extra directives included in the configuration file to indicate how they should be laid out in the interface. These directives are passed on from the configuration engine to the rendering framework. The rendering framework is itself configurable, and is a class that extends &amp;lt;tt&amp;gt;org.geworkbench.engine.config.GUIFramework&amp;lt;/tt&amp;gt;. The default and most full-featured implementation of GUIFramework is &amp;lt;tt&amp;gt;org.geworkbench.engine.config.Skin&amp;lt;/tt&amp;gt;. This implementation supports four layout areas (''Project'', ''Selection'', ''Command'' and ''Visual''). It also supports an annotation system for determining which visual components to display based on the selected data set in the Project Panel.&lt;br /&gt;
&lt;br /&gt;
Visual plugins may annotate their class definition with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.AcceptTypes&amp;lt;/tt&amp;gt;. If the annotation is omitted, then the visual plugin will always be rendered by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. The annotation takes an array of class objects, each of which must be assignable to &amp;lt;tt&amp;gt;DSDataSet&amp;lt;/tt&amp;gt;. For example, here is how the ''Color Mosaic Panel'' is annotated:&lt;br /&gt;
&lt;br /&gt;
 @AcceptTypes({DSMicroarraySet.class, DSSignificanceResultSet.class}) public class ColorMosaicPanel implements VisualPlugin ...&lt;br /&gt;
&lt;br /&gt;
When the Project Panel generates a &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; resulting from a data set node being selected, the type of the data set is examined by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. Each component that has a type in its @AcceptTypes annotation that is assignable from the selected data set type is made visible in the interface. Additionally, all unannotated components are also made visible. Annotated components without a type assignable from the selected d ata set are hidden. This way, the user is only presented with relevant components upon selection of a data set node.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2844</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2844"/>
				<updated>2006-03-14T20:58:39Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt; interface. Four implementations are provided with geWorkbench (all in the &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt; package):&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt; - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt; - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt; - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt; from another component. This events are usually generated as the result of an analysis by the publishing component.&lt;br /&gt;
&lt;br /&gt;
The conceppt of data sets is central to geWorkbench development. Many plugins can be characterized by the types of data sets they process and the types of data sets that they produce.&lt;br /&gt;
&lt;br /&gt;
== Visual Plugins and GUIFramework ==&lt;br /&gt;
&lt;br /&gt;
Many plugins have a visual representation. This visual intention is advertised to the framework by the plugin implementing &amp;lt;tt&amp;gt;org.geworkbench.engine.config.VisualPlugin&amp;lt;/tt&amp;gt;. Some plugins, such as file parsers and analyses, do not require a visual representation, and so do not implement this interface.&lt;br /&gt;
&lt;br /&gt;
Those that implement VisualPlugin will have extra directives included in the configuration file to indicate how they should be laid out in the interface. These directives are passed on from the configuration engine to the rendering framework. The rendering framework is itself configurable, and is a class that extends &amp;lt;tt&amp;gt;org.geworkbench.engine.config.GUIFramework&amp;lt;/tt&amp;gt;. The default and most full-featured implementation of GUIFramework is &amp;lt;tt&amp;gt;org.geworkbench.engine.config.Skin&amp;lt;/tt&amp;gt;. This implementation supports four layout areas (''Project'', ''Selection'', ''Command'' and ''Visual''). It also supports an annotation system for determining which visual components to display based on the selected data set in the Project Panel.&lt;br /&gt;
&lt;br /&gt;
Visual plugins may annotate their class definition with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.AcceptTypes&amp;lt;/tt&amp;gt;. If the annotation is omitted, then the visual plugin will always be rendered by &amp;lt;tt&amp;gt;Skin&amp;lt;/tt&amp;gt;. The annotation takes an array of class objects, each of which must be assignable to &amp;lt;tt&amp;gt;DSDataSet&amp;lt;/tt&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2843</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2843"/>
				<updated>2006-03-14T20:54:09Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt; interface. Four implementations are provided with geWorkbench (all in the &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt; package):&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt; - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt; - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt; - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt; from another component. This events are usually generated as the result of an analysis by the publishing component.&lt;br /&gt;
&lt;br /&gt;
The conceppt of data sets is central to geWorkbench development. Many plugins can be characterized by the types of data sets they process and the types of data sets that they produce.&lt;br /&gt;
&lt;br /&gt;
== Visual Plugins and GUIFramework ==&lt;br /&gt;
&lt;br /&gt;
Many plugins have a visual representation. This visual intention is advertised to the framework by the plugin implementing &amp;lt;tt&amp;gt;org.geworkbench.engine.config.VisualPlugin&amp;lt;/tt&amp;gt;. Some plugins, such as file parsers and analyses, do not require a visual representation, and so do not implement this interface.&lt;br /&gt;
&lt;br /&gt;
Those that implement VisualPlugin will have extra directives included in the configuration file to indicate how they should be laid out in the interface. These directives are passed on from the configuration engine to the rendering framework. The rendering framework is itself configurable, and is a class that extends &amp;lt;tt&amp;gt;org.geworkbench.engine.config.GUIFramework&amp;lt;/tt&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2842</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2842"/>
				<updated>2006-03-14T20:46:07Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;org.geworkbench.engine.config.PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;org.geworkbench.engine.management.ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;java.lang.Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;org.geworkbench.engine.management.Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the &amp;lt;tt&amp;gt;org.geworkbench.engine.management.SynchModel&amp;lt;/tt&amp;gt; interface. Four implementations are provided with geWorkbench (all in the &amp;lt;tt&amp;gt;org.geworkbench.engine.management&amp;lt;/tt&amp;gt; package):&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt; - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt; - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt; - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface &amp;lt;tt&amp;gt;org.geworkbench.bison.datastructure.biocollections.DSDataSet&amp;lt;/tt&amp;gt;. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt; from another component.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2841</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2841"/>
				<updated>2006-03-14T20:41:49Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the &amp;lt;tt&amp;gt;SynchModel&amp;lt;/tt&amp;gt; interface. Four implementations are provided with geWorkbench:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt; - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt; - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped. This is very useful in situations where a component may receive many rapid updates to a state from other components, but each update contains complete information about the state at that time, rendering previous state updates obsolete.&lt;br /&gt;
* &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt; - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
== The Project Panel and Data Sets ==&lt;br /&gt;
&lt;br /&gt;
While the Project Panel is itself a geWorkbench plugin, it has some special properties that merit a mention. The Project Panel need not be the only source of project selection events, but this is typically the case. In this way, it becomes the central point of organization for the application.&lt;br /&gt;
&lt;br /&gt;
All entries in the Project Panel below the level of ''Project'' nodes are data sets that implement the interface &amp;lt;tt&amp;gt;DSDataSet&amp;lt;/tt&amp;gt;. These nodes are created in one of two ways. The first is that the Project Panel was used to load a data set from disk or some other network resource. In this case, a non-visual plugin extending &amp;lt;tt&amp;gt;org.geworkbench.engine.parsers.FileFormat&amp;lt;/tt&amp;gt; is used to parse the data and construct a data set. The second is that the Project Panel receives a &amp;lt;tt&amp;gt;org.geworkbench.events.ProjectNodeAddedEvent&amp;lt;/tt&amp;gt; from another component.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2840</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2840"/>
				<updated>2006-03-14T20:28:27Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Publish/Subscribe */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source) { ... }&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent() { ... }&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synch Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the &amp;lt;tt&amp;gt;SynchModel&amp;lt;/tt&amp;gt; interface. Four implementations are provided with geWorkbench:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt; - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt; - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped.&lt;br /&gt;
* &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt; - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2839</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2839"/>
				<updated>2006-03-14T20:27:59Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Synch Models */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source);&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent();&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Synch Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However, occasionally special handling is required for the subscribe methods. For example, a subscribe method for a visual plugin may need to be run on the Swing event-dispatching thread. Another example would be a subscribe method that results in a fairly long-running  computation. It maybe desirable that this subscribe method is called in the background rather than on the publishing thread.&lt;br /&gt;
&lt;br /&gt;
The author of the plugin can specify a ''synchronization model'' as a parameter to the subscribe method in this case. A syncrhonization model is any class that implements the &amp;lt;tt&amp;gt;SynchModel&amp;lt;/tt&amp;gt; interface. Four implementations are provided with geWorkbench:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;Synchronous&amp;lt;/tt&amp;gt; - The default, runs the subscribe method synchronously on the publishing thread.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;  - Runs the subscribe method in the background on one thread from a thread pool.&lt;br /&gt;
* &amp;lt;tt&amp;gt;Overflow&amp;lt;/tt&amp;gt; - Similar to &amp;lt;tt&amp;gt;Asynchronous&amp;lt;/tt&amp;gt;, this model runs subscribe methods on a background thread. However, if multiple subscribe events for a given component and method accrue during the processing of a subscribe event for that component and method, then all but the last of these events will be dropped.&lt;br /&gt;
* &amp;lt;tt&amp;gt;SwingModel&amp;lt;/tt&amp;gt; - This ensures that the subscribe method is run on the Swing event-dispatching thread.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to specify a synchronization model for a subscribe method:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe(Asynchronous.class) public void receive(ProjectEvent event, Object source) { ... }&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2838</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2838"/>
				<updated>2006-03-14T18:36:58Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Publish/Subscribe */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source);&lt;br /&gt;
&lt;br /&gt;
Note that subscribe methods must take two parameters, and the second parameter must be of type &amp;lt;tt&amp;gt;Object&amp;lt;/tt&amp;gt;. Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent();&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;br /&gt;
&lt;br /&gt;
When a publish method is called in a component, the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; will intercept the call (via CGLIB). It will allow the method call to proceed normally. The type of the returned value is then examined. Each component that has a subscribe method that is linked to a type that is assignable from the published type will have that method called, with the publish object as the first parameter, and the component that published the object as the second parameter.&lt;br /&gt;
&lt;br /&gt;
=== Event Models ===&lt;br /&gt;
&lt;br /&gt;
Normally, the above publish/subscribe sequence is processed serially by the same thread that called the publish method. In many situations, this behavior is acceptable. However occasionally, special handling is required for the subscribe methods.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2837</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2837"/>
				<updated>2006-03-14T18:04:52Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Publish/Subscribe */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ''subscribe method'':&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source);&lt;br /&gt;
&lt;br /&gt;
Below is the method signature for a typical ''publish method'':&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent();&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ''polymorphic''; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2836</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2836"/>
				<updated>2006-03-14T18:04:21Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Publish/Subscribe */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include annotated methods that indicate their publish or subscribe behavior. Below is the method signature for a typical ~~subscribe method~~:&lt;br /&gt;
&lt;br /&gt;
 @Subscribe public void receive(ProjectEvent event, Object source);&lt;br /&gt;
&lt;br /&gt;
Below is the method signature for a typical ~~publish method~~:&lt;br /&gt;
&lt;br /&gt;
 @Publish public ProjectEvent publishProjectEvent();&lt;br /&gt;
&lt;br /&gt;
Upon instantiation of a component, the ComponentRegistry finds all methods that are annotated with &amp;lt;tt&amp;gt;Subscribe&amp;lt;/tt&amp;gt;. It maintains a data structure that maps each subscribe method to the type of its first parameter. For example, the above example would link the &amp;lt;tt&amp;gt;receive&amp;lt;/tt&amp;gt; method to the &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; type. Furthermore, this link is ~~polymorphic~~; that is, a type that extends &amp;lt;tt&amp;gt;ProjectEvent&amp;lt;/tt&amp;gt; will also be linked to this method.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2835</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2835"/>
				<updated>2006-03-14T17:58:26Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Component Instantiation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
=== Component Resources ===&lt;br /&gt;
&lt;br /&gt;
Plugins consist of Java class files, optional library files and optional resource files. These files are created independently by groups of developers. It is possible that some files of one plugin could conflict with some file of another plugin. This is particularly true of library files. For example, one plugin may use a more recent version of a popular library than another plugin. To prevent such unwanted dependency issues, components are instantiated with their own classloader. This classloader resolves classes and resources in the following order:&lt;br /&gt;
&lt;br /&gt;
# The &amp;lt;tt&amp;gt;classes&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# The &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory of the plugin.&lt;br /&gt;
# Defers to the main classloader of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
This resolution scheme is similar to web application containers (such as Tomcat). The &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; class holds the classloader data for each component, and the link between components and &amp;lt;tt&amp;gt;ComponentResource&amp;lt;/tt&amp;gt; instances is maintained by the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2834</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2834"/>
				<updated>2006-03-14T17:50:27Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active plugins (known herein as ''components''). It also keeps track of the publish/subscribe behavior of the plugins. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
Note the following definitions:&lt;br /&gt;
&lt;br /&gt;
; Plugin : The implementation of a geWorkbench add-on.&lt;br /&gt;
; Component : An instance of a plugin active in geWorkbench. Note that it is possible for there to be zero or more components for each plugin. Typically, however, there will be just zero or one components for each plugin.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which plugins should be instantiated in to components. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a plugin-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the plugin, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;. The configuration engine creates the &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt; object and passes it on to the &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. There, the component is instantiated and a CGLIB wrapper is applied. The &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt; stores the component and its associated descriptor for later use. It passes back the instantiated component to the configuration engine. In the case that the component is an instance of a visual plugin, the configuration engine ensures that the component is added to the appropriate visual area.&lt;br /&gt;
&lt;br /&gt;
== Publish/Subscribe ==&lt;br /&gt;
&lt;br /&gt;
Components communicate via a publish/subscribe model. Plugins will include&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2833</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2833"/>
				<updated>2006-03-14T17:39:53Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active components (also known as ''Plugins''). It also keeps track of the publish/subscribe behavior of the plugins. The Component Registry makes use of CGLIB (http://cglib.sourceforge.net) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;br /&gt;
&lt;br /&gt;
== Component Instantiation ==&lt;br /&gt;
&lt;br /&gt;
An XML configuration file specifies which components should be instantiated in to plugins. This is parsed by a set of Apache Digester directives (http://jakarta.apache.org/commons/digester). Also parsed is a component-specific configuration file. This file has the same name and path as the component class file, but it has a &amp;lt;tt&amp;gt;.cwb.xml&amp;lt;/tt&amp;gt; extension. This file includes some metadata about the component, such as the location of its help files, the area of the visual interface that the component should be installed, and what menu items it responds to. This metadata is stored in a class called &amp;lt;tt&amp;gt;PluginDescriptor&amp;lt;/tt&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2832</id>
		<title>Framework</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Framework&amp;diff=2832"/>
				<updated>2006-03-14T17:26:14Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the operation of the geWorkbench framework. This information could be of use to plugin developers who desire a deeper understanding of geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Component Registry ==&lt;br /&gt;
&lt;br /&gt;
The central class to the geWorkbench framework is &amp;lt;tt&amp;gt;ComponentRegistry&amp;lt;/tt&amp;gt;. This class is responsible for maintaining look-up tables of all active components. It also keeps track of the publish/subscribe behavior of the components. The Component Registry makes use of CGLIB (http://cglib.sourceforge.net/) to intercept methods and apply framework functionality. This will be covered in detail in the following sections.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Color_Mosaic_Design&amp;diff=2289</id>
		<title>Color Mosaic Design</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Color_Mosaic_Design&amp;diff=2289"/>
				<updated>2006-02-21T16:38:38Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Plugin Type ===&lt;br /&gt;
&lt;br /&gt;
The Color Mosaic Panel is a ''Visualization'' plugin.&lt;br /&gt;
&lt;br /&gt;
=== Data Sets ===&lt;br /&gt;
&lt;br /&gt;
The Color Mosaic Panel renders ''DSMicroarraySet'' and ''DSSignificanceResultSet'' data sets. It does not create any data sets.&lt;br /&gt;
&lt;br /&gt;
=== Subscribed Types ===&lt;br /&gt;
&lt;br /&gt;
The Color Mosaic Panel subscribes to the following types:&lt;br /&gt;
&lt;br /&gt;
# '''ProjectEvent''' - Receives data sets from the Project Panel.&lt;br /&gt;
# '''AssociationPanelEvent''' - Receives p-values associated with the markers of a microarray set via this event.&lt;br /&gt;
# '''PhenotypeSelectorEvent''' - Notifies the plugin of a change to Phenotype selection.&lt;br /&gt;
# '''GeneSelectorEvent''' - Notifies the plugin of a change to Gene selection.&lt;br /&gt;
&lt;br /&gt;
=== Published Types ===&lt;br /&gt;
&lt;br /&gt;
# '''MarkerSelectedEvent''' - Published when a marker is selected in the visualization.&lt;br /&gt;
# '''ImageSnapshotEvent''' - Published when an image snapshot is requested for the plugin.&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
&lt;br /&gt;
The Color Mosaic displays a heat map of a microarray set. Microarrays are displayed in the columns, and markers are displayed in the rows. It can render the entire set, or subset of markers and microarrays can be rendered. Active phenotype and gene selections are labelled in the color mosaic. If the result of T-Test or similar significance test is visualized, the associated p-values can also be included in the display.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Color_Mosaic_Design&amp;diff=2288</id>
		<title>Color Mosaic Design</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Color_Mosaic_Design&amp;diff=2288"/>
				<updated>2006-02-21T16:35:35Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Plugin Type ===&lt;br /&gt;
&lt;br /&gt;
The Color Mosaic Panel is a ''Visualization'' plugin.&lt;br /&gt;
&lt;br /&gt;
=== Data Sets ===&lt;br /&gt;
&lt;br /&gt;
The Color Mosaic Panel renders ''DSMicroarraySet'' and ''DSSignificanceResultSet'' data sets. It does not create any data sets.&lt;br /&gt;
&lt;br /&gt;
=== Subscribed Types ===&lt;br /&gt;
&lt;br /&gt;
The Color Mosaic Panel subscribes to the following types:&lt;br /&gt;
&lt;br /&gt;
# '''ProjectEvent''' - Receives data sets from the Project Panel.&lt;br /&gt;
# '''AssociationPanelEvent''' - Receives p-values associated with the markers of a microarray set via this event.&lt;br /&gt;
# '''PhenotypeSelectorEvent''' - Notifies the plugin of a change to Phenotype selection.&lt;br /&gt;
# '''GeneSelectorEvent''' - Notifies the plugin of a change to Gene selection.&lt;br /&gt;
&lt;br /&gt;
=== Published Types ===&lt;br /&gt;
&lt;br /&gt;
# '''MarkerSelectedEvent''' - Published when a marker is selected in the visualization.&lt;br /&gt;
# '''ImageSnapshotEvent''' - Published when an image snapshot is requested for the plugin.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugin_Design_Documentation&amp;diff=2284</id>
		<title>Plugin Design Documentation</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugin_Design_Documentation&amp;diff=2284"/>
				<updated>2006-02-21T16:33:19Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the requirements for plugin design documentation.&lt;br /&gt;
&lt;br /&gt;
=== Plugin Type ===&lt;br /&gt;
&lt;br /&gt;
Plugins can generally be categorized as one of the following:&lt;br /&gt;
# '''File Filter''' - A plugin that can read a data set from a stream.&lt;br /&gt;
# '''Analysis''' - A plugin that performs an analysis on a data set (often producing a result data set).&lt;br /&gt;
# '''Visualization''' - A plugin that creates a visualization of a data set.&lt;br /&gt;
# '''Interactive''' - A plugin that is a hybrid of ''Analysis'' and ''Visualization'' types.&lt;br /&gt;
&lt;br /&gt;
=== Data Sets ===&lt;br /&gt;
&lt;br /&gt;
All data sets that the plugin can operate on should be listed. If a plugin operates on a super-type data set, the sub-types need not be listed. If the plugin is capable of producing data sets, these types should be listed as well. Image snapshots need not be considered as produced data sets, since most visualization components create these.&lt;br /&gt;
&lt;br /&gt;
=== Subscribed Types ===&lt;br /&gt;
&lt;br /&gt;
The data types to which this plugin subscribes should be listed. If the subscription has a synchronization model other than ''Synchronous'' or ''SwingModel'', then it should be indicated.&lt;br /&gt;
&lt;br /&gt;
=== Published Types ===&lt;br /&gt;
&lt;br /&gt;
The data types that are published by the plugin should be listed. Additionally, the conditions upon which the types are published should be indicated.&lt;br /&gt;
&lt;br /&gt;
=== Remote Access ===&lt;br /&gt;
&lt;br /&gt;
If the plugin makes any connections to remote hosts, information about such connections should be listed. The protocol, port, host (if fixed) and credential requirements should be included. Additionally, the conditions upon which plugin initiates remote access should be stated.&lt;br /&gt;
&lt;br /&gt;
=== Description of Behavior ===&lt;br /&gt;
&lt;br /&gt;
A brief description of the plugins behavior should be included.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
See an example of this documentation: [[Color Mosaic Design]].&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Color_Mosaic_Design&amp;diff=2282</id>
		<title>Color Mosaic Design</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Color_Mosaic_Design&amp;diff=2282"/>
				<updated>2006-02-21T16:32:46Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Plugin Type ===&lt;br /&gt;
&lt;br /&gt;
The Color Mosaic Panel is a ''Visualization'' plugin.&lt;br /&gt;
&lt;br /&gt;
=== Data Sets ===&lt;br /&gt;
&lt;br /&gt;
The Color Mosaic Panel renders ''DSMicroarraySet'' and ''DSSignificanceResultSet'' data sets. It does not create any data sets.&lt;br /&gt;
&lt;br /&gt;
=== Subscribed Types ===&lt;br /&gt;
&lt;br /&gt;
The Color Mosaic Panel subscribes to the following types:&lt;br /&gt;
&lt;br /&gt;
# '''ProjectEvent''' - Receives data sets from the Project Panel.&lt;br /&gt;
# '''AssociationPanelEvent''' - Receives p-values associated with the markers of a microarray set via this event.&lt;br /&gt;
# '''PhenotypeSelectorEvent''' - Notifies the plugin of a change to Phenotype selection.&lt;br /&gt;
# '''GeneSelectorEvent''' - Notifies the plugin of a change to Gene selection.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugin_Design_Documentation&amp;diff=2281</id>
		<title>Plugin Design Documentation</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugin_Design_Documentation&amp;diff=2281"/>
				<updated>2006-02-21T16:25:32Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the requirements for plugin design documentation.&lt;br /&gt;
&lt;br /&gt;
=== Plugin Type ===&lt;br /&gt;
&lt;br /&gt;
Plugins can generally be categorized as one of the following:&lt;br /&gt;
# '''File Filter''' - A plugin that can read a data set from a stream.&lt;br /&gt;
# '''Analysis''' - A plugin that performs an analysis on a data set (often producing a result data set).&lt;br /&gt;
# '''Visualization''' - A plugin that creates a visualization of a data set.&lt;br /&gt;
# '''Interactive''' - A plugin that is a hybrid of ''Analysis'' and ''Visualization'' types.&lt;br /&gt;
&lt;br /&gt;
=== Data Sets ===&lt;br /&gt;
&lt;br /&gt;
All data sets that the plugin can operate on should be listed. If a plugin operates on a super-type data set, the sub-types need not be listed. If the plugin is capable of producing data sets, these types should be listed as well.&lt;br /&gt;
&lt;br /&gt;
=== Subscribed Types ===&lt;br /&gt;
&lt;br /&gt;
The data types to which this plugin subscribes should be listed. If the subscription has a synchronization model other than ''Synchronous'' or ''SwingModel'', then it should be indicated.&lt;br /&gt;
&lt;br /&gt;
=== Published Types ===&lt;br /&gt;
&lt;br /&gt;
The data types that are published by the plugin should be listed. Additionally, the conditions upon which the types are published should be indicated.&lt;br /&gt;
&lt;br /&gt;
=== Remote Access ===&lt;br /&gt;
&lt;br /&gt;
If the plugin makes any connections to remote hosts, information about such connections should be listed. The protocol, port, host (if fixed) and credential requirements should be included. Additionally, the conditions upon which plugin initiates remote access should be stated.&lt;br /&gt;
&lt;br /&gt;
=== Description of Behavior ===&lt;br /&gt;
&lt;br /&gt;
A brief description of the plugins behavior should be included.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
See an example of this documentation: [[Color Mosaic Design]].&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugin_Design_Documentation&amp;diff=2280</id>
		<title>Plugin Design Documentation</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugin_Design_Documentation&amp;diff=2280"/>
				<updated>2006-02-21T16:23:55Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the requirements for plugin design documentation.&lt;br /&gt;
&lt;br /&gt;
=== Plugin Type ===&lt;br /&gt;
&lt;br /&gt;
Plugins can generally be categorized as one of the following:&lt;br /&gt;
# '''File Filter''' - A plugin that can read a data set from a stream.&lt;br /&gt;
# '''Analysis''' - A plugin that performs an analysis on a data set (often producing a result data set).&lt;br /&gt;
# '''Visualization''' - A plugin that creates a visualization of a data set.&lt;br /&gt;
# '''Interactive''' - A plugin that is a hybrid of ''Analysis'' and ''Visualization'' types.&lt;br /&gt;
&lt;br /&gt;
=== Data Sets ===&lt;br /&gt;
&lt;br /&gt;
All data sets that the plugin can operate on should be listed. If a plugin operates on a super-type data set, the sub-types need not be listed. If the plugin is capable of producing data sets, these types should be listed as well.&lt;br /&gt;
&lt;br /&gt;
=== Subscribed Types ===&lt;br /&gt;
&lt;br /&gt;
The data types to which this plugin subscribes should be listed. If the subscription has a synchronization model other than ''Synchronous'' or ''SwingModel'', then it should be indicated.&lt;br /&gt;
&lt;br /&gt;
=== Published Types ===&lt;br /&gt;
&lt;br /&gt;
The data types that are published by the plugin should be listed. Additionally, the conditions upon which the types are published should be indicated.&lt;br /&gt;
&lt;br /&gt;
=== Remote Access ===&lt;br /&gt;
&lt;br /&gt;
If the plugin makes any connections to remote hosts, information about such connections should be listed. The protocol, port, host (if fixed) and credential requirements should be included. Additionally, the conditions upon which plugin initiates remote access should be stated.&lt;br /&gt;
&lt;br /&gt;
=== Description of Behavior ===&lt;br /&gt;
&lt;br /&gt;
A brief description of the plugins behavior should be included.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugin_Design_Documentation&amp;diff=2273</id>
		<title>Plugin Design Documentation</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugin_Design_Documentation&amp;diff=2273"/>
				<updated>2006-02-21T16:14:54Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document outlines the requirements for plugin design documentation.&lt;br /&gt;
&lt;br /&gt;
=== Plugin Type ===&lt;br /&gt;
&lt;br /&gt;
Plugins can generally be categorized as one of the following:&lt;br /&gt;
# '''File Filter''' - A plugin that can read a data set from a stream.&lt;br /&gt;
# '''Analysis''' - A plugin that performs an analysis on a data set (often producing a result data set).&lt;br /&gt;
# '''Visualization''' - A plugin that creates a visualization of a data set.&lt;br /&gt;
# '''Interactive''' - A plugin that is a hybrid of ''Analysis'' and ''Visualization'' types.&lt;br /&gt;
&lt;br /&gt;
=== Data Sets ===&lt;br /&gt;
&lt;br /&gt;
All data sets that the plugin can operate on should be listed. If a plugin operates on a super-type data set, the sub-types need not be listed. If the plugin is capable of producing data sets, these types should be listed as well.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Developers&amp;diff=1748</id>
		<title>Developers</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Developers&amp;diff=1748"/>
				<updated>2006-02-01T18:31:08Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Introduction_For_Developers|Introduction For Developers]]&lt;br /&gt;
* [[Devkit|Instructions]] for the Developer Kit&lt;br /&gt;
* [[Building geWorkbench]]&lt;br /&gt;
* Coding Standards [[Style Guide]]&lt;br /&gt;
* [http://caldev/workbench/api Javadocs]&lt;br /&gt;
* [[CVS Repository]]&lt;br /&gt;
* [[Screenshots]]&lt;br /&gt;
* Information on [[.GEAR files]], a method of distributing plugins.&lt;br /&gt;
* [[Plugin certification checklist]]&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1747</id>
		<title>Software Development Kit</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1747"/>
				<updated>2006-02-01T18:29:40Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Developer Kit is a self-contained package that facilitates the process of developing plugins for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Using the Developer Kit ==&lt;br /&gt;
&lt;br /&gt;
The Developer Kit is available as a .zip file. Unzip it in to a directory of your choice, then follow the instructions below to create a geWorkbench plugin.&lt;br /&gt;
&lt;br /&gt;
The high-level steps for creating, testing and releasing a plugin are as follows:&lt;br /&gt;
&lt;br /&gt;
# Edit the provided Apache Ant build script to specify the name of your plugin.&lt;br /&gt;
# Add the .java source files for your plugin to the &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Add any .jar libraries that your plugin requires to the &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ant&amp;lt;/tt&amp;gt; to build your plugin.&lt;br /&gt;
# Edit the geWorkbench configuration file to add a directive for your new plugin.&lt;br /&gt;
# Run geWorkbench with &amp;lt;tt&amp;gt;ant run&amp;lt;/tt&amp;gt; to test your plugin.&lt;br /&gt;
# Once satisfied with your plugin, use the provided utility to package your plugin in to a single file for distribution.&lt;br /&gt;
&lt;br /&gt;
The next section will illustrate the above steps with an example.&lt;br /&gt;
&lt;br /&gt;
== An Example Plugin ==&lt;br /&gt;
&lt;br /&gt;
We will create an example plugin that is simply called &amp;lt;tt&amp;gt;test&amp;lt;/tt&amp;gt;. This will be a very simple visualization plugin that just displays a blank blue region.&lt;br /&gt;
&lt;br /&gt;
=== Setting the Plugin Name ===&lt;br /&gt;
&lt;br /&gt;
In the provided &amp;lt;tt&amp;gt;build.xml&amp;lt;/tt&amp;gt;, this line can be found near the beginning of the file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;noname&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line is changed to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;test&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This specifies the name of our component, which is used for all build products.&lt;br /&gt;
&lt;br /&gt;
=== Adding Source ===&lt;br /&gt;
&lt;br /&gt;
Next, a single .java source file is added to the org.organization.test package. The file &amp;lt;tt&amp;gt;TestComponent.java&amp;lt;/tt&amp;gt; goes in the &amp;lt;tt&amp;gt;src/org/organization/test&amp;lt;/tt&amp;gt; and has the following contents:&lt;br /&gt;
&lt;br /&gt;
 package org.organization.test;&lt;br /&gt;
 &lt;br /&gt;
 import org.geworkbench.engine.config.VisualPlugin;&lt;br /&gt;
  &lt;br /&gt;
 import javax.swing.*;&lt;br /&gt;
 import java.awt.*;&lt;br /&gt;
  &lt;br /&gt;
 /**&lt;br /&gt;
  * A simple component for demonstration purposes.&lt;br /&gt;
  *&lt;br /&gt;
  * @author John Watkinson&lt;br /&gt;
  */&lt;br /&gt;
 public class TestComponent implements VisualPlugin {&lt;br /&gt;
  &lt;br /&gt;
     private JPanel panel;&lt;br /&gt;
  &lt;br /&gt;
     public TestComponent() {&lt;br /&gt;
         panel = new JPanel();&lt;br /&gt;
         panel.setBackground(Color.blue);&lt;br /&gt;
     }&lt;br /&gt;
  &lt;br /&gt;
     public Component getComponent() {&lt;br /&gt;
         return panel;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If the component required any .jar files, those would be added to the &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
=== Configure Plugin ===&lt;br /&gt;
&lt;br /&gt;
The configuration file for the Developer Kit is called &amp;lt;tt&amp;gt;minimal.xml&amp;lt;/tt&amp;gt; and it is in the &amp;lt;tt&amp;gt;conf&amp;lt;/tt&amp;gt; directory. The following directive is added:&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;plugin id=&amp;quot;testPanel&amp;quot; name=&amp;quot;Test Panel&amp;quot; class=&amp;quot;org.organization.test.TestComponent&amp;quot; source=&amp;quot;test&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;gui-area name=&amp;quot;VisualArea&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/plugin&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Running the Plugin in geWorkbench ===&lt;br /&gt;
&lt;br /&gt;
The plugin will now appear when the application is run. It can be run with the command:&lt;br /&gt;
&lt;br /&gt;
 ant run&lt;br /&gt;
&lt;br /&gt;
=== Releasing the Plugin ===&lt;br /&gt;
&lt;br /&gt;
Satisfied with the plugin, it can now be released by running:&lt;br /&gt;
&lt;br /&gt;
 ant gear&lt;br /&gt;
&lt;br /&gt;
This creates the file &amp;lt;tt&amp;gt;test.gear&amp;lt;/tt&amp;gt;. A .gear file is the geWorkbench analogue of a .war file for a web application. Is a bundled  plugin that can deployed to a geWorkbench install by placing the file in the &amp;lt;tt&amp;gt;components&amp;lt;/tt&amp;gt; directory. A configuration directive (such as the one above) would also need to be added to the configuration file to activate the plugin.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1746</id>
		<title>Software Development Kit</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1746"/>
				<updated>2006-02-01T18:27:05Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Developer Kit is a self-contained package that facilitates the process of developing plugins for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Using the Developer Kit ==&lt;br /&gt;
&lt;br /&gt;
The Developer Kit is available as a .zip file. Unzip it in to a directory of your choice, then follow the instructions below to create a geWorkbench plugin.&lt;br /&gt;
&lt;br /&gt;
The high-level steps for creating, testing and releasing a plugin are as follows:&lt;br /&gt;
&lt;br /&gt;
# Edit the provided Apache Ant build script to specify the name of your plugin.&lt;br /&gt;
# Add the .java source files for your plugin to the &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Add any .jar libraries that your plugin requires to the &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ant&amp;lt;/tt&amp;gt; to build your plugin.&lt;br /&gt;
# Edit the geWorkbench configuration file to add a directive for your new plugin.&lt;br /&gt;
# Run geWorkbench with &amp;lt;tt&amp;gt;ant run&amp;lt;/tt&amp;gt; to test your plugin.&lt;br /&gt;
# Once satisfied with your plugin, use the provided utility to package your plugin in to a single file for distribution.&lt;br /&gt;
&lt;br /&gt;
The next section will illustrate the above steps with an example.&lt;br /&gt;
&lt;br /&gt;
== An Example Plugin ==&lt;br /&gt;
&lt;br /&gt;
We will create an example plugin that is simply called &amp;lt;tt&amp;gt;test&amp;lt;/tt&amp;gt;. This will be a very simple visualization plugin that just displays a blank blue region.&lt;br /&gt;
&lt;br /&gt;
* In the provided &amp;lt;tt&amp;gt;build.xml&amp;lt;/tt&amp;gt;, this line can be found near the beginning of the file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;noname&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line is changed to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;test&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This specifies the name of our component, which is used for all build products.&lt;br /&gt;
* Next we will add a single .java source file in the org.organization.test package. The file &amp;lt;tt&amp;gt;TestComponent.java&amp;lt;/tt&amp;gt; goes in the &amp;lt;tt&amp;gt;src/org/organization/test&amp;lt;/tt&amp;gt; and has the following contents:&lt;br /&gt;
&lt;br /&gt;
 package org.organization.test;&lt;br /&gt;
 &lt;br /&gt;
 import org.geworkbench.engine.config.VisualPlugin;&lt;br /&gt;
  &lt;br /&gt;
 import javax.swing.*;&lt;br /&gt;
 import java.awt.*;&lt;br /&gt;
  &lt;br /&gt;
 /**&lt;br /&gt;
  * @author John Watkinson&lt;br /&gt;
  */&lt;br /&gt;
 public class TestComponent implements VisualPlugin {&lt;br /&gt;
  &lt;br /&gt;
     private JPanel panel;&lt;br /&gt;
  &lt;br /&gt;
     public TestComponent() {&lt;br /&gt;
         panel = new JPanel();&lt;br /&gt;
         panel.setBackground(Color.blue);&lt;br /&gt;
     }&lt;br /&gt;
  &lt;br /&gt;
     public Component getComponent() {&lt;br /&gt;
         return panel;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* The configuration file for the Developer Kit is called &amp;lt;tt&amp;gt;minimal.xml&amp;lt;/tt&amp;gt; and it is in the &amp;lt;tt&amp;gt;conf&amp;lt;/tt&amp;gt; directory. The following directive is added:&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;plugin id=&amp;quot;testPanel&amp;quot; name=&amp;quot;Test Panel&amp;quot; class=&amp;quot;org.organization.test.TestComponent&amp;quot; source=&amp;quot;test&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;gui-area name=&amp;quot;VisualArea&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/plugin&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The plugin will now appear when the application is run. It can be run with the command:&lt;br /&gt;
&lt;br /&gt;
 ant run&lt;br /&gt;
&lt;br /&gt;
* Satisfied with the plugin, it can now be released by running:&lt;br /&gt;
&lt;br /&gt;
 ant gear&lt;br /&gt;
&lt;br /&gt;
This creates the file &amp;lt;tt&amp;gt;test.gear&amp;lt;/tt&amp;gt;. A .gear file is the geWorkbench analogue of a .war file for a web application. Is a bundled  plugin that can deployed to a geWorkbench install by placing the file in the &amp;lt;tt&amp;gt;components&amp;lt;/tt&amp;gt; directory. A configuration directive (such as the one above) would also need to be added to the configuration file to activate the plugin.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1745</id>
		<title>Software Development Kit</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1745"/>
				<updated>2006-02-01T18:23:11Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Developer Kit is a self-contained package that facilitates the process of developing plugins for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Using the Developer Kit ==&lt;br /&gt;
&lt;br /&gt;
The Developer Kit is available as a .zip file. Unzip it in to a directory of your choice, then follow the instructions below to create a geWorkbench plugin.&lt;br /&gt;
&lt;br /&gt;
The high-level steps for creating, testing and releasing a plugin are as follows:&lt;br /&gt;
&lt;br /&gt;
# Edit the provided Apache Ant build script to specify the name of your plugin.&lt;br /&gt;
# Add the .java source files for your plugin to the &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Add any .jar libraries that your plugin requires to the &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ant&amp;lt;/tt&amp;gt; to build your plugin.&lt;br /&gt;
# Edit the geWorkbench configuration file to add a directive for your new plugin.&lt;br /&gt;
# Run geWorkbench with &amp;lt;tt&amp;gt;ant run&amp;lt;/tt&amp;gt; to test your plugin.&lt;br /&gt;
# Once satisfied with your plugin, use the provided utility to package your plugin in to a single file for distribution.&lt;br /&gt;
&lt;br /&gt;
The next section will illustrate the above steps with an example.&lt;br /&gt;
&lt;br /&gt;
== An Example Plugin ==&lt;br /&gt;
&lt;br /&gt;
We will create an example plugin that is simply called &amp;lt;tt&amp;gt;test&amp;lt;/tt&amp;gt;. This will be a very simple visualization plugin that just displays a blank blue region.&lt;br /&gt;
&lt;br /&gt;
* In the provided &amp;lt;tt&amp;gt;build.xml&amp;lt;/tt&amp;gt;, this line can be found near the beginning of the file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;noname&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line is changed to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;test&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This specifies the name of our component, which is used for all build products.&lt;br /&gt;
* Next we will add a single .java source file in the org.organization.test package. The file &amp;lt;tt&amp;gt;TestComponent.java&amp;lt;/tt&amp;gt; goes in the &amp;lt;tt&amp;gt;src/org/organization/test&amp;lt;/tt&amp;gt; and has the following contents:&lt;br /&gt;
&lt;br /&gt;
 package org.organization.test;&lt;br /&gt;
 &lt;br /&gt;
 import org.geworkbench.engine.config.VisualPlugin;&lt;br /&gt;
  &lt;br /&gt;
 import javax.swing.*;&lt;br /&gt;
 import java.awt.*;&lt;br /&gt;
  &lt;br /&gt;
 /**&lt;br /&gt;
  * @author John Watkinson&lt;br /&gt;
  */&lt;br /&gt;
 public class TestComponent implements VisualPlugin {&lt;br /&gt;
  &lt;br /&gt;
     private JPanel panel;&lt;br /&gt;
  &lt;br /&gt;
     public TestComponent() {&lt;br /&gt;
         panel = new JPanel();&lt;br /&gt;
         panel.setBackground(Color.blue);&lt;br /&gt;
     }&lt;br /&gt;
  &lt;br /&gt;
     public Component getComponent() {&lt;br /&gt;
         return panel;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* The configuration file for the Developer Kit is called &amp;lt;tt&amp;gt;minimal.xml&amp;lt;/tt&amp;gt; and it is in the &amp;lt;tt&amp;gt;conf&amp;lt;/tt&amp;gt; directory. The following directive is added:&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;plugin id=&amp;quot;testPanel&amp;quot; name=&amp;quot;Test Panel&amp;quot; class=&amp;quot;org.organization.test.TestComponent&amp;quot; source=&amp;quot;test&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;gui-area name=&amp;quot;VisualArea&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/plugin&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The plugin will now appear when the application is run. It can be run with the command:&lt;br /&gt;
&lt;br /&gt;
 ant run&lt;br /&gt;
&lt;br /&gt;
* Satisfied with the plugin, it can now be released by running the provided &amp;lt;tt&amp;gt;makeGear.bat&amp;lt;/tt&amp;gt; batch file with our component name as a parameter:&lt;br /&gt;
&lt;br /&gt;
 makeGear test&lt;br /&gt;
&lt;br /&gt;
This is just a shorcut to the following ant&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1744</id>
		<title>Software Development Kit</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1744"/>
				<updated>2006-02-01T18:17:38Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Developer Kit is a self-contained package that facilitates the process of developing plugins for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Using the Developer Kit ==&lt;br /&gt;
&lt;br /&gt;
The Developer Kit is available as a .zip file. Unzip it in to a directory of your choice, then follow the instructions below to create a geWorkbench plugin.&lt;br /&gt;
&lt;br /&gt;
The high-level steps for creating, testing and releasing a plugin are as follows:&lt;br /&gt;
&lt;br /&gt;
# Edit the provided Apache Ant build script to specify the name of your plugin.&lt;br /&gt;
# Add the .java source files for your plugin to the &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Add any .jar libraries that your plugin requires to the &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ant&amp;lt;/tt&amp;gt; to build your plugin.&lt;br /&gt;
# Edit the geWorkbench configuration file to add a directive for your new plugin.&lt;br /&gt;
# Run geWorkbench with &amp;lt;tt&amp;gt;ant run&amp;lt;/tt&amp;gt; to test your plugin.&lt;br /&gt;
# Once satisfied with your plugin, use the provided utility to package your plugin in to a single file for distribution.&lt;br /&gt;
&lt;br /&gt;
The next section will illustrate the above steps with an example.&lt;br /&gt;
&lt;br /&gt;
== An Example Plugin ==&lt;br /&gt;
&lt;br /&gt;
We will create an example plugin that is simply called &amp;lt;tt&amp;gt;test&amp;lt;/tt&amp;gt;. This will be a very simple visualization plugin that just displays a blank blue region.&lt;br /&gt;
&lt;br /&gt;
* In the provided &amp;lt;tt&amp;gt;build.xml&amp;lt;/tt&amp;gt;, this line can be found near the beginning of the file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;noname&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line is changed to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;test&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This specifies the name of our component, which is used for all build products.&lt;br /&gt;
* Next we will add a single .java source file in the org.organization.test package. The file &amp;lt;tt&amp;gt;TestComponent.java&amp;lt;/tt&amp;gt; goes in the &amp;lt;tt&amp;gt;src/org/organization/test&amp;lt;/tt&amp;gt; and has the following contents:&lt;br /&gt;
&lt;br /&gt;
 package org.organization.test;&lt;br /&gt;
 &lt;br /&gt;
 import org.geworkbench.engine.config.VisualPlugin;&lt;br /&gt;
  &lt;br /&gt;
 import javax.swing.*;&lt;br /&gt;
 import java.awt.*;&lt;br /&gt;
  &lt;br /&gt;
 /**&lt;br /&gt;
  * @author John Watkinson&lt;br /&gt;
  */&lt;br /&gt;
 public class TestComponent implements VisualPlugin {&lt;br /&gt;
  &lt;br /&gt;
     private JPanel panel;&lt;br /&gt;
  &lt;br /&gt;
     public TestComponent() {&lt;br /&gt;
         panel = new JPanel();&lt;br /&gt;
         panel.setBackground(Color.blue);&lt;br /&gt;
     }&lt;br /&gt;
  &lt;br /&gt;
     public Component getComponent() {&lt;br /&gt;
         return panel;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
*&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1743</id>
		<title>Software Development Kit</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1743"/>
				<updated>2006-02-01T18:16:12Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Developer Kit is a self-contained package that facilitates the process of developing plugins for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Using the Developer Kit ==&lt;br /&gt;
&lt;br /&gt;
The Developer Kit is available as a .zip file. Unzip it in to a directory of your choice, then follow the instructions below to create a geWorkbench plugin.&lt;br /&gt;
&lt;br /&gt;
The high-level steps for creating, testing and releasing a plugin are as follows:&lt;br /&gt;
&lt;br /&gt;
# Edit the provided Apache Ant build script to specify the name of your plugin.&lt;br /&gt;
# Add the .java source files for your plugin to the &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Add any .jar libraries that your plugin requires to the &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ant&amp;lt;/tt&amp;gt; to build your plugin.&lt;br /&gt;
# Edit the geWorkbench configuration file to add a directive for your new plugin.&lt;br /&gt;
# Run geWorkbench with &amp;lt;tt&amp;gt;ant run&amp;lt;/tt&amp;gt; to test your plugin.&lt;br /&gt;
# Once satisfied with your plugin, use the provided utility to package your plugin in to a single file for distribution.&lt;br /&gt;
&lt;br /&gt;
The next section will illustrate the above steps with an example.&lt;br /&gt;
&lt;br /&gt;
== An Example Plugin ==&lt;br /&gt;
&lt;br /&gt;
We will create an example plugin that is simply called &amp;lt;tt&amp;gt;test&amp;lt;/tt&amp;gt;. This will be a very simple visualization plugin that just displays a blank blue region.&lt;br /&gt;
&lt;br /&gt;
* In the provided build.xml file, we find this line:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;noname&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line is changed to:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;test&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This specifies the name of our component, which is used for all build products.&lt;br /&gt;
* Next we will add a single .java source file in the org.organization.test package. The file &amp;lt;tt&amp;gt;TestComponent.java&amp;lt;/tt&amp;gt; goes in the &amp;lt;tt&amp;gt;src/org/organization/test&amp;lt;/tt&amp;gt; and has the following contents:&lt;br /&gt;
&lt;br /&gt;
 package org.organization.test;&lt;br /&gt;
 &lt;br /&gt;
 import org.geworkbench.engine.config.VisualPlugin;&lt;br /&gt;
  &lt;br /&gt;
 import javax.swing.*;&lt;br /&gt;
 import java.awt.*;&lt;br /&gt;
  &lt;br /&gt;
 /**&lt;br /&gt;
  * @author John Watkinson&lt;br /&gt;
  */&lt;br /&gt;
 public class TestComponent implements VisualPlugin {&lt;br /&gt;
  &lt;br /&gt;
     private JPanel panel;&lt;br /&gt;
  &lt;br /&gt;
     public TestComponent() {&lt;br /&gt;
         panel = new JPanel();&lt;br /&gt;
         panel.setBackground(Color.blue);&lt;br /&gt;
     }&lt;br /&gt;
  &lt;br /&gt;
     public Component getComponent() {&lt;br /&gt;
         return panel;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
*&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1742</id>
		<title>Software Development Kit</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1742"/>
				<updated>2006-02-01T18:12:33Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Developer Kit is a self-contained package that facilitates the process of developing plugins for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Using the Developer Kit ==&lt;br /&gt;
&lt;br /&gt;
The Developer Kit is available as a .zip file. Unzip it in to a directory of your choice, then follow the instructions below to create a geWorkbench plugin.&lt;br /&gt;
&lt;br /&gt;
The high-level steps for creating, testing and releasing a plugin are as follows:&lt;br /&gt;
&lt;br /&gt;
# Edit the provided Apache Ant build script to specify the name of your plugin.&lt;br /&gt;
# Add the .java source files for your plugin to the &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Add any .jar libraries that your plugin requires to the &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ant&amp;lt;/tt&amp;gt; to build your plugin.&lt;br /&gt;
# Edit the geWorkbench configuration file to add a directive for your new plugin.&lt;br /&gt;
# Run geWorkbench with &amp;lt;tt&amp;gt;ant run&amp;lt;/tt&amp;gt; to test your plugin.&lt;br /&gt;
# Once satisfied with your plugin, use the provided utility to package your plugin in to a single file for distribution.&lt;br /&gt;
&lt;br /&gt;
The next section will illustrate the above steps with an example.&lt;br /&gt;
&lt;br /&gt;
== An Example Plugin ==&lt;br /&gt;
&lt;br /&gt;
We will create an example plugin that is simply called &amp;lt;tt&amp;gt;test&amp;lt;/tt&amp;gt;. This will be a very simple visualization plugin that just displays a blank blue region.&lt;br /&gt;
&lt;br /&gt;
# In the provided build.xml file, we find this line:&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;noname&amp;quot;/&amp;gt;&lt;br /&gt;
The line is changed to:&lt;br /&gt;
 &amp;lt;property name=&amp;quot;component&amp;quot; value=&amp;quot;test&amp;quot;/&amp;gt;&lt;br /&gt;
This specifies the name of our component, which is used for all build products.&lt;br /&gt;
# Next&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1741</id>
		<title>Software Development Kit</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1741"/>
				<updated>2006-02-01T18:08:34Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Using the Developer Kit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Developer Kit is a self-contained package that facilitates the process of developing plugins for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Using the Developer Kit ==&lt;br /&gt;
&lt;br /&gt;
The Developer Kit is available as a .zip file. Unzip it in to a directory of your choice, then follow the instructions below to create a geWorkbench plugin.&lt;br /&gt;
&lt;br /&gt;
The high-level steps for creating, testing and releasing a plugin are as follows:&lt;br /&gt;
&lt;br /&gt;
# Edit the provided Apache Ant build script to specify the name of your plugin.&lt;br /&gt;
# Add the .java source files for your plugin to the &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Add any .jar libraries that your plugin requires to the &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ant&amp;lt;/tt&amp;gt; to build your plugin.&lt;br /&gt;
# Edit the geWorkbench configuration file to add a directive for your new plugin.&lt;br /&gt;
# Run geWorkbench with &amp;lt;tt&amp;gt;ant run&amp;lt;/tt&amp;gt; to test your plugin.&lt;br /&gt;
# Once satisfied with your plugin, use the provided utility to package your plugin in to a single file for distribution.&lt;br /&gt;
&lt;br /&gt;
The next section will illustrate the above steps with an example.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1740</id>
		<title>Software Development Kit</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1740"/>
				<updated>2006-02-01T18:06:46Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Developer Kit is a self-contained package that facilitates the process of developing plugins for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Using the Developer Kit ==&lt;br /&gt;
&lt;br /&gt;
The Developer Kit is available as a .zip file. Unzip it in to a directory of your choice, then follow the instructions below to create a geWorkbench plugin.&lt;br /&gt;
&lt;br /&gt;
The high-level steps for creating, testing and releasing a plugin are as follows:&lt;br /&gt;
&lt;br /&gt;
# Edit the provided Apache Ant build script to specify the name of your plugin.&lt;br /&gt;
# Add the .java source files for your plugin to the &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Add any .jar libraries that your plugin requires to the &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; directory.&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ant&amp;lt;/tt&amp;gt; to build your plugin.&lt;br /&gt;
# Edit the geWorkbench configuration file to add a directive for your new plugin.&lt;br /&gt;
# Run geWorkbench with &amp;lt;tt&amp;gt;ant run&amp;lt;/tt&amp;gt; to test your plugin.&lt;br /&gt;
# Once satisfied with your plugin, use the provided utility to package your plugin in to a single file for distribution.&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1739</id>
		<title>Software Development Kit</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Software_Development_Kit&amp;diff=1739"/>
				<updated>2006-02-01T18:03:01Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Developer Kit is a self-contained package that facilitates the process of developing plugins for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
== Using the Developer Kit ==&lt;br /&gt;
&lt;br /&gt;
The Developer Kit is available as a .zip file. Unzip it in to a directory of your choice, then follow the instructions below to create a geWorkbench plugin.&lt;br /&gt;
&lt;br /&gt;
The high-level steps for creating, testing and releasing a plugin are as follows:&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=.GEAR_files&amp;diff=1723</id>
		<title>.GEAR files</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=.GEAR_files&amp;diff=1723"/>
				<updated>2006-01-31T17:31:11Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
.GEAR files are essentially zipped versions of geWorkBench visual plugins. They make it easy to distribute reasonably sized upgrades to specific parts of the application. They are the geWorkbench analogue of .WAR files for web applications.&lt;br /&gt;
&lt;br /&gt;
== Creating a .GEAR file ==&lt;br /&gt;
&lt;br /&gt;
There is an ant task that will create a .GEAR file automatically. Run ant with “ant –Dcomponent=NAME” which will create a .gear file from the specified component directory. You can also run the Windows batch file “makeGear NAME” instead. Put the resulting .gear file in the components directory of a geWorkbench installation and it will be loaded by the application.&lt;br /&gt;
&lt;br /&gt;
== Viewing loaded versions of components ==&lt;br /&gt;
&lt;br /&gt;
The version menu item, under help will list all the loaded versions of plugins, and will indicate which ones are loading from .GEAR files, an example is below.&lt;br /&gt;
&lt;br /&gt;
[[Image:VersionDialog.png||Example version screen.]]&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=.GEAR_files&amp;diff=1722</id>
		<title>.GEAR files</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=.GEAR_files&amp;diff=1722"/>
				<updated>2006-01-31T17:11:38Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: /* Creating a .GEAR file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
.GEAR files are essentially zipped versions of geWorkBench visual plugins. They make it easy to distribute reasonably sized upgrades to specific parts of the application.&lt;br /&gt;
&lt;br /&gt;
== Creating a .GEAR file ==&lt;br /&gt;
&lt;br /&gt;
There is an ant task that will create a .GEAR file automatically. Run ant with “ant –Dcomponent=NAME” which will create a .gear file from the specified component directory. You can also run the Windows batch file “makeGear NAME” instead. Put the resulting .gear file in the components directory of a geWorkbench installation and it will be loaded by the application.&lt;br /&gt;
&lt;br /&gt;
== Viewing loaded versions of components ==&lt;br /&gt;
&lt;br /&gt;
The version menu item, under help will list all the loaded versions of plugins, and will indicate which ones are loading from .GEAR files, an example is below.&lt;br /&gt;
&lt;br /&gt;
[[Image:VersionDialog.png||Example version screen.]]&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Developers&amp;diff=1721</id>
		<title>Developers</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Developers&amp;diff=1721"/>
				<updated>2006-01-31T17:09:15Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Introduction_For_Developers|Introduction For Developers]]&lt;br /&gt;
* [[Building geWorkbench]]&lt;br /&gt;
* Coding Standards [[Style Guide]]&lt;br /&gt;
* [http://caldev/workbench/api Javadocs]&lt;br /&gt;
* [[CVS Repository]]&lt;br /&gt;
* [[Screenshots]]&lt;br /&gt;
* Information on [[.GEAR files]], a method of distributing plugins.&lt;br /&gt;
* [[Plugin certification checklist]]&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugins&amp;diff=1611</id>
		<title>Plugins</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugins&amp;diff=1611"/>
				<updated>2006-01-25T21:18:33Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Plugins are sets of pluggable components for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
Below is the list of available plugins.&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;border: 1px solid lightGray&amp;quot;&lt;br /&gt;
!Plugin||Description||Compatibility&lt;br /&gt;
|-&lt;br /&gt;
|Color Mosaic||Displays heat maps for microarray expression data, organized by phenotypic or gene groupings.||Verified to work on 3.0&lt;br /&gt;
|-&lt;br /&gt;
|Clustering||Contains analysis components to perform hierarchical clustering self-organizing maps clustering on microarray expression data.||Verified to work on 3.0&lt;br /&gt;
|-&lt;br /&gt;
|caScript||A scripting language engine for geWorkbench.||Not yet verified.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugins&amp;diff=1610</id>
		<title>Plugins</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugins&amp;diff=1610"/>
				<updated>2006-01-25T21:18:25Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Plugins are sets of pluggable components for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
Below is the list of available plugins.&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;border: 1px solid lightGray&amp;quot;&lt;br /&gt;
!Plugin||Description||Compatibility||Download&lt;br /&gt;
|-&lt;br /&gt;
|Color Mosaic||Displays heat maps for microarray expression data, organized by phenotypic or gene groupings.||Verified to work on 3.0&lt;br /&gt;
|-&lt;br /&gt;
|Clustering||Contains analysis components to perform hierarchical clustering self-organizing maps clustering on microarray expression data.||Verified to work on 3.0&lt;br /&gt;
|-&lt;br /&gt;
|caScript||A scripting language engine for geWorkbench.||Not yet verified.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugins&amp;diff=1609</id>
		<title>Plugins</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=Plugins&amp;diff=1609"/>
				<updated>2006-01-25T21:01:42Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Plugins are sets of pluggable components for geWorkbench.&lt;br /&gt;
&lt;br /&gt;
Below is the list of available plugins.&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;border: 1px solid lightGray&amp;quot;&lt;br /&gt;
!Plugin||Description||Compatibility||Download&lt;br /&gt;
|-&lt;br /&gt;
|Color Mosaic||Displays heat maps for microarray expression data, organized by phenotypic or gene groupings.||Verified to work on 3.0||[[Media:colormosaic-3.0.gear|Download]]&lt;br /&gt;
|-&lt;br /&gt;
|Clustering||Contains analysis components to perform hierarchical clustering self-organizing maps clustering on microarray expression data.||Verified to work on 3.0||[[Media:clustering-3.0.gear|Download]]&lt;br /&gt;
|-&lt;br /&gt;
|caScript||A scripting language engine for geWorkbench.||Not yet verified.||[[Media:Cascript-3.0.gear|Download]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	<entry>
		<id>http://wiki.c2b2.columbia.edu/workbench/index.php?title=File:Colormosaic-3.0.gear&amp;diff=1608</id>
		<title>File:Colormosaic-3.0.gear</title>
		<link rel="alternate" type="text/html" href="http://wiki.c2b2.columbia.edu/workbench/index.php?title=File:Colormosaic-3.0.gear&amp;diff=1608"/>
				<updated>2006-01-25T21:01:03Z</updated>
		
		<summary type="html">&lt;p&gt;Watkinson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Watkinson</name></author>	</entry>

	</feed>