Chapter 3. ISV Manual

Table of Contents

Eventbus
IAstProvider
JavaElement Events Provider
Call Chain Completion
Example: Call Chain Using a Local Variable
Design Overview
Extdoc
Design Overview for Extdoc
Workflow: Processing of a Java Selection Event
Example of a provider execution scheduling
Layout of the ExtdocView
Sources of an example provider

Eventbus

Code Recommenders uses an event bus to get rid of all kind of listener interfaces. Although considered to be used internally mostly, the bus may be used by other subscribers (such as usage data collectors, indexing services etc.) to respond to events such as compilation unit changes, project creations or deletions etc.

To subscribe to the event bus one has to obtain an instance of EventBus using Code Recommenders' injection service (or Guice Injector).

Event providers using the workspace event bus:

IAstProvider

Code Recommenders offers an AST caching service that can be used by completion engines to get the last know ast of a compilation unit.

Needs verification.

Do we still need that? Why not use the AST that is send with the compilation unit?

JavaElement Events Provider

The JavaElementEventsProvider sends events such as project open/close or compilation unit added/removed/changed/saved events. This list is incomplete and is expected to grow quickly for 1.0. Look at the corresponding class to learn which events it posts to the event bus.

Call Chain Completion

Example: Call Chain Using a Local Variable

This example briefly illustrates the graph structure used to create call chains by a simple example:

        ExecutorService pool = Executors.newCachedThreadPool();
        Future future = $
        

Resulting Callchain graph

Design Overview

Class Responsibilities

  1. CallChainCompletionProposalComputer : Extracts the available information about accessible locals, fields and methods to find all potential entry-points for the GraphBuilder .
  2. CallChainCompletionProposal : The proposal that gets executed when the user selects the proposal from code completion window. It internally relies on a (jdt) Template built by the CompletionTemplateBuilder .
  3. CompletionTemplateBuilder : builds, as the name suggests, the Java template. It does quite a lot JDT internal magic and is considered unclean and yet incomplete (!).
  4. GraphBuilder : Creates the call chain graph. Uses a thread pool internally for building the graph (but not for creating the call chains). This might change?
  5. TypeNode : represents the class node in a call chain. It stores the incoming edges which are later used to travers the graph and build the call chains.
  6. MemberEdge : represents a transition from one type to another, typically an IMethod, IType, or ILocalVariable (for entry points only).

Design Overview

Extdoc

Design Overview for Extdoc

Class Responsibilities

ExtdocView

central controller; manages the registering and unregistering of all components on the EventBus ; listens for selection events and delegates them to the ProviderExecutionScheduler . Uses ProviderConfigurationPersistenceService to persist the width of the Sash (vertical separator between overview and content).

SubscriptionManager

Manages the subscriptions for specific java selections of all registered providers. Can be queried to return a matching java.lang.reflect.Method for a given provider that should be called for the selection. No guarantees are provided which method is returned if multiple methods of a provider overlap.

ProviderExecutionScheduler

Manages the multithreaded execution of all providers. To indicate the status of the execution corresponding execution events are posted to the EventBus .

ExtdocProvider

Extdoc providers are the entities of the extdoc view that bring the real content. Providers are registered via the extension point org.eclipse.recommenders.extdoc.rcp.provider .

The content is provided through methods that are annotated with a @JavaSelectionSubscriber annotation. More details on this and an example provider is given in a later section

ExtdocProvider provide an ExtdocProviderDescriptor to access their

A single List<ExtdocProvider> is injected to all entities that need to know the providers.

ProviderOverviewPart

darstellung des status aktivierung / deaktivierung order change insb. das management in der liste

ProviderContentPart

manages the displayed content. A new (background) rendering panel can be created and the corresponding Composite can be accessed for each provider.

ProviderArea

Helper class for the visualization of the providers. Mainly accessed by the ProviderContentPart it can be used to set a status or to show the contents of a provider when it is completely rendered.

ProviderConfigurationPersistenceService

This entity is left out in the diagram. It is registered on the EventBus and used to persist the provider configuration to disc on change. The provider configuration consists of the order of all providers and of a list of all disabled providers.

PreferencesFacade

This entity is left out in the diagram. It directly accesses Eclipses singletons to be able to load and save preferences. A low-level API is provided to load/store:

  1. order of the providers

  2. disabled providers

  3. position of the sash in the Extdoc view

This entity is mainly used to increase the testability of all entities that make use of it as they do not need to access Eclipses singletons and this class can be exchanged with a mock for testing.

Workflow: Processing of a Java Selection Event

  1. A JavaSelectionEvent is posted to the extdoc view.

  2. A new ProviderExecutionScheduler is created and the old one is disposed.

  3. The SubscriptionManager is used to identify the providers that are interested in the selection.

  4. A new (hidden) rendering panel is created in the ProviderContentPart .

  5. For each provider the new content area is requested and used as a parameter for the provider execution. This is done by the ProviderExecutionScheduler in multiple threads.

  6. The ProviderOverviewPart updates the provider icons according to the posted execution events of all providers.

  7. The ProviderContentPart listen for the resulting events and update their displayed data accordingly. On finish events the hidden content area of the provider is shown, delay and fail events lead to a status message.

  8. The ProviderContentPart listens for the RenderNowEvent and switches the rendering panel to the new foreground panel if it is posted.

Example of a provider execution scheduling

This example is a conceptual view onto the events that are posted during the provider execution. For this example it is assumed that three providers are registered:

  1. P1 is a fast provider that terminates correctly.

  2. P2 is a provider that crashes on execution with an exception.

  3. P3 is a provider that terminates correctly but takes very long.

The entry point is the schedule(selection) call from the extdoc view. The current selection is provided as a parameter and a NewSelectionEvent is posted. Based on the selection all subscribed provider methods are queried from the SubscriptionManager . A ProviderStartedEvent is posted for each provider and the execution is started in separate threads. Additionally a timeout is started to be able to guarantee a maximum rendering time for the Extdoc view.

P1 finishes first and the successful execution triggers the posting of a ProiderFinishedEvent . The event contains the corresponding provider. P2 crashes on execution and the caught exception triggers a ProviderFailedEvent . Also P3 is not finished yet the render timeout is reached so the next event is a RenderNowEvent companied by ProviderDelayedEvent s for all still running providers. . P3 terminaes successfully after this and a ProviderFinishedLateEvent is posted.

In addition to the normal execution events it is possible that a provider is not interested in a selection. This is possible in two different ways:

  1. If a provider is not subscribed to a selection the SubscriptionManager does not find a suitable method.

  2. A provider might detect during the execution that no data is available to successfully process the selection. In this case a Status.NOT_AVAILABLE can be returned.

In both cases a ProviderNotAvailableEvent is posted for the provider.

Several other events exist:

  1. ProviderOrderChangedEvent : indicates a reordering of the providers

  2. ProviderDe-/ActivationEvent : posted if providers are enabled/disabled. Both are consumed by the ProviderExecutionScheduler . Activation events lead to the execution of the provider with the last selection, deactivation events cancel the running provider.

  3. ProviderSelectionEvent : if providers are selected in the overview the content shuld "jump" to their positions in the content. This event is used to indicate such a selection and is irrelevant for the execution scheduler.

All these are posted from the UI components and not from the scheduler.

Layout of the ExtdocView

Description of the Layout

  1. ExtdocView : Central view that is registered with Eclipse and container for all sub content parts.
  2. ProviderOverviewPart : Manages an overview of all available Extdoc providers in a table. Each provider can be de-/activated by un-/checking the associated ProviderItem . The order of the providers can be changed through drag and drop.
  3. ProviderContentPart : Manages a scrolling stack of content panes. Allows to create a new (background) rendering Composite that contains ProviderArea s for all providers.

    The ProviderContentPart is registered on the EventBus and subscribes all provider related events. Depending on the execution status a providers area is shown or the status is set.

  4. ContentPane (Composite) simple composite that contains all rendered content for a selection
  5. ProviderArea : area that is associated with an Extdoc provider. Allows to set an (optionally clickable) status and to show the rendered content. All sub elements are plain SWT components and with the exception of the content that is provided to the ExtdocProvider all are hidden to the outside. Renders a title for the associated provider.
  6. TitleArea (Composite) status for a providers. It is used at the moment to show delay in execution or to show execution failures.
  7. StatusArea (Composite) status for a providers. It is used at the moment to show delay in execution or to show execution failures.
  8. ContentArea (Composite) Composite that contains the rendered results of the corresponding provider.

Sources of an example provider

An ExtdocProvider is registered on the SubscriptionManager . To be recognized as an provider its methods need to be annotated with a JavaSelectionSubsriber annotation. The parameter list of such methods is fixed:

  1. a IJavaElement (or a subclass of it) defines for which elements this methods provides some content.

  2. the fired JavaSelectionEvent

  3. a Composite into which the contents should be rendered

Three examples are shown in the following diagram.

The simplest case is shown in the method example(...) . The annotation indicates that it is interested in all JavaSelectionEvents . Because the first parameter is an IJavaElement (the super class of all selectable java elements) the method is executed for all possible events.

It is possible to use the annotation and the IJavaElement as a filter to be able to write more specialized provider methods. An example of this is given in method unavailableProvider(...) . The annotation take optional arguments to specify locations for which a selection should be processed. It is possible to provide multiple locations, i.e.: @JavaSelectionSubscriber({METHOD_BODY, TYPE_DECLARATION}) . The events are also matched by the selected java element so it is possible to only subscribe for IType selections if it is used as the first parameter.

Word of caution: if method subscriptions overlap (like it is in this example) only on method is called on an event. No guarantees are given which one.

The providers are executed in their own thread so it is necessary to switch to the UI thread for the rendering. Take a look on the two parts of the example(...) method. All non-UI related information gathering should be done in the provider thread. After that a Runnable can be executed with the helper method runSyncInUiThread(...) . By doing so exceptions that are thrown in the runnable are bubbled out of the Runnable and rethrown in the provider thread. The execution is run sync so that the providers does not finish until the rendering is complete.

A provider can return an ExtdocProvider.Status to indicate its processing status. A normal execution returns Status.OK . If it is not possible to process the current selection (i.e. because the provider has no data available), it is possible to return Status.NOT_AVAILABLE . The provider status is then handled by the UI as if it is not subscribed even if it has already started processing.

It is feasible to throw an exception in a provider as shown in method errorCase(...) . In this case the provider is shown as failed in the UI and a link is shown that opens a dialog with a stacktrace and the message from the exception.