Listening for Changes to Faceted Projects

The Faceted Project Framework provides a facility that will notify any interested parties when a change is made to the model of a faceted project. Listeners can be registered either via a direct API call or via an extension point. Listeners can be global or scoped to a specific project.

Events

Event Type Event Object Interface Description
PROJECT_MODIFIED IFacetedProjectEvent Gets triggered when faceted project metadata is modified in any way. No detailed information about the change is provided. Note that while listening for PROJECT_MODIFIED events is guaranteed to catch all other events, the inverse is not true. Listing on all the other events is not guaranteed to catch all PROJECT_MODIFIED events. This is because there are circumstances when the system does not have the details about the type of the change (such as when the faceted project metadata file is modified on disk).
PRE_INSTALL IProjectFacetActionEvent Gets triggered right before a facet is installed.
POST_INSTALL IProjectFacetActionEvent Gets triggered right after a facet is installed.
PRE_UNINSTALL IProjectFacetActionEvent Gets triggered right before a facet is uninstalled.
POST_UNINSTALL IProjectFacetActionEvent Gets triggered right after a facet is uninstalled.
PRE_VERSION_CHANGE IProjectFacetActionEvent Gets triggered right before a facet version is changed.
POST_VERSION_CHANGE IProjectFacetActionEvent Gets triggered right after a facet version is changed.
FIXED_FACETS_CHANGED IFixedFacetsChangedEvent Gets triggered when project's fixed facets are changed.
TARGETED_RUNTIMES_CHANGED ITargetedRuntimesChangedEvent Gets triggered when the set of runtimes that the project targets is changed.
PRIMARY_RUNTIME_CHANGED IPrimaryRuntimeChangedEvent Gets triggered when the primary targeted runtime of the project is changed.

Registering a Listener

All listeners have to implement IFacetedProjectListener interface which looks like this:

package org.eclipse.wst.common.project.facet.core.events;

public interface IFacetedProjectListener 
{
    void handleEvent( IFacetedProjectEvent event );
}

Depending on the event type, it may be possible to cast the event object to a more specific interface in order to get details about the event. See the event table for information about which event object interface corresponds with which event type.

There are three ways to register a listener:

  1. IFacetedProject.addListener()
  2. FacetedProjectFramework.addListener()
  3. Extension Point: org.eclipse.wst.common.project.facet.core.listeners

All of these methods allows you to specify which events the listener should be notified about. Not specifying event types on registration will cause the listener to be notified about all events. This is typically not desired. If a listener needs to react to any change in the project and has no need to analyze specific events, it should be registered for the PROJECT_MODIFIED event.

The first method registers a listener that is scoped to a specific project. The last two register a global listener which will be notified about changes in all faceted projects that are present in the workspace. In most circumstances, if a global listener is needed, it should be registered via the extension point rather than using FacetedProjectFramework.addListener() API. Using the extension point guarantees that the listener will not miss any events due to not being registered early enough. It also delays initialization of the plugin bundle containing the listener until an event that the listener is interested in is fired.

Extension Point

The extension point that's used for registering listeners is quite simple. Only two pices of information need to be supplied: the listener class name and an optional list of event types.

<extension point="org.eclipse.wst.common.project.facet.core.listeners">
  <listener 
    class="{class:org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener}"
    eventTypes="{event.types}"/> (1 or more)
<extension>

The eventTypes attribute value should be a comma-separated list of event types.

Examples

This example registers a very simple listener that prints out events received. The listener is registered several different ways for the purposes of this example.

package com.mycorp.myproduct;

import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;

public final class ListenerImpl implements IFacetedProjectListener 
{
    public void handleEvent( final IFacetedProjectEvent event )
    {
        System.out.println( event.toString() );
    }
}

The following code snippet registers the above listener on a specific project to listen for changes in the runtimes that the project targets.

import org.eclipse.core.resources.IProject;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;

...

IProject pj;

...

final IFacetedProject fpj = ProjectFacetsManager.create( pj );
final ListenerImpl listener = new ListenerImpl();

fpj.addListener( listener, 
                 IFacetedProjectEvent.Type.TARGETED_RUNTIMES_CHANGED,
                 IFacetedProjectEvent.Type.PRIMARY_RUNTIME_CHANGED );
                 
...

fpj.removeListener( listener );

The following code snippet register the above listener to listen for the PRE_INSTALL and PRE_UNINSTALL events in all faceted projects.

import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;

...

final ListenerImpl listener = new ListenerImpl();

FacetedProjectFramework.addListener( listener, 
                                     IFacetedProjectEvent.Type.PRE_INSTALL,
                                     IFacetedProjectEvent.Type.PRE_UNINSTALL );
                 
...

FacetedProjectFramework.removeListener( listener );

The following code snippet accomplishes the same thing as the one above, except it does this via the extension point.

<extension point="org.eclipse.wst.common.project.facet.core.listeners">
  <listener class="com.mycorp.myproduct.ListenerImpl" eventTypes="PRE_INSTALL,PRE_UNINSTALL"/>
<extension>