Cambios necesarios al adoptar los mecanismos y las API de la versión 3.0

Esta sección describe los cambios que deben realizarse si intenta cambiar el conector 2.1 para adoptar los mecanismos y las API de 3.0.

Abandonar org.eclipse.core.runtime.compatibility

El entorno de ejecución de Eclipse 3.0 es significativamente diferente. La implementación subyacente se basa en la especificación de la infraestructura OSGi. El entorno de ejecución de Eclipse 3.0 incluye una capa de compatibilidad (en el conector org.eclipse.core.runtime.compatibility) que conserva las API de la versión 2.1. Los desarrolladores de conectores interesados en rendimiento y funciones adicionales deben considerar la posibilidad de adoptar las API de la versión 3.0 y eliminar sus dependencias de la capa de compatibilidad. El código de compatibilidad aparece en tres lugares:

El texto que figura a continuación ofrece más detalles acerca de las clases y métodos que están presentes a efectos de compatibilidad, así como una guía para la actualización del conector.

Conectores y paquetes compuestos

El entorno de ejecución de Eclipse se ha dividido en dos componentes: gestión de carga de clases y de prerrequisitos, por un lado, y gestión de extensiones y puntos de extensión, por otro. Esta división permite una adopción natural y fluida de la especificación de infraestructura OSGi para la gestión de la carga de clases y los prerrequisitos. A su vez, esto permite diversas posibilidades nuevas en el entorno de ejecución, desde la instalación, actualización y desinstalación dinámica de conectores a la seguridad y configurabilidad mejorada.

Aunque seguiremos hablando de conectores, en el nuevo entorno de ejecución un conector es en realidad un paquete compuesto más algunas extensiones y puntos de extensión. La especificación de infraestructura OSGi define el término paquete compuesto, que hace referencia a una colección de tipos y recursos e información de los prerrequisitos interpaquetes asociados. El registro de extensiones es el nuevo formato del registro de conectores y detalle sólo información de extensiones y puntos de extensión. En gran parte, la API de registro de extensiones es la misma que la API de registro de conector en cuestión (para obtener más información, consulte la sección Registros).

En el entorno de ejecución de Eclipse 2.x, el objeto de conector tiene diversos cometidos y responsabilidades:

En la infraestructura del entorno de ejecución de Eclipse 3.0, estos cometidos y responsabilidades se agrupan en objetos diferentes.

Paquete compuesto
Los paquetes compuestos son la unidad de modularidad de OSGi. Existe un cargador de clases por paquete compuesto y pueden construirse gráficos de dependencias de carga de clases interpaquetes de tipo Eclipse. Los paquetes compuestos tienen un ciclo de vida para el inicio y la detención y la infraestructura de OSGi distribuye los eventos relacionados con los paquetes compuestos (por ejemplo, instalación, resolución, inicio, detención, desinstalación, etc.) a las partes interesadas. A diferencia de la clase Plugin de Eclipse, la clase Bundle de OSGi no es ampliable. Es decir, los desarrolladores no tienen la oportunidad de definir su propia clase de paquete compuesto.
BundleActivator
BundleActivator es una interfaz definida por la infraestructura de OSGi. Cada paquete compuesto puede definir una clase de activador de paquetes compuestos de forma muy similar a cómo un conector puede definir su propia clase Plugin. La infraestructura crea una instancia de la clase especificada y la utiliza para implementar el proceso de ciclo de vida de start() y stop(). Sin embargo, existe una diferencia principal en la naturaleza de este proceso del ciclo de vida. En Eclipse, es habitual (aunque no aconsejable) que las clases Plugin realicen tanto la inicialización como el registro. En OSGi, los activadores sólo deben realizar el registro. La realización de grandes cantidades de trabajo de inicialización (o de cualquier otro trabajo) en BundleActivator.start() pone en peligro la vida del sistema.
BundleContext
Los BundleContexts (contextos de paquete compuesto) son el mecanismo de OSGi para exponer funciones generales del sistema a paquetes compuestos individuales. Cada paquete compuesto tiene una instancia exclusiva y privada de BundleContext que puede utilizar para acceder a funciones del sistema (por ejemplo, getBundles() para descubrir todos los paquetes compuestos del sistema).
Plugin
la nueva clase Plugin es muy parecida a la clase Plugin original de Eclipse, con las siguientes excepciones: el entorno de ejecución ya no requiere ni gestiona objetos Plugin, y varios métodos han quedado obsoletos. El hecho de suministrar al sistema principal de funciones y mecanismo útiles es básicamente un mecanismo de conveniencia, pero ya no es absolutamente necesario. Muchas de las funciones suministradas allí también están disponibles en la clase Platform del entorno de ejecución.

Plugin también implementa BundleActivator. Éste reconoce la conveniencia de contar con un objeto central que represente el ciclo de vida y la semántica de un conector. Sin embargo, tenga en cuenta que esto no autoriza la inicialización excesiva de estructuras de datos que es común hoy en día en los conectores. Debemos hacer especial hincapié en que los conectores pueden activarse debido a que se ha hecho referencia a algún tipo de clase periférica durante la verificación de una clase en algún otro conector. Es decir, sólo porque el conector se haya activado no significa necesariamente que su función sea necesaria. Tenga en cuenta también que tiene libertad para definir una clase BundleActivator diferente o no tener ningún activador de paquetes compuestos en absoluto.

Los pasos necesarios para portar una clase Plugin del release 2.1 a Eclipse 3.0 dependen de lo que realice la clase. Como se ha indicado anteriormente, la mayor parte del trabajo de ciclo de vida correspondiente al inicio se agrupa en una de las siguientes categorías:

Inicialización
La inicialización de estructuras de datos y modelos se realiza con frecuencia en Plugin.startup(). La correlación natural/obvia sería realizar este trabajo en un BundleActivator.start(), es decir, dejar la función en Plugin. Esto se desaconseja explícitamente. Como los conectores 2.x, los conectores/paquetes compuestos de 3.0 pueden iniciarse por muy diversas razones en muy diversas circunstancias.
Un ejemplo real de los tiempos de Eclipse 2.0 ilustra este caso. Existía un conector que inicializaba un modelo grande que requería la carga de 11 MB de código y muchos megabytes de datos. En casos muy habituales, este conector se activaba para descubrir si el icono de proyecto presentado en el navegador debía decorarse con un código determinado. Esta prueba no requería ninguna de la inicialización realizada en startup(), pero aún así todos los usuarios tenían que pagar en todos los casos la penalización de memoria y tiempo de esta inicialización excesiva.
El sistema alternativo consiste en realizar esta inicialización en un estilo diferido clásico. Por ejemplo, en lugar de inicializar los modelos cuando se activa el conector/paquete compuesto, hágalo cuando sean realmente necesarios (por ejemplo, en un método accesor de modelo centralizado). En muchos casos, esto conducirá prácticamente al mismo punto temporal, pero en otros este sistema diferirá la inicialización (quizás indefinidamente). Es aconsejable tomarse un tiempo al portar conectores 2.1 para reconsiderar la estrategia de inicialización utilizada.
Registro
El inicio del conector es un momento adecuado para registrar escuchadores, servicios, etc. e iniciar hebras de proceso en segundo plano (por ejemplo, la escucha en un socket). Plugin.start() puede ser un lugar adecuado para realizar este trabajo. También puede tener sentido diferirlo hasta que se activa algún otro (por ejemplo, la utilización de una función o elemento de datos determinado).
Datos globales de conector
La clase Plugin puede seguir desempeñando este papel. El problema principal es que los objetos Plugin ya no son globalmente accesibles por medio de una lista gestionada por el sistema. En Eclipse 2.x, se podía descubrir el objeto Plugin de cualquier conector por medio del registro de conectores. Esto ya no es posible. En la mayoría de los casos, este tipo de acceso no es necesario. Los conectores a los que se accede por medio del registro se utilizan más habitualmente como conectores genéricos en lugar de llamar a métodos específicos del dominio. Puede obtenerse el nivel de capacidad equivalente accediendo a los objetos Bundle correspondientes y manipulándolos.

Los registros y el modelo de conector

En el nuevo entorno de ejecución, existe una separación entre la información y las estructuras necesarias para ejecutar un conector, por un lado, y los elementos relacionados con las extensiones y puntos de extensión de un conector, por otro. La especificación de la infraestructura OSGi define y gestiona la primera parte indicada. La segunda consiste en conceptos específicos de Eclipse y los añade el código del entorno de ejecución de Eclipse. De cuerdo con esto, el registro de conectores original y los objetos relacionados se han divido en paquetes compuestos OSGi y el registro de extensiones de Eclipse.

Los componentes de IPluginRegistry relacionados con la especificación de ejecución (por ejemplo, IPluginDescriptor, ILibrary, IPrequisite) han quedado obsoletos y el resto de componentes relacionados con extensiones y puntos de extensión se han transferido a IExtensionRegistry. Además, los así llamados objetos de modelo relacionados con el registro de conectores en conjunto han quedado obsoletos. El entorno de ejecución presentaba y creaba instancias de estos tipos principalmente para dar soporte a herramientas tales como el PDE. Desgraciadamente, se daba con frecuencia el caso de que el nivel de información necesaria sobrepasaba las posibilidades o intereses del entorno de ejecución (por ejemplo, recordar números de línea para elementos plugin.xml) y, finalmente, los consumidores potenciales de la información del entorno de ejecución tenían que mantener de todas formas sus propias estructuras.

En el nuevo entorno de ejecución, se han reevaluado los recursos suministrados por éste y ahora sólo se proporcionan aquellos recursos que son esenciales para la ejecución del entorno de ejecución o que son extraordinariamente difíciles de realizar para otros. Como se ha indicado anteriormente, los objetos de modelo de registro de conectores han quedado obsoletos, al igual que la API de análisis de conectores. El nuevo registro de extensiones mantiene la información esencial relacionada con las extensiones. Una nueva estructura de estado (consulte org.eclipse.osgi.service.resolver.State y allegados) representa la información esencial relacionada con la ejecución y permite manipularla.

Estructura de fragmentos NL

En Eclipse 3.0, se ha actualizado la estructura de fragmentos NL para que sea más coherente. Anteriormente, se presuponía que las traducciones de archivos tales como plugin.properties se encontraban dentro de archivos JAR suministrados por fragmentos. Dado que los archivos originales se encuentran en el directorio raíz del conector de sistema principal en cuestión, sería más coherente ubicar los archivos traducidos en el directorio raíz de los fragmentos NL. Por ejemplo,

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

Tenga en cuenta que el archivo nl1.jar hubiera contenido anteriormente las traducciones de plugin.properties. Estos archivos se encuentran ahora en el directorio raíz del fragmento y el JAR contiene las traducciones de los recursos traducibles (es decir, de los archivos cargados por medio del cargador de clases) en el conector de sistema principal.

Evidentemente, la estructura de fragmentos NL de Eclipse 2.1 sigue estando soportada para los conectores de sistema principal 2.1 ejecutados en Eclipse 3.0. Sin embargo, no puede utilizar un fragmento NL 2.1 en un conector 3.0. El fragmento debe actualizarse a la estructura nueva.

Visión general de los cambios de API

org.eclipse.core.boot (paquete org.eclipse.core.boot)

Todo el paquete org.eclipse.core.boot ha quedado obsoleto. BootLoader se ha fusionado con org.eclipse.core.runtime.Platform, dado que ya no tiene sentido mantener una división entre el arranque y el tiempo de ejecución. Tenga en cuenta que, de hecho, el conector org.eclipse.core.boot se ha dividido y todo su código se ha transferido al nuevo entorno de ejecución o a la capa de compatibilidad.

IPlatformConfiguration siempre ha sido un tipo definido por y para el componente de Instalación/Actualización de Eclipse. Con la reorganización del entorno de ejecución, estamos en condiciones de repatriar este tipo a su ubicación inicial. Esta clase permanece prácticamente sin cambios y se ha reempaquetado como org.eclipse.update.configurator.IPlatformConfiguration.

IPlatformRunnable se ha transferido a org.eclipse.core.runtime.IPlatformRunnable.

IExtension y IExtensionPoint (paquete org.eclipse.core.runtime)

El método getDeclaringPlugin() (de ambas clases) proporciona un enlace de subida al conector que declara la extensión o punto de extensión (respectivamente). El nuevo modelo de registro separa los aspectos de ejecución de los conectores de los aspectos de extensiones y puntos de extensión y ya no contiene IPluginDescriptors. Los usuarios de esta API deben considerar la posibilidad de utilizar el nuevo método getParentIdentifier(), que se encuentra tanto en IExtension como en IExtensionPoint.

ILibrary, IPluginDescriptor, IPluginRegistry y IPrerequisite (paquete org.eclipse.core.runtime)

En el entorno de ejecución original, el registro de conectores mantenía una imagen completa de la configuración del entorno de ejecución. En Eclipse 3.0, esta imagen se ha dividido entre la infraestructura OSGi y el registro de extensiones. Por tanto, estas clases han quedado obsoletas. Los avisos de obsolescencia contienen detalles relativos a la actualización del código.

Platform y Plugin (paquete org.eclipse.core.runtime)

En el nuevo entorno de ejecución, el entorno de ejecución ya no gestiona los objetos Plugin y, por tanto, no puede accederse a ellos genéricamente por medio de Platform. De modo similar, el registro de conectores ya no existe ni da acceso a descriptores de conector. Sin embargo, existen métodos sustitutivos adecuados disponibles que se detallan en el Javadoc de los métodos obsoletos de estas clases.

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

Todos los tipos de este paquete han quedado obsoletos. Consulte la descripción de los registros para obtener más información.

IWorkspaceRunnable y IWorkspace.run (paquete org.eclipse.core.resources)

Los clientes del método IWorkspace.run(IWorkspaceRunnable,IProgressMonitor) deben revisar su utilización de este método y considerar la posibilidad de utilizar el método IWorkspace.run(IWorkspaceRunnable,ISchedulingRule,int,IProgressMonitor), más rico. El método antiguo IWorkspace.run adquiere un bloqueo sobre toda el área de trabajo durante la duración de IWorkspaceRunnable. Esto significa que una operación realizada con este método nunca podrá ejecutarse simultáneamente a otras operaciones que cambien el área de trabajo. En Eclipse 3.0, muchas operaciones de larga ejecución se han transferido a hebras de segundo plano, y con ello ha aumentado mucho la posibilidad de conflictos entre operaciones. Si una operación de larga ejecución en segundo plano bloquea una operación modal en primer plano, la UI queda bloqueada hasta que la operación de segundo plano finaliza o hasta que se cancela una de las operaciones.

La solución sugerida consiste en conmutar todas las referencias al IWorkspace.run antiguo para utilizar el método nuevo con un parámetro de norma de planificación. La norma de planificación debe ser la de grano más fino (la más concreta) que abarque las normas de todos los cambios realizados por esa operación. Si la operación intenta modificar recursos situados fuera del ámbito de la norma de planificación, se producirá una excepción de ejecución. La norma de planificación precisa necesaria para una operación determinada del área de trabajo no se especifica, y puede cambiar en función del proveedor de repositorios instalado en un proyecto dado. Debe utilizarse la fábrica IResourceRuleFactory para obtener la norma de planificación de una operación de cambio de recurso. Si lo desea, puede utilizarse una MultiRule (multinorma) para especificar varias normas de recurso y el método de conveniencia MultiRule.combine para combinar normas de varias operaciones de cambio de recurso.

Si no es necesario ningún bloqueo, puede utilizarse una norma de planificación nula. Esto permitirá al ejecutable modificar todos los recursos del área de trabajo, pero no evitará que otras hebras también modifiquen el área de trabajo simultáneamente. Para realizar cambios sencillos en el área de trabajo, esta es con frecuencia la solución más fácil y adecuada a los aspectos de simultaneidad.

IWorkbenchPage (paquete org.eclipse.ui)

IEditorDescriptor (paquete org.eclipse.ui)

ISharedImages (paquete org.eclipse.ui)

IWorkbenchActionConstants (paquete org.eclipse.ui)

IWorkbenchPreferenceConstants (paquete org.eclipse.ui)

IExportWizard (paquete org.eclipse.ui)

IImportWizard (paquete org.eclipse.ui)

INewWizard (paquete org.eclipse.ui)

WorkbenchHelp (paquete org.eclipse.ui.help)

IHelp (paquete org.eclipse.help)

ITextEditorActionConstants (paquete org.eclipse.ui.texteditor)

IAbstractTextEditorHelpContextIds (paquete org.eclipse.ui.texteditor)

BasicTextEditorActionContributor (paquete org.eclipse.ui.texteditor)

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

Punto de extensión annotationTypes (conector org.eclipse.ui.editors)

Ahora existe la noción explícita de tipo de anotación. Consulte Annotation.getType() y Annotation.setType(). El tipo de una anotación puede cambiar a lo largo de su ciclo de vida. Se ha añadido un punto de extensión nuevo para la declaración de tipos de anotación: "org.eclipse.ui.editors.annotationTypes". Un tipo de anotación tiene un nombre y puede declararse como subtipo de otro tipo de anotación declarado. Una declaración de tipo de anotación también puede utilizar los atributos "markerType" y "markerSeverity" a fin de especificar que los marcadores de un tipo y una gravedad determinados deben representarse en los editores de texto como anotaciones de un tipo determinado. Los atributos "markerType" y "markerSeverity" de "org.eclipse.ui.editors.markerAnnotationSpecification" ya no deben utilizarse. Por tanto, las especificaciones de anotaciones de marcador pasan a ser independientes de los marcadores y el nombre puede ser engañoso. Sin embargo, se conserva para garantizar la compatibilidad hacia atrás.

Las instancias de subclases de AbstractMarkerAnnotationModel detectan automáticamente los tipos de anotación correctos de las anotaciones que crean a partir de los marcadores. Para poder recuperar programáticamente el tipo de anotación de un marcador determinado o un par de markerType y markerSeverity, utilice org.eclipse.ui.texteditor.AnnotationTypeLookup.

IAnnotationAccessExtension proporciona acceso a la jerarquía de tipos de anotación. Para un tipo de anotación determinado, puede obtener la cadena de supertipos y comprobar si un tipo de anotación es un subtipo de otro tipo de anotación. DefaultMarkerAnnotationAccess implementa esta interfaz.

Punto de extensión markerAnnotationSpecification (conector org.eclipse.ui.editors)

El tipo de anotación es la clave con la que se busca la especificación de anotación de marcador asociada. Dado que los tipos de anotación pueden ampliar otros tipos de anotación, existe también una relación implícita entre las especificaciones de anotación de marcador. Por tanto, una especificación de anotación de marcador de un tipo de anotación determinado se completa con la especificaciones de anotación de marcador dadas para los supertipos del tipo de anotación en cuestión. En consecuencia, la especificación de anotación de marcador no tiene que estar completa como era necesario anteriormente. AnnotationPreferences recupera las especificaciones de anotación de marcador. Mediante org.eclipse.ui.texteditor.AnnotationPreferenceLookup, puede recuperar una preferencia de anotación de un tipo de anotación determinado que completa de forma transparente la preferencia junto con la cadena de supertipos de anotación.

la especificación de anotación de marcador se ha ampliado con tres atributos adicionales para permitir la definición de apariciones personalizadas de un tipo de anotación determinado en la regla vertical. Estos atributos son: "icon", "symbolicIcon" y "annotationImageProvider". El valor de "icon" es la vía de acceso al archivo que contiene la imagen del icono. El valor de "symbolicIcon" puede ser "error", "warning", "info", "task", "bookmark". El atributo "symbolicIcon" se utiliza para indicar a la plataforma que la anotación debe representarse con las mismas imágenes utilizadas por la plataforma para presentar errores, avisos, informaciones, tareas y favoritos, respectivamente. El valor de "annotationImageProvider" es una clase que implementa org.eclipse.ui.texteditor.IAnnotationImageProvider que permite una presentación de anotación personalizada completa.

La regla vertical utiliza su IAnnotationAccess/IAnnotationAccessExtension asociada para dibujar las anotaciones. La regla vertical ya no llama a Annotation.paint. En general, ya no se presupone que las anotaciones deban dibujarse a sí mismas. Los métodos "paint" y "getLayer" han quedado obsoletos para que las anotaciones sean a fin de cuentas independientes de la UI. DefaultMarkerAnnotationAccess actúa como implementación por omisión de IAnnotationAccess/IAnnotationAccessExtension. DefaultMarkerAnnotationAccess implementa la siguiente estrategia para representar anotaciones: si una anotación implementa IAnnotationPresentation, se llama a IAnnotationPresentation.paint. En caso contrario, se busca el proveedor de imágenes de anotación en la preferencia de anotación. El proveedor de imágenes de anotación sólo está disponible si está especificado y si ya se ha cargado el conector que define la especificación de anotación de marcador que lo incluye. Si existe un proveedor de imágenes de anotación, la llamada se reenvía a éste. En caso contrario, se busca el atributo "icon" especificado. El atributo "symbolicIcon" se utiliza como solución de emergencia. Para dibujar las anotaciones es importante la capa de presentación de anotaciones. DefaultMarkerAnnotationAccess busca la capa de presentación mediante la siguiente estrategia: si la preferencia de anotación especifica una capa de presentación, se utiliza ésta. Si no hay ninguna capa y la anotación implementa IAnnotationPresentation, se utiliza IAnnotationPresentation.getLayer; de lo contrario, se devuelve la capa de presentación por omisión (que es 0).

Migración al punto de extensión annotationTypes (conector org.eclipse.ui.editors)

El conector org.eclipse.ui.editors declara los siguientes tipos de anotación:

   <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>

La extensión markerAnnotationSpecification definida ya no proporciona los atributos "markerType" y "markerSeverity". Definen el atributo "symbolicIcon" con el valor correspondiente. Por tanto, ya no se llama a MarkerAnnotation.paint y MarkerAnnotation.getLayer, es decir, la alteración temporal de estos métodos no tiene efecto alguno. Los clientes afectados deben implementar IAnnotationPresentation.

ILaunchConfigurationType (paquete org.eclipse.debug.core)

Con la introducción de modalidades de lanzamiento ampliables en el release 3.0, puede existir más de un delegado de lanzamiento para un tipo de configuración de lanzamiento. Los releases anteriores a 3.0 sólo daban soporte a un delegado de lanzamiento por tipo de configuración de lanzamiento. El método ILaunchConfigurationType.getDelegate() ha quedado obsoleto. En su lugar, debe utilizarse el método getDelegate(String mode) para recuperar el delegado de lanzamiento de una modalidad de lanzamiento determinada. El método obsoleto se ha cambiado para que devuelva el delegado de lanzamiento de la modalidad run.

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

Los grupos de pestañas de lanzamiento y las pestañas de lanzamiento ya no reciben notificación cuando finaliza un lanzamiento. El método launched(ILaunch) de las interfaces ILaunchConfigurationTab e ILaunchConfigurationTabGroup ha quedado obsoleto y ya no se invoca. El hecho de confiar en este método para lanzar funciones era siempre problemático, ya que las pestañas sólo existen cuando el lanzamiento se realiza desde el diálogo de lanzamiento. Asimismo, con la introducción del lanzamiento en segundo plano, ya no puede llamarse a este método, dado que el diálogo de lanzamiento debe cerrarse antes de que exista el objeto de lanzamiento resultante.

ILaunchConfigurationTab y AbstractLaunchConfigurationTab (paquete org.eclipse.debug.ui)

Se han añadido dos métodos a la interfaz ILaunchConfigurationTab - activated y deactivated. Estos nuevos métodos de ciclo de vida se invocan cuando se entra y sale de una pestaña, respectivamente. Las implementaciones existentes de ILaunchConfigurationTab que crean subclases de la clase abstracta suministrada por el conector de depuración (AbstractLaunchConfigurationTab) son compatibles binarios, ya que los métodos se implementan en la clase abstracta.

En releases anteriores, se enviaba a la pestaña el mensaje initializeFrom cuando se activaba y performApply cuando se desactivaba. De ese modo, la infraestructura de pestañas de configuración de lanzamiento suministraba la comunicación entre pestañas por medio de una configuración de lanzamiento (actualizando la configuración con los valores de atributo actuales cuando se salía de una pestaña, y actualizando la pestaña en la que se acababa de entrar). Sin embargo, puesto que muchas pestañas no establecen comunicación entre pestañas, este proceso puede ser ineficaz. Tampoco existía ningún modo de distinguir entre una pestaña que se activaba y una pestaña que visualizaba una configuración de lanzamiento seleccionada por primera vez. Los métodos nuevos añadidos permiten a las pestañas distinguir entre activación e inicialización, por un lado, y desactivación y guardado de los valores actuales, por otro.

La implementación por omisión de activated, suministrada por la pestaña abstracta, llama a initializeFrom. Y la implementación por omisión de deactivated llama a performApply. Las pestañas que deseen aprovechar la nueva API deben alterar temporalmente estos métodos según convenga. Generalmente, para las pestañas que no establecen comunicación entre pestañas el procedimiento recomendado consiste en reimplementar estos métodos sin que realicen ninguna acción.

Tipo de punto de extensión launchConfigurationTabGroup (paquete org.eclipse.debug.ui)

En releases anteriores, la conmutación de perspectiva se especificaba en una configuración de lanzamiento por medio de loa atributos de configuración de lanzamiento ATTR_TARGET_DEBUG_PERSPECTIVE y ATTR_TARGET_RUN_PERSPECTIVE. Con la adición de modalidades de lanzamiento ampliables en el release 3.0, este procedimiento ya no es escalable. La conmutación de perspectivas se especifica ahora en función del tipo de configuración de lanzamiento, según la modalidad de lanzamiento soportada por el tipo de configuración de lanzamiento. Se ha añadido una API a DebugUITools para establecer y obtener la perspectiva asociada con un tipo de configuración de lanzamiento de una modalidad de lanzamiento específica.

Se ha añadido el elemento opcional launchMode al punto de extensión launchConfigurationTabGroup, que permite a un grupo de pestañas añadido especificar una perspectiva por omisión para un tipo y modalidad de configuración de lanzamiento.

Desde la interfaz de usuario de Eclipse, los usuarios pueden editar la perspectiva asociada con un tipo de configuración de lanzamiento abriendo el diálogo de configuraciones de lanzamiento y seleccionando un nodo de tipo de configuración de lanzamiento en el árbol (en lugar de una configuración individual). Se visualiza una pestaña que permite al usuario establecer una perspectiva con cada modalidad de lanzamiento soportada.

[Sólo JDT] IVMRunner (paquete org.eclipse.jdt.launching)

Se han añadido dos métodos a la clase VMRunnerConfiguration para dar soporte al establecimiento y recuperación de variables de entorno. Los implementadores de IVMRunner deben llamar a VMRunnerConfiguration.getEnvironment() y pasar ese entorno en la JVM ejecutada. Los clientes que utilicen DebugPlugin.exec(String[] cmdLine, File workingDirectory) pueden hacerlo llamando en su lugar a DebugPlugin.exec(String[] cmdLine, File workingDirectory, String[] envp). Es suficiente con pasar el resultado de getEnvironment().

[Sólo JDT] VMRunnerConfiguration y clases Bootstrap (paquete org.eclipse.jdt.launching)

En releases anteriores, VMRunnerConfiguration tenía un atributo para describir una vía de acceso de arranque. El atributo es una colección de Strings que deben especificarse en el argumento -Xbootclasspath. Se han añadido tres atributos nuevos a VMRunnerConfiguration para dar soporte a las JVM que permiten realizar adiciones al principio y al final de la vía de acceso de arranque. Los nuevos métodos/atributos añadidos son:

El atributo antiguo, getBootClassPath(), sigue existiendo y contiene una vía de acceso completo equivalente a la de los nuevos atributos del árbol. Sin embargo, los VMRunners que dan soporte a las nuevas opciones de vía de acceso de arranque deben aprovechar los nuevos atributos.

[Sólo JDT] Soporte mejorado para copias de trabajo (paquete org.eclipse.jdt.core)

El recurso de copia de trabajo del modelo Java se ha reestructurado en el release 3.0 para suministrar funciones muy mejoradas. Antes de 3.0, el modelo Java permitía la creación de copias de trabajo individuales de unidades de compilación. Podían realizarse cambios en la copia de trabajo y comprometerse más tarde. Existía soporte para el análisis limitado de una copia de trabajo en el contexto del resto del modelo Java. Sin embargo, no había forma de que estos análisis pudieran tener en cuenta más de una de las copias de trabajo a la vez.

Los cambios realizados en 3.0 hacen posible crear y gestionar conjuntos de copias de trabajo de unidades de compilación y realizar análisis en presencia de todas las copias de trabajo de un conjunto. Por ejemplo, ahora es posible que un cliente como la reestructuración de JDT cree copias de trabajo para una o varias unidades de compilación que considere modificadas y a continuación resuelva las referencias de tipo entre las copias de trabajo. Anteriormente, esto sólo era posible después de comprometer los cambios realizados en las copias de trabajo de la unidad de compilación.

La API de modelo Java ha cambiado de 2 formas para añadir este soporte mejorado:

(1) Las funciones que se encontraban anteriormente en IWorkingCopy y que ICompilationUnit heredaba se han consolidado en ICompilationUnit. La interfaz IWorkingCopy sólo se utilizaba en ese lugar y era más general de lo necesario sin necesidad. Este cambio simplifica la API. IWorkingCopy ha quedado obsoleto. Otros lugares de la API donde IWorkingCopy se utiliza como parámetro o tipo de resultado también han quedado obsoletos; los métodos de API de sustitución indican ICompilationUnit en lugar de IWorkingCopy.

(2) La interfaz IBufferFactory se ha sustituido por WorkingCopyOwner. El soporte mejorado para las copias de trabajo requiere que exista un objeto propietario de las copias de trabajo. Aunque IBufferFactory está en el lugar adecuado, el nombre no indica adecuadamente cómo funciona el nuevo mecanismo de copias de trabajo. WorkingCopyOwner es mucho más significativo. Además, WorkingCopyOwner se declara como clase abstracta, en lugar de como interfaz, para permitir que él concepto de propietario de copia de trabajo evolucione en el futuro. El método de IBufferFactory se transfiere a WorkingCopyOwner sin cambios. WorkingCopyOwner no implementa IBufferFactory para dejar claro que IBufferFactory es cosa del pasado. IBufferFactory ha quedado obsoleto. Otros lugares de la API donde IBufferFactory aparece como parámetro o tipo de resultado también han quedado obsoletos; los métodos de API de sustitución indican WorkingCopyOwner en lugar de IBufferFactory.

Estos cambios no interrumpen la compatibilidad binaria.

Al realizar la migración, todas las referencias al tipo IWorkingCopy deben hacer referencia a ICompilationUnit. La única implementación de IWorkingCopy implementa también ICompilationUnit, lo que significa que los objetos de tipo IWorkingCopy pueden convertirse temporalmente de forma segura a ICompilationUnit.

Una clase que implemente IBufferFactory deberá sustituirse por una subclase de WorkingCopyOwner. Aunque WorkingCopyOwner no implementa IBufferFactory por sí mismo, es posible declarar la subclase de WorkingCopyOwner que implementa IBufferFactory, creando así un puente entre antiguo y nuevo (IBufferFactory declara createBuffer(IOpenable), mientras que WorkingCopyOwner declara createBuffer(ICompilationUnit); ICompilationUnit amplía IOpenable).

Dado que los cambios que implican a IWorkingCopy y IBufferFactory están interrelacionados, es aconsejable tratarlos al mismo tiempo. Los detalles de los elementos obsoletos son los siguientes:

Reestructuración del conector org.eclipse.help

El conector org.eclipse.help, utilizado para contener API y puntos de extensión para efectuar adiciones y ampliar el sistema de ayuda, así como para visualizar la ayuda, ahora sólo contiene las API y puntos de extensión para efectuar adiciones y acceder a recursos de la ayuda. Una parte de la implementación de la UI de ayuda por omisión contenida en ese conector se ha transferido al conector nuevo org.eclipse.help.base, junto con las API destinadas a ampliar la implementación. Las API y puntos de extensión destinados a efectuar adiciones a la UI de ayuda y a visualizar la ayuda se han transferido al conector org.eclipse.ui. Esta reestructuración permite a las aplicaciones una mayor flexibilidad con respecto al sistema de ayuda; la nueva estructura permite que las aplicaciones basadas en el entorno de trabajo genérico suministren su propia UI de ayuda y/o implementación de ayuda, o que omitan por completo el sistema de ayuda.

Debido a que los paquetes de puntos de extensión y API afectados sólo están destinados al uso del propio sistema de ayuda, no es probable que los conectores existentes resulten afectados por este cambio. Se incluyen aquí sólo para que la información sea completa:

Nueva API de UI de búsqueda

Una nueva API destinada a implementar búsquedas personalizadas se ha añadido al release 3.0. La API original ha quedado obsoleta en 3.0 y es aconsejable que los clientes migren a la API nueva en los paquetes org.eclipse.search.ui y org.eclipse.search.ui.text.

Los clientes deberán crear implementaciones de ISearchQuery, ISearchResult y ISearchResultPage. A continuación, la implementación de ISearchResultPage debe añadirse al nuevo punto de extensión org.eclipse.search.searchResultViewPages.

Las implementaciones por omisión de ISearchResult y ISearchResultPage se suministran en el paquete org.eclipse.search.ui.text.

mensajes nulos en MessageBox y DirectoryDialog (paquete org.eclipse.swt.widgets)

Antes del release 3.0, la llamada a DirectoryDialog.setMessage(String string) o MessageBox.setMessage(String string) de SWT con un valor nulo para string daba como resultado un diálogo sin texto en el título. Este comportamiento no estaba especificado (nunca ha estado permitido pasar nulo) y creaba problemas en getMessage, que no puede devolver nulo. En 3.0, el pasar nulo se provoca el lanzamiento de una IllegalArgumentException y las especificaciones han cambiado para indicarlo, situando en línea el método en su superclase Dialog.setMessage. Si utiliza Dialog.setMessage, asegúrese de que la serie pasada nunca es nula. Pase simplemente una serie vacía si desea que aparece un diálogo sin texto en el título.

Mejoramiento de la información de progreso modal

El soporte de operaciones simultáneas requiere formas más soficticadas de mostrar el progreso modal. Como parte del esfuerzo de capacidad de respuesta, se ha implementado soporte adicional en la clase IProgressService. La forma existente de mostrar el progreso con ProgressMonitorDialog sigue funcionando. Sin embargo, para mejorar la práctica del usuario es aconsejable migrar al nuevo IProgressService.

El documento Showing Modal Progress in Eclipse 3.0 describe cómo migrar al nuevo IProgressService.

Grupos de acciones de depuración eliminados

El punto de extensión de grupos de acciones de depuración (org.eclipse.debug.ui.debugActionGroups) se ha eliminado. En Eclipse 3.0, el entorno de trabajo ha introducido soporte para actividades por medio del punto de extensión org.eclipse.platform.ui.activities. Este soporte proporciona todo lo que suministraban los grupos de acciones de depuración, es más fácil de utilizar (soporta patrones en lugar de especificar todas las acciones exhaustivamente) y tiene una API programática de soporte. El hecho de no eliminar las referencias al punto de extensión antiguo no provocará anomalías. Las referencias al punto de extensión simplemente se pasarán por alto. Se insta a los distribuidores de productos a utilizar el soporte de actividades del entorno de trabajo para asociar acciones del depurador específicas del lenguaje con actividades específicas del lenguaje (por ejemplo, las acciones de depuración de C++ pueden asociarse con una actividad llamada "Desarrollar C++").

BreakpointManager puede estar inhabilitado

IBreakpointManager define ahora los métodos setEnabled(boolean) e isEnabled(). Cuando el gestor de puntos de interrupción está inhabilitado, debe pasar por alto todos los puntos de interrupción registrados. La plataforma de depuración también proporciona un nuevo mecanismo de escuchador, IBreakpointManagerListener, que permite informar a los clientes que deben registrarse en el gestor de puntos de interrupción cuando cambia su habilitación. La vista Puntos de interrupción llama a este API desde una nueva acción de conmutación que permite al usuario "Saltar todos los puntos de interrupción". Los depuradores que no realicen la habilitación del gestor de puntos de interrupción aparecerán por tanto interrumpidos si el usuario intenta utilizar esta característica.

[Sólo JDT] participantes de búsqueda Java (paquete org.eclipse.jdt.core.search)

Los lenguajes cercanos a Java (como por ejemplo JSP, SQLJ, JWS, etc.) deben poder participar en la búsqueda Java. En particular, los implementadores de tales lenguajes deben ser capaces de:

 

Un implementador de este tipo se denomina participante de búsqueda. Amplía la clase SearchParticipant. Los participantes de búsqueda se pasan a consultas de búsqueda (consulte SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)).

Para indexar o localizar coincidencias, un participante de búsqueda debe definir una subclase de SearchDocument que pueda recuperar el contenido del documento alterando temporalmente getByteContents() o getCharContents(). Una instancia de esta subclase se devuelve en getDocument(String).

Un participante de búsqueda que desee indexar algún documento utilizará SearchParticipant.scheduleDocumentIndexing(SearchDocument, IPath) para planificar el indexado del documento dado en el índice dado. Una vez que el documento esté preparado para indexarlo, la infraestructura subyacente llama a SearchParticipant.indexDocument(SearchDocument, IPath). A continuación, el participante de búsqueda obtiene el contenido del documento, lo analiza y añade entradas de índice mediante SearchDocument.addIndexEntry(char[], char[]).

Una vez realizado el indexado, pueden consultarse los índices y localizar coincidencias mediante SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor). En primer lugar se solicita a cada participante los índices necesarios para la consulta mediante SearchParticipant.selectIndexes(SearchPattern, IJavaSearchScope). para cada entrada de índice que coincide con el patrón dado, se crea un documento de búsqueda solicitando el participante de búsqueda (consulte getDocument(String)). Todos estos documentos se pasan al participante de búsqueda para que pueda localizar las coincidencias mediante locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor). El participante de búsqueda notifica las coincidencias de búsqueda al SearchRequestor mediante acceptSearchMatch(SearchMatch) y pasando una instancia de una subclase de SearchMatch.

Un participante de búsqueda puede delegar parte de su trabajo al participante de búsqueda Java por omisión. Una instancia de este participante por omisión se obtiene mediante SearchEngine.getDefaultSearchParticipant(). Por ejemplo, cuando se le solicita que localice coincidencias, un participante SQLJ puede crear documentos .java a partir de sus documentos .sqlj y delegar el trabajo en el participante por omisión pasándole los documentos .java.

Avisos legales