Component implementation

Components registered with the types extension point are much like part components. They can take a set of dependencies in their constructor and must implement the interface they were registered for. This example shows the implementation of the NullNameableService.

/**
 * Default implementation of the Nameable service. All methods are no-ops.
 *
 * @since 3.1
 */
public class NullNameableService implements INameable {

    /**
     * Component constructor. Do not invoke directly.
     */
    public NullNameableService() {}

    public void setName(String newName) {}
    public void setContentDescription(String contentDescription) {}
    public void setImage(ImageDescriptor theImage) {}
    public void setTooltip(String toolTip) {}
}

This may be a simple example as the class doesn't do anything, however it demonstrates a common pattern. The INameable service is used to tell the parent about some state in the child. With this type of interface, the default implementation typically doesn't do anything. This makes sense: if the parent doesn't care about the state of its child, it can be ignored. By convention, we use the "Null" prefix to indicate that this is a component that doesn't do anything. This type of object is usually registered as a singleton since it would be wasteful to create multiple instances of such a trivial object. Clients should ensure that any new interfaces that report state are capable of being multiplexed.

If the purpose of the interface is to allocate resources or generate output, the default implementation will typically do something more useful. The following example shows the implementation of the DefaultMessageDialogs class. Since this class is intended for generating interactive output, it has a useful default implementation and would not support multiplexing. Since this class needs access to a part's Composite, it cannot be a singleton. By convention, we use the class prefix "Default" to indicate that this is a default component with some useful behavior.

/**
 * Default implementation of the IMessageDialogs interface. Takes the part's
 * control as context and allows the part to open dialogs in a child shell.
 *
 * @since 3.1
 */
public class DefaultMessageDialogs implements IMessageDialogs {

    private Composite control;
   
    /**
     * Component constructor. Do not invoke directly.
     */
    public DefaultMessageDialogs(Composite control) {
        this.control = control;
    }
   
    public void open(IStatus message) {
        if (message.getSeverity() == IStatus.ERROR) {
            ErrorDialog.openError(control.getShell(), null, null, message);
        } else {
            open(message.getSeverity(), message.getMessage());
        }
    }

    public void openError(String message, Throwable cause) {
        open(new Status(IStatus.ERROR,
                WorkbenchPlugin.getDefault().getBundle().getSymbolicName(),
                IStatus.OK,
                message,
                cause));
    }
   
    public void open(int severity, String message) {
        if (severity == IStatus.ERROR) {
            MessageDialog.openError(control.getShell(), null, message);
        } else if (severity == IStatus.WARNING) {
            MessageDialog.openWarning(control.getShell(), null, message);
        } else {
            MessageDialog.openInformation(control.getShell(), null, message);
        }   
    }
}

Here is the associated extension point markup for DefaultMessageDialog.

<extension point="org.eclipse.core.component.types">
      <component
            initializer="org.eclipse.ui.part.SiteInitializer"
            interface="org.eclipse.ui.part.services.IMessageDialogs"
            implementation="org.eclipse.ui.internal.part.services.DefaultMessageDialogs"
            singleton="false"/>
</extension>