Implémentation des composants

Les composants enregistrés avec les points d'extension types sont très similaires à des composants "part". Ils peuvent prendre un ensemble de dépendances dans leur constructeur et doivent implémenter l'interface pour laquelle ils ont été enregistrés. Cet exemple montre l'implémentation de 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) {}
}

Cet exemple est simple car la classe ne fait rien, mais il illustre un motif courant. Le service INameable est utilisé pour prévenir les parents de l'état des enfants. Avec ce type d'interface, l'implémentation par défaut ne fait rien. C'est logique : si le parent ne se soucie pas de l'état de son enfant, il peut être ignoré. Par convention, on utilise le préfixe "Null" pour indiquer que ce composant ne fait rien. Ce type d'objet est généralement enregistré en tant que singleton car il serait inutile de créer plusieurs instances d'un objet aussi insignifiant. Les clients doivent s'assurer que toute nouvelle interface qui rend compte des états peut être multiplexée.

Si le but de l'interface est d'allouer des ressources ou de générer un résultat, l'implémentation par défaut aura une action plus utile. L'exemple suivant illustre l'implémentation de la classe DefaultMessageDialogs. Comme cette classe a pour rôle la génération de résultats interactifs, elle a une implémentation par défaut utile et ne peut être multiplexée. Cette classe doit accéder au composite d'un composant "part", elle ne peut donc être un singleton. Par convention, on utilise le préfixe de classe "Default" pour indiquer qu'il s'agit d'un composant par défaut avec une action utile.

/**
 * 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);
        }   
    }
}

Voici le marquage de l'extension associée pour 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>