Implementação do Componente

Os componentes registrados com o ponto de extensão de tipos são muito parecidos com componentes de parte. Eles podem utilizar um conjunto de dependências em seu construtor e devem implementar a interface para as quais foram registrados. Este exemplo mostra a implementação do NullNameableService.

/**
 * Implementação padrão do serviço Nameable. Todos os métodos são no-ops.
 *
 * @since 3.1
 */
public class NullNameableService implements INameable {

    /**
     * Construtor do componente. Não chamar diretamente.
     */
    public NullNameableService() {}

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

Esse pode ser um exemplo simples pois a classe não faz nada, no entanto, ele demonstra um padrão comum. O serviço INameable é utilizado para informar o pai sobre algum estado no filho. Com esse tipo de interface, tipicamente, a implementação padrão não faz nada. Isso faz sentido: se o pai não se preocupar com o estado do filho, ele poderá ser ignorado. Por convenção, utilizamos o prefixo "Null" para indicar que este é um componente que não faz nada. Esse tipo de objeto geralmente é registrado como um singleton pois seria desperdício criar várias instâncias de um objeto tão trivial. Os clientes devem verificar se quaisquer interfaces novas que relatam estado podem ser multiplexadas.

Se o objetivo da interface for alocar recursos ou gerar saída, tipicamente, a implementação padrão fará alguma coisa mais útil. O exemplo a seguir mostra a implementação da classe DefaultMessageDialogs. Como essa classe tem como objetivo gerar saída interativa, ela terá uma implementação padrão útil e não suportará multiplexação. Como essa classe precisa acessar o Composto de uma parte, ela não poderá ser singleton. Por convenção, utilizamos o prefixo de classe "Padrão" para indicar que este é um componente padrão com algum comportamento útil.

/**
 * Implementação padrão da interface IMessageDialogs. Utiliza o controle
 * de parte como contexto e permite que a parte abra diálogos em um shell filho.
 *
 * @since 3.1
 */
public class DefaultMessageDialogs implements IMessageDialogs {

    private Composite control;
   
    /**
     * Construtor do componente. Não chamar diretamente.
     */
    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);
        }   
    }
}

Aqui está a marcação do ponto de extensão associado 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>