# 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>