## Model Visualization

### Visualization framework

The plug-in `org.eclipse.app4mc.visualization.ui` provides a small framework to visualize model elements. It contains a view part `VisualizationPart` that can be opened via

- Window → Show View → Other... → APP4MC → APP4MC Visualizations,
- or via right click on an element and selecting Open APP4MC Visualization.

Via the context menu it is also possible to open multiple instances of the `VisualizationPart`.

On selecting a model element, the VisualizationPart is updated to render a corresponding visualization. The visualization to render is searched in the ModelVisualizationRegistry OSGi service. If multiple visualizations are registered, the first one will be selected by default, unless the user has selected another visualization before.

The visualization view has 3 buttons in the toolbar:

1. Visualization dropdown
   The dropdown contains all available visualizations for the current active selection. A click on the image will reload the visualization.
2. Pin visualization
   The selection handling will be disabled so the visualization gets not updated on model selection changes.
3. Select model element
   Selects the current visualized model element in the model editor. Useful for example if a visualization is pinned and the selection in the model editor changed.

The whole red area can be used to render the visualization.

### Contributing a new model visualization

To contribute a new visualization to the framework, the followings steps have to be done:

1. Create a new plug-in for the visualization contribution.
2. Add at least the following dependencies:
   - Required Plug-ins
     - org.eclipse.jface
       (to be able to contribute to the view)
   - Imported Packages
     - org.eclipse.app4mc.amalthea.model
       (to get access to the model element that should be rendered)
     - org.eclipse.app4mc.visualization.ui.registry
       (needed to import the necessary interface)
     - org.osgi.service.component.annotations: In the properties, select Minimum Version as 1.3.0 inclusive
       (needed to get access to the OSGi DS annotations)
3. Create a new Visualization implementation that follows this pattern:

    @Component(property= {
    		"name=Runnable Visualization",
    		"description=Render the name of the Runnable"
    })
    public class SampleVisualization implements Visualization {

    	@PostConstruct
    	public void createVisualization(Runnable runnable, Composite parent) {
    		Label label = new Label(parent, SWT.NONE);
    		label.setText(runnable.getName());
    	}
    }

To register the Visualization implementation the framework utilizes OSGi DS. This means:

- The class needs to implement Visualization (only a marker interface needed for OSGi service injection)

    It is mandatory to place this class inside a user defined package (i.e., other than default package)

- The class needs to be annotated with @Component (ensure DS annotation support is enabled in your workspace)

    To enable DS annotation for the entire workspace,enable the following option in your eclipse workspace at:
    Window -> Preferences -> Plug-in Development -> DS Annotations -> "Enable descriptors from annotated sources"

Once above steps are followed, visualization plugin contents should look like below:

The Visualization will automatically be registered in the ModelVisualizationRegistry with the appropriate meta-data. The meta-data is extracted from the class definition and the method annotated with @PostConstruct. Additionally information can be provided via component properties on the @Component annotation.

The following component properties are supported:

id
  Defaults to the fully qualified class name of the service.
  Used to uniquely identify the last selected visualization.

name
  Defaults to the simple class name of the service.
  Used in the visualization dropdown as label of the menu item.

description
  Defaults to null.
  Used in the visualization dropdown as tooltip of the menu item.

type
  Defaults to the type of the first parameter of the @PostConstruct method.
  Used to register the visualizations for a given model type.
  Note: It is not recommended to override the type configuration.

The rendering is triggered via Eclipse injection mechanisms. Therefore a method annotated with @PostConstruct needs to be created. This method needs at least two parameters in the following order:

1. Model type or java.util.List<Model type>
   The first parameter needs to be the type or a List of the type that should be handled by this Visualization.
2. Composite
   The parent Composite on which the rendering should be performed.

So the following method signatures would be valid for Visualizations for Runnable model elements:

    @PostConstruct
    public void createVisualization(Runnable runnable, Composite parent) {}

    @PostConstruct
    public void createVisualization(List<Runnable> runnable, Composite parent) {}

You can specify additional parameters that should be injected. Only the first parameter has a semantic to be able to extract the model type for which the Visualization is implemented.

Additionally a method annotated with @PreDestroy can be added that gets called before the Visualization is disposed. This gives the opportunity to clean up resources if necessary.

As the service instance creation is done by the OSGi Service Component Runtime, the following information needs to be considered with regards to injection:

1. You can use @Reference to get other OSGi services injected.
2. There is no field or constructor injection available via Eclipse injection.
   (usage of @Inject on fields or constructors will not work)
3. In general you should not use fields/members to store rendering related information on an instance level.