Differences between revisions 22 and 24 (spanning 2 versions)
Revision 22 as of 2007-10-09 20:59:17
Size: 18702
Editor: malbec
Comment:
Revision 24 as of 2007-10-09 21:49:31
Size: 13369
Editor: malbec
Comment:
Deletions are marked like this. Additions are marked like this.
Line 151: Line 151:
=== Scripting === == Algorithms ==

Algorithms can implement additional interfaces, e.g. ProgressTrackable, which would mean a progress monitor could be added.

[http://cishell.org CIShell] does all of this now.

=== Workflow ===

'''JMenu Context'''
 * Menu is created with menu items that are connected to GUI services. The GUI services are associated with Algorithms via thier metadata (i.e. the ''algorithm.service.pid'').
 * The menu item does not actually ''load'' the GUI service, it merely keeps a reference to it. The GUI service is only actually retrieved when the menu item is clicked.

 1. Click Top-level menu
 1. Check algorithm meta data to see if menu item should be enabled. For example, if a "requiresNetwork=true" attribute is found, then the menu item should only be enabled if a network has actually been loaded into cytoscape.
 1. Click menu item.
 1. Menu item creates a GUIController object that connects the Algorithm and the GUI.
 1. The GUI queries the GUIController to get the Algorithm Tunables.
 1. The GUI returns a JPanel that is inserted (by Cytoscape) into a Tab or Dialog depending on the GUI metadata.
 1. User does stuff to the GUI setting the various Tunables.
 1. Some user interaction (i.e. click OK) indicates that the algorithm should be run.
 1. The GUI service calls GUIController.trigger(List<Tunables>) where the list of tunables are those needed to run the algorithm.
 1. GUIController, at its leisure, calls AlgorithmFactory.createAlgorithm(List<Tunable>) which instantiates an Algorithm with the proper parameters.
 1. The algorithm is executed via the execute() method.
 1. GUI Service calls GUIController.close() when it is finished.

'''''WARNING''''' This scheme currently does not support the case where the Algorithm interacts with the GUI, i.e. returns a result to the GUI.

== Scripting ==
Line 156: Line 183:

=== UI Services ===
Interactive - provide an option to bring up before or after action has run
Action to create panel
Action to be triggered by the panel

 * Control Tab
 * Results Tab
 * Dialog
 
{{{

// the service interface
interface UIPanel {
  JPanel getJPanel();
}

// in the plugin
// meta data defining where/how to use the panel
Hashtable dict = new HashTable();
dict.put("panel.location","control");
dict.put("panel.name","hello world");
dict.put("service.pid","myuipanel.persistent.id");

bundleContext.registerService(UIPanel.class.getName(), new MyUIPanel(), dict);
 }}}

Single Action
 * Menu Item
 * Button On Toolbar

{{{
// The factory is the service. The factory will return individual action objects
// that can store internal state. If we didn't have a factory, then the individual
// actions wouldn't be able to store their state because they'd persist as services.
interface CytoscapeActionFactory {
  CytoscapeAction createAction(context of some sort);
  List<Tunable> createParameters(possibly some context);
 boolean isEnabled(context of some sort);
}

interface CytoscapeAction {
   void run();
}

// meta data defining where/how to use the action
Hashtable dict = new HashTable();
dict.put("preferred.menu","whereever/submenu");
dict.put("action.panel","myuipanel.persistent.id"); // so that it can get the exact panel
dict.put("menu.label","asdfasdf");
dict.put("icon", new Icon("my.png"));

bundleContext.registerService(CytoscapeActionFactory.class.getName(), new MyCyActionFactory(), dict);
}}}

=== Menus ===

Menu Action flow of events
 1. MenuItem is created.
 1. Click on a menu
 1. The menuSelected() method checks the CytoscapeActionFactory metadata to see if the menu item should be enabled/disabled. The Action could just declare what attributes need to exist in the world in the metadata of the CytoscapeActionFactory. For example, you could define metadata like requiresNetwork, requiresNetworkView, requiresNodeSelection, requiresEdgeSelection, etc.. There could also a overriding metadatum called isEnabled that could be forced to be true if necessary.
 1. The menu would be displayed if the action is enabled.
 1. The menu looks for a registered service for CytoscapeActionFactory. The individual factory returned is determined based on a parameter to the MenuItem. This happens dynamically based on how the CytoscapeActionFactories are defined.
 1. First call createParameters() that creates some sort of UI (e.g. a GUI that allows input values or a command line that reads a config file or queries a database or reads a command line, etc.). This data is specified by the user and is then passed into the action that is created next.
 1. The factory.createAction() method is called with all of the appropriate params (e.g. currentNetwork, currentNetworkView, etc.).
 1. The CytoscapeAction object can now be run at your leisure.


CytoscapeAction can implement additional interfaces, e.g. ProgressTrackable, which would mean a progress monitor could be added.

A CytoscapeAction needs it's basic inputs (current network, current view, or possibly a DataManager), but it also may need separate parameters. These should be defined as some sort of Tunable or List<Tunable> or a JPanel that returns some sort of configuration object, e.g. a Dictionary of key -> value pairs.

The action context could be a DataManager interface that provides methods like getCurrentNetwork, getCurrentNetworkView, etc.. Alternatively, you could provide an Context object (e.g. CIShellContext) which could provide access to all Cytoscape services. This isn't an osgi context that worries about
bundles, but is an application specific context that provides services appropriate for how the application is currently being run.



=== the Solution ===

[http://cishell.org CIShell] does all of this now.


 
=== Action Services ===
 An action gets current context (network, view, etc.). Then the action does "something". '''The action should be independent of the UI.''' Make the actions chainable.


 
== Breakdown of Cytoscape Services ==
Currently supported by Cytoscape.java.

 * handled by OSGi
    * void exit(int returnVal) {
 * gui specific
    * CytoscapeDesktop getDesktop() {
    * VisualMappingManager getVisualMappingManager() {
 *network service
    * Set getNetworkSet() {
    * CyNetwork getNetwork(String id) {
    * CyNetwork getNullNetwork() {
    * CyNetwork getCurrentNetwork() {
    * void setCurrentNetwork(String id) {
    * void destroyNetwork(CyNetwork network) {
    * CyNetwork createNetwork(String title, ...) {
  * '''encapsulate in CyNetwork:'''
           * List getCyNodesList() {
           * List getCyEdgesList() {
           * CyNode getCyNode(String alias)
           * CyEdge getCyEdge(Node node_1, Node node_2, ...)
 * network view service
    * Map getNetworkViewMap() {
    * CyNetworkView getNetworkView(String network_id) {
    * CyNetworkView getNullNetworkView() {
    * boolean viewExists(String network_id) {
    * CyNetworkView getCurrentNetworkView() {
    * boolean setCurrentNetworkView(String id) {
    * CyNetworkView createNetworkView(CyNetwork network, ...) {
    * void destroyNetworkView(CyNetworkView view, ...) {
 * session service
    * String getCurrentSessionFileName() {
    * void setCurrentSessionFileName(String newName) {
    * void setSessionState(int state) {
    * int getSessionstate() {
    * void createNewSession() {
 * attribute service
    * CyAttributes getNodeAttributes() {
    * CyAttributes getEdgeAttributes() {
    * CyAttributes getNetworkAttributes() {
    * void loadAttributes(String[] nodeAttrLocations, String[] edgeAttrLocations) {
 * import service
    * No need to exist. Imports are handled automatically by getting service references to all CyNetworkFileFilters.
 * event handling service
    * SwingPropertyChangeSupport getSwingPropertyChangeSupport() {
    * PropertyChangeSupport getPropertyChangeSupport() {
    * void firePropertyChange(String property_type, Object old_value, Object new_value) {
 * expression data service
    * ExpressionData getExpressionData() {
    * void setExpressionData(ExpressionData expData) {
    * boolean loadExpressionData(String filename, boolean copy_atts) {
 * ontology service
    * OntologyServer buildOntologyServer() {
    * OntologyServer getOntologyServer() {
    * String getOntologyRootID() {
    * void setOntologyRootID(String id) {
    * CyAttributes getOntologyAttributes() {
 * bookmark service
    * Bookmarks getBookmarks() throws JAXBException, IOException {
    * void setBookmarks(Bookmarks pBookmarks) {
'''NOT''' Currently provided by Cytoscape.java
 * Export service
    * No need to exist. Imports are handled automatically by getting service references to all export filters.

"Services" currently existing elsewhere that would be transformed into OSGi services.
 * Proxy handling service
 * Layout service
 * Web Service Service
 * Groups - Perhaps this should be integrated with CyNetwork and CyNetworkView. CyGroup should be in/related to CyNetwork (CyNode?) and CyGroupView should in/related to CyNetworkView (CyNodeView?).

=== Visual Styles ===
== Visual Styles Refactoring ==
Line 318: Line 187:
Line 329: Line 197:
== UI Services ==

The Cytoscape GUI will look for GUI services. Each GUI service will have (among other things) two key pieces of information in its metadata. The first will be a ''location'' where the GUI Services JPanel can be placed. Some possible locations are:
 * Control Tab
 * Results Tab
 * Data Tab
 * Dialog
The second piece of metadata will be an ''action style'' which indicates whether the GUI Service will be instantiated from a menu item or a toolbar button. Some possible action styles are:
 * menu item
 * toolbar button
The GUI service should also be able to use the Algorithm metadata to further define its functionality.

=== Possible GUI Service MetaData ===
 * preferred.menu
 * preferred.location
 * preferred.action.style
 * label
 * description
 * service.pid
 * hot.keys
 * preferred.icon

=== Possible Algorithm MetaData ===
 * requires.network
 * requires.network.view
 * requires.selected.nodes
 * requires.selected.edges
Line 330: Line 226:
 * SHOULD be gui independent  * '''SHOULD be gui independent'''
Line 365: Line 261:
 * pops up dialog  * '''pops up dialog'''
Line 375: Line 271:
 * gui specific view manipulation  * '''gui specific view manipulation'''
Line 396: Line 292:
 * gui specific state  * '''gui specific state'''
Line 400: Line 296:

== Algorithm Workflow ==

 1. Click Top-level menu
 1. Check algorithm meta data to see if menu item should be enabled.
 1. Click menu item.
 1. MenuManager checks Algorithm meta data to UI service id.
 1. MenuManager associates a GUI instance with an Algorithm through Algorithm meta data.
 1. MenuManager creates a GUIController object that knows about the Algorithm and the GUI.
 1. MenuManager creates GUI based on the UI service id. MenuManager creates the GUI with a GUIController object.
 1. GUI intializes itself from UI.getFallBackInterface().
 1. User does stuff to the GUI setting the various Tunables.
 1. User clicks submit().
 1. GUI calls GUIController.execute(List<Tunables>).
 1. GUIController.close() gets called some point to close the GUI.
 1. GUIController gets all associated algorithms with GUI and calls AlgorithmFactory.createAlgorithm(List<Tunable>).execute().

Cytoscape PUBLIC API

The core network and network view interfaces. We should consider rolling groups into network/view.

The core attribute interface.

Interfaces for writing various types to data. Session writing will not be provided as a service since on the internal core will ever write a session.

Interfaces for reading various types of data along with file filters that can be used to define how files get read.

The interfaces used for defining general actions in Cytoscape. Algorithms are strictly separated from any sort of UI.

The interfaces defining the user interface. Tunable objects are the primary mechanism for communicating data between Algorithms and the UI. If an Algorithm wants to be present in the UI, then it must provide its own SwingFactory. Eventually we'll have interfaces for things like CommandLineFactory (we could perhaps infer this automatically) or AJAXFactory.

  • org.cytoscape.ui.TunableType

  • org.cytoscape.ui.Tunable
  • org.cytoscape.ui.Constraint
  • org.cytoscape.ui.UIController
  • org.cytoscape.ui.SwingFactory

The interface for defining a web service client.

The (substantially simplified) interfaces for defining visual styles.

The service interfaces for Cytoscape. These interfaces represent much of the functionality that is currently included in Cytoscape.java as static methods. These services will be implemented by cytoscape.

Plugin Implemented Services

The general mechanism for plugins to provide services to the rest of Cytoscape is to implement a public Cytoscape interface and register that object as a service with OSGi's service registry. The primary example of this is the Algorithm/AlgorithmFactory interface. Another example is the CyNetworkFileFilter.

Here is some example plugin code that would provide an SBML reader:

package sbmlreader;

import org.cytoscape.io.import.CyNetworkFileFilter;

import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;

import java.util.Hashtable;

public class SBMLReaderPlugin implements BundleActivator {

        private ServiceRegistration filterReg;

        public void start(BundleContext bc) {
                // defin the service metadata
                Hashtable metadata = new Hashtable();
                metadata.put("file.extensions",".sbml,.xml");
                metadata.put("description","SBML files");
                metadata.put("service.pid",SBMLFilter.class.getName());

                //                                               just an interface, implementation of interface, metadata
                filterReg = bc.registerService(CyNetworkFileFilter.class.getName(), new SBMLFilter(), metadata);
        }

        public void stop(BundleContext bc) {
                filterReg.unregister();
        }
}

Here is code that would exist in the Cytoscape core, consume services that have been registered as implementing CyNetworkFileFilter. Since SBMLReaderPlugin has done this, it will be found and used within the core normally.

package cytoscape;

import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.cytoscape.io.import.CyNetworkFileFilter;

public class ServiceHandler {

    private BundleContext bc;

    // perhaps called at startup or some other time
    public ServiceHandler(BundleContext bc) {
        this.bc = bc;
        registerCyFileFilters();
    }

    public void registerCyFileFilters() {
        try {
           ServiceReference[] sr = bc.getServiceReferences(CyNetworkFileFilter.class.getName(), null);
           for (ServiceReference r : sr ) {
               CyNetworkFileFilter filter = (CyNetworkFileFilter)bc.getService(r));
               // do something with filter
           }
        } catch (Exception e) { e.printStackTrace(); }
    }

CORE Bundle Organization

  • Each service described above will consist of a small number of interfaces. All service interfaces will be part of a single framework bundle.
  • Each service implementation will (probably) have a separate bundle. This isn't necessary, but some organization is a good idea.
  • There will be an initialization bundle that will handle starting and stopping all of the core services defined in the framework.
  • The GUI will consist of separate bundles.
  • Each service will (for the most part) have an associated GUI bundle.

Plugin Bundle Organization

  • Most plugins will provide a single bundle that includes an Algorithm (model) component and a GUI (view) component.
  • For large/complicated plugins, it is recommend that these be in separate bundles.
  • Multiple algorithms can be included in the same bundle.
  • Plugins can provide libraries as separate bundles.
  • We will need to have bundles of bundles (i.e. themes in cytoscape or features in Eclipse) to that users can request a single feature and not be concerned with loading all necessary bundles.

Algorithms

Algorithms can implement additional interfaces, e.g. ProgressTrackable, which would mean a progress monitor could be added.

[http://cishell.org CIShell] does all of this now.

Workflow

JMenu Context

  • Menu is created with menu items that are connected to GUI services. The GUI services are associated with Algorithms via thier metadata (i.e. the algorithm.service.pid).

  • The menu item does not actually load the GUI service, it merely keeps a reference to it. The GUI service is only actually retrieved when the menu item is clicked.

  • Click Top-level menu
  • Check algorithm meta data to see if menu item should be enabled. For example, if a "requiresNetwork=true" attribute is found, then the menu item should only be enabled if a network has actually been loaded into cytoscape.
  • Click menu item.
  • Menu item creates a GUIController object that connects the Algorithm and the GUI.
  • The GUI queries the GUIController to get the Algorithm Tunables.
  • The GUI returns a JPanel that is inserted (by Cytoscape) into a Tab or Dialog depending on the GUI metadata.
  • User does stuff to the GUI setting the various Tunables.
  • Some user interaction (i.e. click OK) indicates that the algorithm should be run.
  • The GUI service calls GUIController.trigger(List<Tunables>) where the list of tunables are those needed to run the algorithm.

  • GUIController, at its leisure, calls AlgorithmFactory.createAlgorithm(List<Tunable>) which instantiates an Algorithm with the proper parameters.

  • The algorithm is executed via the execute() method.
  • GUI Service calls GUIController.close() when it is finished.

WARNING This scheme currently does not support the case where the Algorithm interacts with the GUI, i.e. returns a result to the GUI.

Scripting

This Algorithm model is separated from the GUI so that it can be easily used in a scripting context (i.e headless mode).

Visual Styles Refactoring

A VisualStyle consists of a NodeAppearanceCalculator, EdgeAppearanceCalculator, and GlobalAppearanceCalculator.

NodeAppearanceCalculators and EdgeAppearanceCalculators consist of lists of Calculator objects. Each calculator has a specific VisualPropertyType. Only one Calculator of a given VisualPropertyType is allowed in either NodeAppearanceCalculators or EdgeAppearanceCalculators.

Possible Improvements for VisualStyles

UI Services

The Cytoscape GUI will look for GUI services. Each GUI service will have (among other things) two key pieces of information in its metadata. The first will be a location where the GUI Services JPanel can be placed. Some possible locations are:

  • Control Tab
  • Results Tab
  • Data Tab
  • Dialog

The second piece of metadata will be an action style which indicates whether the GUI Service will be instantiated from a menu item or a toolbar button. Some possible action styles are:

  • menu item
  • toolbar button

The GUI service should also be able to use the Algorithm metadata to further define its functionality.

Possible GUI Service MetaData

  • preferred.menu
  • preferred.location
  • preferred.action.style
  • label
  • description
  • service.pid
  • hot.keys
  • preferred.icon

Possible Algorithm MetaData

  • requires.network
  • requires.network.view
  • requires.selected.nodes
  • requires.selected.edges

Current Cytoscape Actions

OSGI_Refactoring_Possibilities (last edited 2009-02-12 01:03:49 by localhost)

Funding for Cytoscape is provided by a federal grant from the U.S. National Institute of General Medical Sciences (NIGMS) of the Na tional Institutes of Health (NIH) under award number GM070743-01. Corporate funding is provided through a contract from Unilever PLC.

MoinMoin Appliance - Powered by TurnKey Linux