Alterações Requeridas ao Adotar os Mecanismos e APIs da 3.0

Esta seção descreve as alterações que são requeridas se você estiver tentando alterar o plug-in da 2.1 para adotar os mecanismos e APIs da 3.0.

Tirando o org.eclipse.core.runtime.compatibility

O tempo de execução do Eclipse 3.0 é significativamente diferente. A implementação subjacente é baseada na especificação de estrutura do OSGi. O tempo de execução do Eclipse 3.0 inclui uma camada de compatibilidade (no plug-in org.eclipse.core.runtime.compatibility) que mantém as APIs da 2.1. Os desenvolvedores de plug-in interessados no desempenho e funções adicionais devem considerar a adoção de APIs da 3.0 e a remoção de sua dependência da camada de compatibilidade. O código de compatibilidade aparece em três locais:

O texto abaixo fornece mais detalhes sobre quais classes e métodos estão presentes para fins de compatibilidade, bem como um guia sobre como atualizar o plug-in.

Plug-ins e pacotes configuráveis

O tempo de execução do Eclipse foi refatorado em duas partes; gerenciamento de carregamento de classe e de pré-requisito e gerenciamento de extensão/ponto de extensão. Essa divisão permite a adoção natural/completa da especificação de estrutura do OSGi para gerenciamento de carregamento de classe e pré-requisito. Isso, por sua vez, permite uma gama de novas capacidades no tempo de execução a partir da instalação/atualização/desinstalação do plug-in dinâmico para segurança e maior configurabilidade.

Enquanto continuamos a falar sobre plug-ins, no novo tempo de execução um plug-in é realmente um pacote configurável mais algumas extensões e pontos de extensão. O termo pacote configurável é definido pela especificação da estrutura OSGi e se refere a uma coleta de tipos e recursos e a informações de pré-requisito associadas entre pacotes configuráveis. O registro de extensão é a nova forma do registro de plug-in e detalha apenas informações de extensão e de pontos de extensão. No todo, a API do registro de extensão é igual à API do registro de plug-in pertinente (para obter informações adicionais, consulte Registros).

No tempo de execução do Eclipse 2.x, o objeto de plug-in tem uma série de funções e responsabilidades:

Na imagem do tempo de execução do Eclipse 3.0, essas funções e responsabilidades são fatoradas em objetos distintos.

Pacote configurável
Os pacotes configuráveis são a unidade de modularidade do OSGi. Há um carregador de classes em cada pacote configurável e os gráficos de dependência de carregamento de classe entre pacotes configuráveis semelhantes ao Eclipse podem ser construídos. Os pacotes configuráveis têm ciclo de vida para iniciar e parar e a estrutura OSGi difunde os eventos relacionados aos pacotes configuráveis (por exemplo, instalar, resolver, iniciar parar, desinstalar ...) às partes interessadas. Ao contrário da classe Plugin do Eclipse, a classe Bundle do OSGi não é extensível. Ou seja, os desenvolvedores não têm a oportunidade de definir sua própria classe de pacote configurável.
BundleActivator
BundleActivator é uma interface definida pela estrutura OSGi. Cada pacote configurável pode definir um ativador de pacote configurável da mesma forma que um plug-in pode definir sua classe Plugin. A classe especifica é instanciada pela estrutura e utilizada para implementar o processamento de ciclo de vida start() e stop(). Há uma diferença importante, no entanto, na natureza desse processamento de ciclo de vida. No Eclipse, é comum (embora não recomendado) as classes Plugin fazerem inicialização e registro. No OSGi, os ativadores devem apenas fazer o registro. Fazer grande quantidade de inicialização (ou de qualquer outro trabalho) no BundleActivator.start() ameaça a agilidade do sistema.
BundleContext
BundleContexts são o mecanismo OSGi para expor funções gerais do sistema para pacotes configuráveis individuais. Cada pacote configurável tem uma instância exclusiva e privada de BundleContext que pode ser utilizada para acessar a função do sistema (por exemplo, getBundles() para descobrir todos os pacotes configuráveis no sistema).
Plugin
O novo Plugin é muito semelhante à classe Plugin original do Eclipse com as seguintes exceções: os objetos Plugin não são mais requeridos ou gerenciados pelo tempo de execução e os vários métodos foram reprovados. É essencialmente um mecanismo de conveniência fornecer um host de função e mecanismos úteis, mas isso não é mais requerido. Muitas funções fornecidas lá também estão disponíveis na classe Platform no tempo de execução.

Plugin também implementa BundleActivator. Ele reconhece a conveniência de ter um objeto central representando o ciclo de vida e a semântica de um plug-in. No entanto, observe que ele não aprova a inicialização ávida que é comum nos plug-ins atuais. Não podemos salientar o suficiente que os plug-ins podem ser ativados porque alguma uma classe periférica foi referida durante a verificação de uma classe em algum outro plug-in. Ou seja, apenas porque seu plug-in foi ativado não significa necessariamente que sua função é necessária. Observe também que você está livre para definir uma classe BundleActivator diferente ou não ter um ativador de pacotes configuráveis.

As etapas requeridas para transportar uma classe Plugin da 2.x para o Eclipse 3.0 depende de qual classe está fazendo o transporte. Conforme descrito acima, a maioria do trabalho do ciclo de vida de inicialização falha em uma das seguintes categorias:

Inicialização
A inicialização da estrutura e do modelo de dados é freqüentemente feita no Plugin.startup(). O mapeamento natural/óbvio será fazer esse trabalho em um BundleActivator.start(), ou seja, deixar a função no Plugin. Isso é extremamente desincentivado. Como ocorre nos plug-ins da 2.x, os plug-ins/pacotes da 3.0 poderão ser iniciados para várias razões diferentes em várias circunstâncias diferentes.
Um exemplo real de dias do Eclipse 2.0 esclarece esse caso. Havia um plug-in que inicializava um grande modelo que requeria o carregamento de 11 MB de código e vários megabytes de dados. Havia casos casos de uso bem comuns nos quais esse plug-in era ativado para descobrir se o ícone do projeto apresentado no navegador deveria ser decorado com uma marcação específica. Esse teste não requeria que nenhuma inicialização fosse feita em startup(), mas, no entanto, todos os usuários em todos os casos de uso tinham de pagar a multa de memória e tempo por essa inicialização ávida.
A abordagem alternativa é fazer tal inicialização em um estilo lento clássico. Por exemplo, em vez de ter modelos inicializados quando o plug-in/pacote pacote configurável estiver ativado, faça-o quando eles realmente forem necessários por exemplo, em um método do acessador de modelo centralizado. Para vários casos de uso, isso equivalerá próximo ao mesmo ponto no tempo, mas para outros cenários essa abordagem adiará a inicialização (talvez indefinidamente). Recomendamos que obtenha tempo ao transportar plug-ins da 2.1 para reconsiderar a estratégia de inicialização utilizada.
Registro
A inicialização do plug-in é um tempo conveniente para registrar listeners, serviços, etc. e iniciar encadeamentos de processamento em segundo plano (por exemplo, atender em um soquete). Plugin.start() poderá ser um local razoável para fazer esse trabalho. Também poderá fazer sentido adiar até algum outro acionamento (por exemplo, o uso de uma função específica ou elemento de dados).
Dados globais do plug-in
Sua classe Plugin pode continuar a desempenhar essa função. O principal problema é que os objetos Plugin não são mais globalmente acessíveis através de uma lista gerenciada pelo sistema. No Eclipse 2.x, você poderia descobrir qualquer objeto Plugin do plug-in através do registro de plug-ins. Isso não é mais possível. Na maioria das circunstâncias, esse tipo de acesso não é requerido. Plugins acessados através do registro são mais normalmente utilizados como Plugins genéricos, em vez de chamar métodos específicos do domínio. O nível equivalente de capacidade pode ser obtido, acessando e manipulando os objetos Bundle correspondentes.

Registros e o Modelo de Plug-in

No novo tempo de execução, há uma separação entre as informações e a estrutura necessária para executar um plug-in e aquela relacionada às extensões e pontos de extensão do plug-in. A primeira é definida e gerenciada pela especificação da estrutura OSGi. A segunda são conceitos específicos do Eclipse e são incluídos pelo código de tempo de execução do Eclipse. Dessa maneira, o registro do plug-in original e os objetos relacionados foram divididos em pacotes configuráveis do OSGi e registro de extensão do Eclipse.

As partes do IPluginRegistry que lidam com a especificação da execução (por exemplo, IPluginDescriptor, ILibrary, IPrequisite) foram reprovadas e as partes restantes relacionadas às extensões e ao ponto de extensão foram movidas para IExtensionRegistry. Além do mais, os chamados objetos de modelo relacionados ao registro de plug-in como um todo agora estão reprovados. Esses foram apresentados e instanciados pelo tempo execução principalmente para suportar ferramentas, como o PDE. Infelizmente, freqüentemente o nível de informações necessárias excedia as capacidades ou interesses do tempo de execução (por exemplo, lembrando números de linha para elementos de plugin.xml) e no final, os consumidores potenciais das informações de tempo de execução tinham de manter sua próprias estruturas.

No novo tempo de execução precisamos reavaliar as facilidades fornecidas pelo tempo de execução e agora fornecer apenas aquelas que são essenciais para a execução do tempo de execução ou são extraordinariamente difíceis para outros fazerem. Conforme mencionado acima, os objetos de modelo de registro de plug-in foram reprovados porque têm a API de análise de plug-in. O novo registro de extensões mantém informações essenciais relacionadas à extensão. Uma nova estrutura de estado (consulte org.eclipse.osgi.service.resolver.State e friends) representa e permite a manipulação de informações essenciais relacionadas à execução.

Estrutura de Fragmento do NL

No Eclipse 3.0, a estrutura de fragmento do NL foi atualizada para ser mais consistente. As traduções para arquivos, como plugin.properties, foram anteriormente assumidas para ficarem dentro de JARs fornecidos por fragmentos. Como os arquivos originais estão localizados na raiz do plug-in de host pertinente, um local mais consistente teria os arquivos traduzidos localizados na raiz dos fragmentos do NL. Por exemplo:

  org.eclipse.ui.workbench.nl/
     fragment.xml
     plugin_fr.properties
     plugin_pt_BR.properties
     ...
     nl1.jar

Observe que o arquivo nl1.jar anteriormente continha as traduções para plugin.properties. Esses arquivos estão agora na raiz do fragmento e o JAR contém traduções de quaisquer recursos traduzíveis (isto é, arquivos carregados através do carregador de classe) no plug-in do host.

Naturalmente, a estrutura do fragmento NL do Eclipse 2.1 ainda é suportada pelos plug-ins do host da 2.1 que executam no Eclipse 3.0. No entanto, você não pode utilizar um fragmento NL da 2.1 em um plug-in da 3.0. O fragmento deve ser atualizado para a nova estrutura.

Visão Geral das Alterações da API

org.eclipse.core.boot (Pacote org.eclipse.core.boot)

O pacote org.eclipse.core.boot inteiro foi reprovado. O BootLoader foi mesclado com o org.eclipse.core.runtime.Platform pois não faz mais sentido ter uma divisão entre a inicialização e o tempo de execução. Observe que, de fato, o plug-in org.eclipse.core.boot foi dividido e todo o seu código movido para o novo tempo de execução ou a camada de compatibilidade.

IPlatformConfiguration sempre foi um tipo definido para o componente Instalar/Desinstalar do Eclipse. Com a reorganização do tempo de execução, podemos repatriar esse tipo para seu local correto. Essa classe permanece em grande parte inalterada e foi empacotada novamente como org.eclipse.update.configurator.IPlatformConfiguration.

O IPlatformRunnable foi movido para org.eclipse.core.runtime.IPlatformRunnable.

IExtension e IExtensionPoint (Pacote org.eclipse.core.runtime)

O método getDeclaringPlugin() (nas duas classes) fornece um link ascendente para o plug-in que declara a extensão ou o ponto de extensão (respectivamente). O novo modelo de registro separa os aspectos de execução de plug-ins dos aspectos de extensão/ponto de extensão e não contém mais IPluginDescriptors. Os usuários dessa API devem considerar o novo método getParentIdentifier() localizado em IExtension e IExtensionPoint.

ILibrary, IPluginDescriptor, IPluginRegistry e IPrerequisite (Pacote org.eclipse.core.runtime)

No tempo de execução original, o registro de plug-in mantinha uma imagem completa da configuração do tempo de execução. No Eclipse 3.0, essa imagem é dividida através da estrutura OSGi e o registro de extensão. Deste modo, essas classes foram reprovadas. Os avisos de reprovação contêm detalhes de como você deve atualizar o código.

Platform e Plugin (Pacote org.eclipse.core.runtime)

No novo tempo de execução, os objetos Plugin não são mais gerenciados pelo tempo de execução e, portanto, não podem ser acessados genericamente através de Platform. Da mesma forma, o registro do plug-in não existe mais ou fornece acesso aos descritores de plug-in. No entanto, há métodos de substituição adequados disponíveis e detalhados no Javadoc dos métodos reprovados nessas classes.

org.eclipse.core.runtime.model (Pacote org.eclipse.core.runtime.model)

Todos os tipos nesse pacote estão agora reprovados. Consulte a discussão sobreregistros para obter informações adicionais.

IWorkspaceRunnable e IWorkspace.run (Pacote org.eclipse.core.resources)

Clientes do método IWorkspace.run(IWorkspaceRunnable,IProgressMonitor) devem revisitar seus usos desse método é considerar o uso do método mais rico IWorkspace.run(IWorkspaceRunnable,ISchedulingRule,int,IProgressMonitor). O método IWorkspace.run antigo adquire uma trava sobre o espaço de trabalho inteiro durante o IWorkspaceRunnable. Isso significa que uma operação feita com esse método nunca poderá executar simultaneamente com outras operações que estão alterando o espaço de trabalho. No Eclipse 3.0, muitas operações de execução prolongada foram movidas para encadeamentos em segundo plano, portanto, a possibilidade de conflitos entre operações aumentou significativamente. Se uma operação modal em primeiro plano for bloqueada por uma operação de execução prolongada em segundo plano, a UI ficará bloqueada até a operação em segundo plano ser concluída ou até uma das operações ser cancelada.

A solução sugerida é trocar todas as referências para o IWorkspace.run antigo a fim de utilizar o novo método com um parâmetro de regra de planejamento. A regra de planejamento deve ser a regra mais detalhada que contém as regras para todas as alterações daquela operação. Se a operação tentar modificar os recursos fora do escopo da regra de planejamento, ocorrerá uma exceção de tempo de execução. A regra de planejamento precisa requerida por uma determinada operação de espaço de trabalho não é especificada e pode ser alterada dependendo do provedor de repositório instalado em um determinado projeto. O depósito de informações do provedor IResourceRuleFactory deve ser utilizado para obter a regra de planejamento para uma operação de alteração de recursos. Se desejar, um MultiRule pode ser utilizado para especificar várias regras de recursos e o método de conveniência MultiRule.combine pode ser utilizado para combinar regras de várias operações de alteração de recursos.

Se nenhuma trava for requerida, uma regra de planejamento de null poderá ser utilizada. Isso permitirá que o executável modifique todos os recursos no espaço de trabalho, mas não impedirá outros encadeamentos de modificar o espaço de trabalho simultaneamente. Para alterações simples no espaço de trabalho, freqüentemente essa é a solução mais fácil e simultaneamente amigável.

IWorkbenchPage (Pacote org.eclipse.ui)

IEditorDescriptor (Pacote org.eclipse.ui)

ISharedImages (Pacote org.eclipse.ui)

IWorkbenchActionConstants (Pacote org.eclipse.ui)

IWorkbenchPreferenceConstants (Pacote org.eclipse.ui)

IExportWizard (Pacote org.eclipse.ui)

IImportWizard (Pacote org.eclipse.ui)

INewWizard (Pacote org.eclipse.ui)

WorkbenchHelp (Pacote org.eclipse.ui.help)

IHelp (Pacote org.eclipse.help)

ITextEditorActionConstants (Pacote org.eclipse.ui.texteditor)

IAbstractTextEditorHelpContextIds (Pacote org.eclipse.ui.texteditor)

BasicTextEditorActionContributor (Pacote org.eclipse.ui.texteditor)

TextEditorActionContributor (Pacote org.eclipse.ui.editors.text)

Ponto de Extensão annotationTypes (Plug-in org.eclipse.ui.editors)

Agora há a noção explícita de um tipo de anotação. Consulte Annotation.getType() e Annotation.setType(). O tipo de uma anotação pode ser alterado através de seu tempo de vida. Um novo ponto de extensão foi incluído para a declaração dos tipos de anotação: "org.eclipse.ui.editors.annotationTypes". Um tipo de anotação tem um nome e pode ser declarado como sendo um subtipo de outro tipo de anotação declarado. Um tipo de anotação declarado também pode utilizar atributos "markerType" e "markerSeverity" para especificar que os marcadores de um determinado tipo e gravidade devem ser representados em editores de texto como anotações de um tipo de anotação específica. Os atributos"markerType" e "markerSeverity" no "org.eclipse.ui.editors.markerAnnotationSpecification" não devem mais ser utilizados. As especificações da anotação do marcador estão, dessa forma, tornando-se independentes dos marcadores e o nome está corrompido. No entanto, o nome é mantido para garantir compatibilidade reversa.

Instâncias da subclasse de AbstractMarkerAnnotationModel detectam automaticamente e definem os tipos de anotação corretos para anotações que eles criam a partir de marcadores. Para recuperar programaticamente o tipo de anotação para um determinado marcador ou determinado par de markerType e markerSeverity, utilize org.eclipse.ui.texteditor.AnnotationTypeLookup.

O acesso à hierarquia de tipos de anotação é fornecido por IAnnotationAccessExtension. Para um determinado tipo de anotação, você pode obter a cadeia de super tipos e verificar se um tipo de anotação é um subtipo de outro tipo de anotação. DefaultMarkerAnnotationAccess implementa essa interface.

Ponto de Extensão markerAnnotationSpecification (Plug-in org.eclipse.ui.editors)

O tipo de anotação é a chave com a qual irá localizar a especificação da anotação do marcador associado. Como os tipos de anotação podem estender outros tipos de anotação, também há uma relação implícita entre as especificações da anotação do marcador. Portanto, uma especificação da anotação do marcador para um determinado tipo de anotação é concluída pelas especificações da anotação do marcador fornecidas para os super tipos do determinado tipo de anotação. Portanto, a especificação da anotação do marcador não precisa ser concluída como era requerido anteriormente. As especificações da anotação do marcador são recuperadas por AnnotationPreferences. Ao utilizar org.eclipse.ui.texteditor.AnnotationPreferenceLookup, você pode recuperar uma preferência de anotação para um determinado tipo de anotação que executa transparentemente a conclusão da preferência junto com a cadeia de super tipos da anotação.

A especificação da anotação do marcador foi estendida com três atributos adicionais para permitir a definição de aparências personalizadas de um determinado tipo de anotação na régua vertical. Esses atributos são: "icon", "symbolicIcon" e "annotationImageProvider". O valor para "icon" é o caminho para um arquivo que contém a imagem do ícone. O valor de "symbolicIcon" pode ser "error", "warning", "info", "task", "bookmark". O atributo "symbolicIcon" é utilizado para informar à plataforma que a anotação deve ser representada com as mesmas imagens que foram utilizadas pela plataforma para apresentar erros, avisos, informações, tarefas e marcadores respectivamente. O valor de"annotationImageProvider" é uma classe que implementa org.eclipse.ui.texteditor.IAnnotationImageProvider que permite uma apresentação completa da anotação personalizada.

A régua vertical utiliza sua IAnnotationAccess/IAnnotationAccessExtension associada para retirar anotações. A régua vertical não chama mais Annotation.paint. Em geral, não se supõe mais que as Anotações retiram a si próprias. Os métodos "paint" e "getLayer" foram reprovados para tornar a anotação eventualmente independente da UI. DefaultMarkerAnnotationAccess serve como uma implementação padrão de IAnnotationAccess/IAnnotationAccessExtension. DefaultMarkerAnnotationAccess implementa a seguinte estratégia para anotações de pintura: Se uma anotação implementar IAnnotationPresentation, IAnnotationPresentation.paint será chamada. Senão, o provedor de imagem da anotação será procurado na preferência da anotação. O provedor de imagem da anotação também estará disponível se especificado e se o plug-in que define a especificação da anotação do marcador de fechamento já tiver sido carregado. Se houver um provedor de imagem da anotação, a chamada será redirecionada para ele. Senão, o "icon" especificado será procurado. "symbolicIcon" é utilizado como a emergência final. Para anotações de retirada, a camada de apresentação da anotação é pertinente. DefaultMarkerAnnotationAccess procura a camada de apresentação utilizando a seguinte estratégia: Se a preferência da anotação especificar uma camada de apresentação, a camada especificada será utilizada. Se não houver nenhuma camada e a anotação implementar IAnnotationPresentation, IAnnotationPresentation.getLayer será utilizado; caso contrário, a camada de apresentação padrão (que é 0) será retornada.

Migração para o Ponto de Extensão annotationTypes (Plug-in org.eclipse.ui.editors)

Os seguintes tipos de anotação são declarados pelo plug-in org.eclipse.ui.editors:

   <extension point="org.eclipse.ui.editors.annotationTypes">
      <type
         name="org.eclipse.ui.workbench.texteditor.error"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="2">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.warning"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="1">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.info"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="0">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.task"
         markerType="org.eclipse.core.resources.taskmarker">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.bookmark"
         markerType="org.eclipse.core.resources.bookmark">
      </type>
 </extension>

A extensão markerAnnotationSpecification defina não fornece mais os atributos "markerType" e "markerSeverity". Eles definem o atributo "symbolicIcon" com o valor de acordo. Dessa forma, MarkerAnnotation.paint e MarkerAnnotation.getLayer não são chamados mais, isto é, a substituição desses métodos não tem qualquer efeito. Os clientes afetados devem implementar IAnnotationPresentation.

ILaunchConfigurationType (Pacote org.eclipse.debug.core)

Com a introdução de modos de ativação extensíveis na 3.0, mais de um representante de ativação pode existir para um tipo de configuração de ativação. Os releases anteriores a 3.0 suportavam apenas um representante de ativação por tipo de configuração de ativação. O método ILaunchConfigurationType.getDelegate() é agora reprovado. O método getDelegate(String mode) deve ser utilizado em seu local para recuperar o representante de ativação para um modo de ativação específico. O método reprovado foi alterado para retornar o representante de ativação para o modo run.

ILaunchConfigurationTab e ILaunchConfigurationTabGroup (Pacote org.eclipse.debug.ui)

Grupos de guia de ativação e guias de ativação não são mais notificados quando uma ativação é concluída. O método launched(ILaunch) nas interfaces ILaunchConfigurationTab e ILaunchConfigurationTabGroup foi reprovado e não é mais chamado. Contar com esse método para ativar uma função sempre foi um problema, porque as guias existem apenas quando a ativação é executada a partir do diálogo de ativação. Além disso, com a introdução de ativação em segundo plano, esse método não pode mais ser chamado, porque o diálogo de ativação deve ser fechado antes do objeto de ativação resultante existir.

ILaunchConfigurationTab e AbstractLaunchConfigurationTab (Pacote org.eclipse.debug.ui)

Dois métodos foram incluídos na interface ILaunchConfigurationTab - activated e deactivated. Esses novos métodos de ciclo de vida são chamados ao entrar e sair de uma guia respectivamente. Implementações existentes de ILaunchConfigurationTab que a subclasse da classe abstrata forneceu através do plug-in de depuração (AbstractLaunchConfigurationTab) são binárias compatíveis porque os métodos são implementados na classe abstrata.

Em releases anteriores, uma guia enviava a mensagem initializeFrom quando ativada e performApply quando desativada. Dessa forma, a estrutura da guia de configuração de ativação fornecia comunicação entre guias através de uma configuração de ativação (atualizando a configuração com valores de atributo atuais quando a guia era fechada e atualizando a guia recém-entrada). No entanto, muitas guias não executam comunicação entre guias, isso pode ser ineficiente. Não havia também como distinguir entre uma guia sendo ativada e uma guia exibindo uma configuração de ativação selecionada pela primeira vez. Os métodos recém-incluídos permite que as guias distinguam entre ativação e inicialização e desativação e salvamento de valores atuais.

A implementação padrão de activated, fornecida pela guia abstrata, chama initializeFrom. E, a implementação padrão de deactivated, chama performApply. As guias que desejam obter vantagem da nova API devem substituir esses métodos, conforme requerido. Geralmente, para guias que não executam comunicação entre guias, a abordagem recomendada é reimplementar esses métodos para que não façam nada.

Tipo de Ponto de Extensão launchConfigurationTabGroup (Pacote org.eclipse.debug.ui)

Em releases anteriores, a troca era especificada em uma configuração de ativação, através dos atributos da configuração de ativação ATTR_TARGET_DEBUG_PERSPECTIVE e ATTR_TARGET_RUN_PERSPECTIVE. Com a inclusão de modos de ativação extensíveis na 3.0, essa abordagem não é mais escalável. A troca de perspectiva é agora especificada por tipo de configuração de ativação, modo de ativação que um tipo de configuração de ativação suporta. A API foi incluída em DebugUITools para definir e obter a perspectiva associada a um tipo de configuração de ativação para um modo de ativação específico.

Um elemento launchMode adicional e opcional foi incluído no ponto de extensão launchConfigurationTabGroup, permitindo que um grupo de guias contribuído especifique uma perspectiva padrão para um tipo e modo de configuração de ativação.

Na interface com o usuário do Eclipse, os usuários podem editar a perspectiva associada a um tipo de configuração de ativação, abrindo o diálogo de configuração de ativação e selecionando um nó de tipo de configuração de ativação na árvore (em vez de uma configuração individual). Uma guia é exibida permitindo que o usuário defina uma perspectiva com cada modo de ativação suportado.

[Apenas no JDT] IVMRunner (Pacote org.eclipse.jdt.launching)

Dois métodos foram incluídos na classe VMRunnerConfiguration para suportar a definição e a recuperação das variáveis de ambiente. Os implementadores de IVMRunner devem chamar VMRunnerConfiguration.getEnvironment() e transmitir aquele ambiente para a JVM executada. Clientes cujo uso DebugPlugin.exec(String[] cmdLine, File workingDirectory) podem fazer isso chamando DebugPlugin.exec(String[] cmdLine, File workingDirectory, String[] envp). Simplesmente transmitir o resultado de getEnvironment() é suficiente.

[Apenas no JDT] Classes VMRunnerConfiguration e Bootstrap Classes (Pacote org.eclipse.jdt.launching)

Em releases anteriores, o VMRunnerConfiguration tinha um atributo para descrever um caminho de inicialização. O atributo é uma coleta de Strings a ser especificada no argumento -Xbootclasspath. Três novos atributos foram incluídos no VMRunnerConfiguration para suportar JVMs que permitem a pré-anexação e anexação do caminho de inicialização. Os novos métodos/atributos incluídos são:

O atributo antigo, getBootClassPath(), ainda existe e contém um caminho completo equivalente àquele dos três novos atributos. No entanto,VMRunners que suporta as novas opções do caminho de inicialização deve obter vantagem dos novos atributos.

[Apenas no JDT] Suporte Aprimorado para Cópias de Trabalho (Pacote org.eclipse.jdt.core)

O recurso de cópia de trabalho do modelo Java foi retrabalhado na 3.0 para fornecer uma funcionalidade significativamente maior. Antes da 3.0, o modelo Java permitia a criação de cópias de trabalho individuais das unidades de compilação. As alterações puderam ser feitas na cópia de trabalho e depois consolidadas. Havia suporte para análise limitada de uma cópia de trabalho no contexto do restante do modelo Java. No entanto, não havia como essas análises levarem em conta mais de uma cópia de trabalho por vez.

As alterações na 3.0 possibilitam a criação e o gerenciamento de conjuntos de cópias de trabalho de unidades de compilação e a execução de análises na presença de todas as cópias de trabalho em um conjunto. Por exemplo, agora é possível para um cliente, como o JDT, refatorar a criação de cópias de trabalho para uma ou mais unidades de compilação, que estiverem considerando a modificação, e, em seguida, a resolução de referências de tipo entre as cópias de trabalho. Anteriormente, isso só era possível após as alterações nas cópias de trabalho da unidade de compilação serem consolidadas.

A API do modelo Java altera 2 maneiras para incluir esse suporte aprimorado:

(1) A funcionalidade anteriormente localiza em IWorkingCopy e herdada por ICompilationUnit foi consolidada em ICompilationUnit. A interface IWorkingCopy foi utilizada apenas nesse único lugar e gratuitamente mais geral do que precisava ser. Essa alteração simplifica a API. IWorkingCopy foi reprovado. Outros lugares na API em que IWorkingCopy é utilizado como um parâmetro ou tipo de resultado também foram reprovados; os métodos da API mencionam ICompilationUnit em vez de IWorkingCopy.

(2) A interface IBufferFactory foi substituída por WorkingCopyOwner. O suporte aprimorado para cópias de trabalho requer que haja um objeto que possua as cópias de trabalho. Embora IBufferFactory esteja no local correto, o nome não transmite adequadamente como o novo mecanismo de cópia de trabalho funciona. WorkingCopyOwner é muito mais sugestivo. Além disso,WorkingCopyOwner é declarado como uma classe abstrata em vez de uma interface, para permitir que a noção de proprietário da cópia de trabalho evolua no futuro. O único método em IBufferFactory é movido para WorkingCopyOwner sem ser afetado. WorkingCopyOwner não implementa IBufferFactory para esclarecer que IBufferFactory é uma coisa do passado. IBufferFactory foi reprovado. Outros lugares na API em que IBufferFactory aparece como um parâmetro ou tipo de resultado também foram reprovados; a substituição de métodos da API mencionam WorkingCopyOwner em vez de IBufferFactory.

Essas alterações não interrompem a compatibilidade binária.

Ao migrar, todas as referências para o tipo IWorkingCopy devem se referir a ICompilationUnit. A única implementação de IWorkingCopy também implementa ICompilationUnit, o que significa que os objetos do tipo IWorkingCopy podem ser seguramente distribuídos para ICompilationUnit.

Uma classe que implementa IBufferFactory precisará ser substituída por uma subclasse de WorkingCopyOwner. Embora WorkingCopyOwner não implemente o próprio IBufferFactory, será possível declarar a subclasse de WorkingCopyOwner que implementa IBufferFactory criando, dessa forma, uma ponte entre o antigo e o novo (IBufferFactory declara createBuffer(IOpenable) enquanto WorkingCopyOwner declara createBuffer(ICompilationUnit); ICompilationUnit estende IOpenable).

Como as alterações que envolvem IWorkingCopy e IBufferFactory são entrelaçadas, recomendamos lidar com ambos ao mesmo tempo. Os detalhes das reprovações são os seguintes:

Reestruturação do Plug-in org.eclipse.help

O plug-in org.eclipse.help, que continha APIs e pontos de extensão para contribuir e estender o sistema de ajuda, bem como exibir a ajuda, agora contém apenas APIs e pontos de extensão para contribuir e acessar os recursos de ajuda. Uma parte da implementação da UI de ajuda padrão contida nesse plug-in foi movida para um novo plug-in org.eclipse.help.base junto com APIs para estender a implementação. As APIs e o ponto de extensão para contribuir com a UI da Ajuda e exibir a ajuda foram movidos para o plug-in org.eclipse.ui. Essa reestruturação permite aos aplicativos mais flexibilidade com relação ao sistema de ajuda; a nova estrutura permite que aplicativos baseados no workbench genérico forneçam sua própria UI de Ajuda e/ou implementação de Ajuda ou omitam o sistema de ajuda inteiramente.

Como os pontos de extensão e os pacotes de API afetados são destinados apenas para uso pelo próprio sistema de ajuda, não é provável que os plug-ins existentes sejam afetados por essa alteração. Eles são incluídos aqui apenas devido à totalidade:

Nova API da UI de Procura

A nova API para implementar procuras personalizadas foi incluída na 3.0. A API original é reprovada na 3.0 e recomendamos que os clientes sejam transportados para a nova API nos pacotes org.eclipse.search.ui e org.eclipse.search.ui.text.

Os clientes precisarão criar implementações de ISearchQuery, ISearchResult e ISearchResultPage. A implementação ISearchResultPage deve então ser contribuída para o novo ponto de extensão org.eclipse.search.searchResultViewPages.

As implementações padrão para ISearchResult e ISearchResultPage são fornecidas no pacote org.eclipse.search.ui.text.

Mensagens Nulas em MessageBox e DirectoryDialog (Pacote org.eclipse.swt.widgets)

Antes da 3.0, chamar DirectoryDialog.setMessage(String string) ou MessageBox.setMessage(String string) do SWT com um valor nulo para a cadeia resultaria em um diálogo sem texto no título. Esse comportamento não era especificado (a transmissão de nulo nunca era permitida) e cria problemas com getMessage que não tem permissão para retornar nulo. Na 3.0, a transmissão de nulo agora resulta no lançamento de uma exceção IllegalArgumentException e as especificações foram alteradas para declarar isso, tornando-a visível na linha com o método em sua superclasse Dialog.setMessage. Se você utilizar Dialog.setMessage, assegure-se de que a cadeia transmitida não seja nunca nula. Simplesmente transmita uma cadeia vazia se desejar um diálogo sem texto no título.

Aprimorando o Feedback de Progresso Modal

O suporte a operações concorrentes requer formas mais sofisticadas de mostrar o progresso modal. Como parte do esforço de pronto atendimento, o suporte a progresso adicional foi implementado na classe IProgressService. A forma existente para mostrar progresso com o ProgressMonitorDialog ainda está funcionando. No entanto, para aprimorar a experiência do usuário, recomendamos migrar para o novo IProgressService.

O documento Showing Modal Progress in Eclipse 3.0 descreve como migrar para o novo IProgressService.

Grupos de Ação de Depuração Removidos

O ponto de extensão dos Grupos de Ação de Depuração (org.eclipse.debug.ui.debugActionGroups) foi removido. No Eclipse 3.0, o workbench introduziu suporte para Atividades através do ponto de extensão org.eclipse.platform.ui.activities. Esse suporte fornece tudo que os Grupos de Ação de Depuração forneciam e também é mais fácil de utilizar (ele suporta padrões em vez de especificar todas as ações exaustivamente) e tem uma API programática para suportá-lo. Se as referências ao ponto de extensão antigo não forem removidas, não ocorrerão falhas. Elas serão simplesmente ignoradas. Os fornecedores do produto são incentivados a utilizar o suporte de Atividades do workbench para associar ações do depurador específicas da linguagem a atividades específicas da linguagem (por exemplo, as ações de depuração do C++ poderão ser associadas a uma atividade chamada "Desenvolvendo C++").

BreakpointManager Pode Ser Desativado

IBreakpointManager agora define os métodos setEnabled(boolean) e isEnabled(). Quando o gerenciador do ponto de interrupção for desativado, os depuradores deverão ignorar todos os pontos de interrupção registrados. A plataforma de depuração também fornece um novo mecanismo do listener, IBreakpointManagerListener que permite que os clientes que se registram no gerenciador de ponto de interrupção sejam notificados quando sua autorização for alterada. A visualização Pontos de Interrupção chama essa API a partir de uma nova ação de comutação que permite que o usuário "Ignore Todos os Pontos de Interrupção". Os depuradores que não honrarem a autorização do gerneciador do ponto de interrupção aparecerão de alguma forma interrompidos se o usuário tentar utilizar esse recurso.

[Apenas no JDT] Participantes da Procura Java (Pacote org.eclipse.jdt.core.search)

As linguagem próximas a Java (como JSP, SQLJ, JWS, etc.) devem poder participar na procura Java. Particularmente, os implementadores de tais linguagens devem poder:

Tal implementador é chamado de participante da procura. Ele estende a classe SearchParticipant. Os participantes da procura são transmitidos para procurar consultas (consulte SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)).

Para indexar ou localizar correspondências, uma participantes da procura precisa definir uma subclasse de SearchDocument que possa recuperar o conteúdo do documento substituindo getByteContents() ou getCharContents(). Uma instância dessa subclasse é retornada em getDocument(String).

Um participante da procura que deseja indexar algum documento utilizará SearchParticipant.scheduleDocumentIndexing(SearchDocument, IPath) para planejar a indexação do determinado documento no índice especificado. Depois do documento estar pronto para ser indexado, a estrutura subjacente chamará SearchParticipant.indexDocument(SearchDocument, IPath). O participante da procura então obtém o conteúdo do documento, transmite-o e inclui entradas de índice utilizando SearchDocument.addIndexEntry(char[], char[]).

Depois da indexação ser concluída, será possível então consultar os índices e localizar as correspondências utilizando SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor). Primeiro, é perguntado a cada participante os índices necessários por essa consulta, utilizando SearchParticipant.selectIndexes(SearchPattern, IJavaSearchScope). Para cada entrada de índice que corresponde ao padrão determinado, um documento de procura é criado perguntado ao participante da procura (consulte getDocument(String)). Todos esses documentos são transmitidos para o participante da procura para que ele possa localizar as correspondências utilizando locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor). O participante da procura notifica o SearchRequestor das correspondências da procura, utilizando acceptSearchMatch(SearchMatch) e transmitindo uma instância da subclasse de SearchMatch.

Um participante da procura pode delegar parte de seu trabalho para o participante padrão da procura Java. Uma instância desse participante padrão é obtida utilizando SearchEngine.getDefaultSearchParticipant(). Por exemplo, quando for solicitado a localizar correspondências, um participante SQLJ pode criar documentos .java a partir de seus documentos .sqlj e delegar o trabalho para o participante padrão transmitindo-o para os documentos .java.