Implementación de componentes

Los componentes registrados con el punto de extensión de tipos son muy parecidos a los componentes. Pueden tomar un conjunto de dependencias en su constructor y deben implementar la interfaz para la que se registraron. Este ejemplo muestra la implementación de NullNameableService.

/**
 * Implementación por omisión del servicio Nameable. Todos los métodos son no-ops.
 *
 * @since 3.1
 */
public class NullNameableService implements INameable {

    /**
     * Constructor de componentes. No debe invocarse directamente.
     */
    public NullNameableService() {}

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

Éste puede ser un ejemplo sencillo, ya que la clase no hace nada; no obstante, demuestra un patrón común. El servicio INameable se utiliza para indicar al padre algún estado existente en el hijo. Con este tipo de interfaz, normalmente la implementación por omisión no realiza ninguna acción. Esto es lógico, ya que si al padre no tiene en cuenta el estado de su hijo, puede pasarlo por alto. Existe el convenio de utilizar el prefijo "Null" para indicar que se trata de un componente que no realiza ninguna acción. Este tipo de objeto suele registrarse como monoinstancia, ya que sería un derroche de recursos el crear varias instancias de un objeto tan trivial. Los clientes deben asegurarse de que las nuevas interfaces que informen de estados tengan la capacidad de multiplexación.

Si el propósito de la interfaz es el de asignar recursos o generar salida, normalmente la implementación por omisión hará algo más útil. El ejemplo siguiente muestra la implementación de la clase DefaultMessageDialogs. Dado que esta clase está concebida para generar salida interactiva, tiene una implementación por omisión útil y no daría soporte a la multiplexación. Como esta clase tiene que acceder al elemento Composite de un componente, no puede ser una monoinstancia. Por convenio, se utiliza el prefijo de clase "Default" para indicar que se trata de un componente por omisión con un funcionamiento útil.

/**
 * Implementación por omisión de la interfaz IMessageDialogs. Toma el control
 * del componente como contexto y permite que el componente abra diálogos en un shell hijo.
 *
 * @since 3.1
 */
public class DefaultMessageDialogs implements IMessageDialogs {

    private Composite control;
   
    /**
     * Constructor de componentes. No debe invocarse directamente.
     */
    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);
        }   
    }
}

Éstos son los códigos del punto de extensión asociado para 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>