Contains all JBoogie classes that are useful for third-party plugins.

Package Specification

Target and TargetListener are about finding and setting the selection. Command, MacroCommand and CommandDiFactory are about modifying the model in an undo-safe way. The Actions are parent classes of anything that you would like to insert in a menu, a toolbar, or a context menu.

About targets

Plugins using JBoogie may want to react to selection events that the user or another part of the program initiated. Let's say your plugin wants to set special tagged values (TVs) to Interfaces, and you want to do it via a GUI. It is not a good idea to have the user type in the name and value for a tagged value as it is clumsy, error-prone, and the user has to know the name of the TV. So you need a panel somewhere that shows the current values of the currently selected element, and whenever a setting in your panel is changed, the value should be stored with the same element.

What is a target?

We call the currently selected element the Target. A target has three parts: element, fig, and diagram.

Remember that there is a difference between a model element and its graphical representation. A Class, for example, may be in the project only once, but it shows up in several diagrams where it is displayed in different contexts. So there is a 1-to-n relation between elements and graphical representations.

An element is the UML element. It exists once in the whole project. A DI element, short for 'Diagram Interchange element', is a graphical representation of the UML element. It is of the type GraphElement in the Diagram Interchange. There may be none, one, or several Di elements for one model element. And a diagram is the third part of the target. Whenever the user selects anything with the mouse, it can be represented as a triple of model element, DI element, and diagram, some of which may be null.

Example: If the user selects a class in the tree, and a diagram is visible where the class can also be found, the resulting target will hold the chosen model element, and the corresponding DI element, and no diagram. Visually, the model element will be selected in the tree, and the DI element will have the yellow handles at the corners, and possibly rapid buttons.
If the user selects an element in the tree for which there is no DI element in the visible diagram, the target will hold the model element and nothing else.
If the user clicks on an empty area in a diagram, or selects a diagram in the tree, the target will hold the diagram and nothing else.

Implementing a TargetListener

Typically, your plugin's panel will be a tab in the Details Pane and be visible as another tab in the area below the diagrams. Add your component via PoseidonUIConnector.addDetailsTab(String name, Component tab).

To actually get hold of the current target, your component will have to register with the PoseidonUIConnector as com.gentleware.poseidon.jboogie.TargetListener. Implement the single method void handleTargetChanged(Target oldTarget, Target newTarget). Call PoseidonUIConnector.addTargetListener(myClass) in the installation part of your plugin, and that is it. Please do not forget to call PoseidonUIConnectorTargetManager.removeTargetListener(myClass) in your plugin's uninstall routine.

Processing the Target

In handleTargetChanged, you can inspect the Target object that is given. Each Target class has the methods

public org.omg.uml.diagraminterchange.Diagram getDiagram()
public Collection getDiagrams()
public org.omg.uml.foundation.core.ModelElement getElement()
public Collection getElements()
public org.omg.uml.diagraminterchange.GraphElement getDiElement()
public Collection[GraphElement] getDiElements()

Now, test the element in the target if it is not null and an instance of the desired class. Then, display the element's values in your component. Whenever necessary, set the element's values in the event handlers of your UI elements. And remember that the target may contain several elements due to multi-selection!

Example

import com.gentleware.poseidon.openapi.PoseidonUIConnector;
import com.gentleware.openapi.jboogie.Target;
import com.gentleware.jboogie.openapi.TargetListener;
import org.omg.uml.diagraminterchange.Diagram;
import org.omg.uml.diagraminterchange.GraphElement;
import org.omg.uml.foundation.core.ModelElement;
import org.omg.uml.behavioralelements.usecases.Actor;

public class MyClass implements TargetListener{
	public void handleTargetChanged(Target oldTarget, Target newTarget) {
		Diagram diag = newTarget.getDiagram();
		GraphElement fig = newTarget.getDiElement();
		ModelElement element = (ModelElement)newTarget.getElement();
		if (element!=null && element instanceof Actor) {
			System.out.println("Actor selected!");
		}
	}
}
MyClass listener = new MyClass();
PoseidonUIConnector.addTargetListener(listener);
[...]
PoseidonUIConnector.removeTargetListener(listener);