How Can We Keep HyperEdge Structures Up-To-Date?

The Problem

Using Event callbacks to monitor the hidding of GraphObjects can lead to IllegalStateExceptions. We can cause IllegalStateExceptions in !FGraphPerspective by indirectly fully hiding objects we are in the middle of hiding.

For example, assume we have a HyperEdge with ConnectorNode cn1. This HyperEdge has edge e1 to node P and edge e2 to node M (see diagram). Notice that if we hide any edge, the HyperEdge will be hidden causing e1-e2, and cn1 to be hidden.

M


o


>P

Now assume a user selects e1 and does 'Edit->Delete Selected Nodes and Edges'. The call chain looks something like:

... cytoscape.editor.actions.DeleteAction.actionPerformed()

The current HyperEdgeManager event callback will take the edge (e1) and carefully remove HyperEdge bookkeeping information about this edge--without deleting it. However, removing e1 from the HyperEdge implies that the whole HyperEdge must be removed. So, e2 and cn1 are hidden. When cn1 is really hidden by !FGraphPerspective, it will first hide its edges, namely e1 will be fully hidden. However, notice that we are in the process of hiding e1--we are in the event call back for it being hidden. So, after our event callback completes, !FGraphPerspective.actuallyHideEdge() will get an IllegalStateException since e2 is been hidden out from underneath it (for all the gory details, see Details of Simple Example, below).

Rehiding versus Recursively Hiding

Notice that rehiding and recursively hiding a GraphObject are different issues. Rehiding a CyNode or CyEdge is attempting to hide it again after fully hiding it already. Fing is fairly robust here, since it already has to deal with these situations (see Rehiding CyNodes and CyEdges in Fing, below). However, where Fing is inflexible is in recursively hiding a GraphObject.

How to Solve This Problem

Before looking at temporary solutions, notice that this problem goes away if (when) HyperEdge is placed in Cytoscape core. At this time, then event callbacks will no longer be needed to track deletions but instead the real HyperEdge API deletion methods would be invoked directly.

To temporarily solve this problem, we need to follow the rule:

1. Save what must be hidden during hide event callback to

1. Delayed CyNode Deletion

Other Strategies Considered

A. Just catch IllegalStateException checking that error is the

A. When a hiding callback starts, track all items given in the list of

Rehiding !CyNodes and !CyEdges in Fing

!FGraphPerspective.hideEdges() must already be somewhat flexible to handle simple hidings. For example, the code for Edit-->"Delete Selected Nodes and Edges", in cytoscape.editor.actions.DeleteAction.actionPerformed(), performs the following steps:

If we select a CyNode and its CyEdges and hide them, then by the time cyNet.hideEdges() is called, 'edges' will be hidden.

More Complex Example

Assume we have two HyperEdges he1 and he2 with ConnectorNodes cn1 and cn2 respectively. he1 has edge e2 to cn2 and edge e1 to node A. he2 has edge e2 to cn1 and edge e3 to B (see diagram). Notice that if we hide any edge or any node, both hyperedges will be deleted causing e1-e3, cn1, and cn2 to be hidden.

A


>o

B


>o

Now assume a user selects e1,e2,e3 and does 'Edit->Delete Selected Nodes and Edges'. The call chain looks something like:

... cytoscape.editor.actions.DeleteAction.actionPerformed()

Details of Simple Example

cytoscape.editor.actions.DeleteAction.actionPerformed()

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