Os Element factories são utilizados para recriar objetos de gabarito do workbench com os dados salvos durante o encerramento do workbench.
Antes de nos aprofundarmos na extensão do element factory, precisamos rever uma técnica geral utilizada na plataforma toda para incluir comportamento específico do plug-in nos objetos de gabaritos comuns da plataforma.
Ao navegar pelas várias classes do workbench, notaremos que muitas das interfaces do workbench estendem a interface IAdaptable.
Os plug-ins utilizam adaptadores para incluir comportamento a tipos preexistentes no sistema. Por exemplo, o workbench talvez queira que os recursos respondam com um rótulo e uma imagem com finalidade de visualização. Sabemos que não é um bom design incluir comportamento específico da UI em objetos de nível inferior, portanto, como podemos incluir esse comportamento nos tipos de recurso?
Os plug-ins podem registrar adaptadores que incluem comportamento em tipos preexistentes. Em seguida, o código de aplicativo pode consultar se há um adaptador específico em um objeto. Se houver um registrado para ele, o aplicativo poderá obter o adaptador e utilizar os novos comportamentos definidos no adaptador.
Fornecendo um recurso para consultar dinamicamente a existência de um objeto em um adaptador, podemos melhorar a flexibilidade do sistema à medida que ele evolui. Novos adaptadores podem ser registrados nos tipos de plataforma através de novos plug-ins, sem ter que alterar as definições dos tipos originais. O padrão para pedir a um objeto um adaptador específico é o seguinte:
//fornecido um objeto o, queremos fazer coisas do "workbench" com ele. if (!(o instanceof IAdaptable)) { return null; } IWorkbenchAdapter adapter = (IWorkbenchAdapter)o.getAdapter(IWorkbenchAdapter.class); if (adapter == null) return null; // agora posso tratar como um IWorkbenchAdapter ...
Se não há adaptador disponível registrado para o objeto, será retornado null como adaptador. Os clientes devem estar preparados para manipular esse caso. Haverá momentos em que um adaptador esperado não foi registrado.
O workbench utiliza adaptadores para obter informações sobre a UI dos tipos base da plataforma, como IResource. Os adaptadores protegem os tipos base do conhecimento específico da UI e permitem que o workbench desenvolva suas interfaces sem alterar as definições da base.
Sem adaptadores, qualquer classe que pudesse ser distribuída na API do workbench teria que implementar as interfaces da UI, o que aumentaria o número de definições de classes, introduziria acoplamento firme e criaria dependências circulares entre as classes do núcleo e da UI. Com adaptadores, cada classe implementa IAdaptable e utiliza o registro do adaptador para permitir que os plug-ins estendam o comportamento dos tipos base.
Em todo o código do workbench, você verá casos em que um tipo de núcleo da plataforma é consultado para ver se há um adaptador. A consulta é utilizada para obter um objeto que saiba como responder informações orientadas pela UI sobre o tipo.
Quando o workbench é encerrado pelo usuário, ele deve salvar o estado atual dos objetos IAdaptable mostrados no workbench. O estado de um objeto é armazenado salvando-se os parâmetros de dados primitivos do objeto em um formato especial, um IMemento. O ID de um factory que pode recriar o objeto a partir de um IMemento também é armazenado e os dados são salvos no sistema de arquivos.
Quando a plataforma é reiniciada, o workbench encontra o element factory associado ao ID do factory do IMemento. Ele encontra o factory verificando a existência de contribuições para a extensão org.eclipse.ui.elementFactories no registro do plug-in.
A marcação é bem simples. Temos apenas que especificar o ID do factory e a classe correspondente que o implementa.
O fragmento de código a seguir é do plugin.xml do workbench.
<extension point="org.eclipse.ui.elementFactories"> <factory class="org.eclipse.ui.internal.model.ResourceFactory" id="org.eclipse.ui.internal.model.ResourceFactory"> </factory> <factory class="org.eclipse.ui.internal.model.WorkspaceFactory" id="org.eclipse.ui.internal.model.WorkspaceFactory"> </factory> <factory class="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.ui.part.FileEditorInputFactory"> </factory> <factory class="org.eclipse.ui.internal.dialogs.WelcomeEditorInputFactory" id="org.eclipse.ui.internal.dialogs.WelcomeEditorInputFactory"> </factory> <factory class="org.eclipse.ui.internal.WorkingSetFactory" id="org.eclipse.ui.internal.WorkingSetFactory"> </factory> </extension>