La présente section décrit les modifications à apporter obligatoirement pour que votre plug-in 2.1 adopte les API et les mécanismes de la version 3.0.
L'environnement d'exécution d'Eclipse 3.0 est très différent. L'implémentation sous-jacente repose sur la spécification de la structure OSGi. Il inclut une couche de compatibilité (dans le plug-in org.eclipse.core.runtime.compatibility) qui permet de conserver les API de la version 2.1. Les développeurs de plug-in qui sont intéressés par des fonctions supplémentaires et de meilleures performances devraient envisager d'adopter les API de la version 3.0 et de supprimer leur dépendance dans la couche de compatibilité. Le code de compatibilité apparaît à trois endroits :
Vous trouverez ci-après des détails sur la façon dont les classes et les méthodes apparaissent pour la compatibilité et des instructions relatives à la mise à jour de votre plug-in.
L'environnement d'exécution Eclipse a été restructuré en deux parties : le chargement des classes et la gestion des prérequis d'une part et la gestion des extensions et des points d'extension d'autre part. Cette division permet une adoption naturelle et transparente de la spécification de la structure OSGi pour le chargement des classes et la gestion des prérequis. Ainsi, de nouvelles fonctionnalités sont disponibles dans l'environnement d'exécution, comme l'installation, la mise à jour et la désinstallation dynamiques d'un plug-in, la sécurité et une meilleure configurabilité.
Alors que le terme plug-ins est toujours employé, dans le nouvel environnement d'exécution, un plug-in est en fait un bundle associé à des extensions et des points d'extension. Le terme bundle est défini par la spécification de la structure OSGi et fait référence à une série de types et de ressources ainsi qu'à des informations relatives aux prérequis inter-bundle. Le registre des extensions est la nouvelle forme du registre des plug-ins et décrit uniquement les extensions et les points d'extension. Globalement, l'API du registre des extensions est identique à l'API du registre des plug-ins correspondant (pour plus d'informations, voir Registres).
Dans l'environnement d'exécution d'Eclipse 2.x, l'objet de plug-in possède un certain nombre de rôles et de responsabilités :
Dans l'environnement d'exécution d'Eclipse 3.0, ces rôles et ces responsabilités sont répartis dans différents objets.
Plugin implémente également BundleActivator. L'intérêt d'avoir un objet central représentant le cycle de vie et la sémantique d'un plug-in est reconnu. Toutefois, l'initialisation systématique de structures de données courantes dans les plug-ins aujourd'hui n'est pas sanctionnée. N'oubliez pas que des plug-ins peuvent être activés car une classe périphérique quelconque a été référencée lors de la vérification d'une classe dans un autre plug-in. En d'autres termes, ce n'est pas parce que votre plug-in a été activé que sa fonction est requise. De plus, vous êtes libre de définir une classe BundleActivator différente ou de ne pas en avoir du tout.
Les étapes de transfert d'une classe Plugin 2.x vers Eclipse 3.0 dépendent de la tâche de la classe. Comme indiqué plus haut, la plupart des travaux de cycle de vie de démarrage se trouvent dans l'une des catégories ci-dessous.
Dans le nouvel environnement d'exécution, les informations et les structures nécessaires à l'exécution d'un plug-in et celles qui sont liées aux extensions et aux points d'extension d'un plug-in sont séparées. Les premières sont définies et gérées par la spécification de la structure OSGi. Les dernières sont des concepts propres à Eclipse et sont ajoutées par le code de l'environnement d'exécution d'Eclipse. De même, le registre des plug-ins d'origine et les objets liés sont répartis entre les bundles OSGi et le registre des extensions Eclipse.
Les parties d'IPluginRegistry relatives à la spécification de l'exécution (c'est-à-dire IPluginDescriptor, ILibrary et IPrequisite) sont déconseillées et les parties relatives aux extensions et aux points d'extension ont été déplacées dans IExtensionRegistry. De plus, les objets de modèle liés au registre des plug-ins entier sont désormais déconseillés. Ces types étaient présentés et instanciés par l'environnement d'exécution principalement pour prendre en charge des outils tels que PDE. Malheureusement, le niveau d'information nécessaire dépassait souvent les capacités ou les intérêts de l'environnement d'exécution (comme par exemple l'enregistrement des numéros de ligne pour les éléments de plug-in.xml) et à la fin, les consommateurs potentiels des informations de l'environnement d'exécution devaient de toute façon gérer leurs propres structures.
Dans le nouvel environnement d'exécution, les fonctionnalités mises à disposition par l'environnement d'exécution ont été redéfinies et ne sont désormais fournies que celles qui sont essentielles à l'exécution de l'environnement d'exécution ou qui sont extrêmement difficiles à effectuer pour d'autres. Comme indiqué plus haut, les objets de modèle du registre des plug-ins sont déconseillés, comme l'API d'analyse des plug-ins. Le nouveau registre des extensions gère les informations essentielles relatives aux extensions. Une nouvelle structure d'état (voir org.eclipse.osgi.service.resolver.State et plug-ins liés) représente et permet leur manipulation.
Dans Eclipse 3.0, la structure des fragments NL a été mise à jour en vue d'une plus grande cohérence. Avant, les traductions des fichiers tels que plugin.properties se trouvaient dans des fichiers Jar fournis par les fragments. Etant donné que les fichiers source se situent à la racine du plug-in hôte correspondant, il est plus judicieux de placer les fichiers traduits à la racine des fragments NL. Par exemple,
org.eclipse.ui.workbench.nl/ fragment.xml plugin_fr.properties plugin_pt_BR.properties ... nl1.jar
Remarque : avant, le fichier nl1.jar aurait contenu les traductions de plugin.properties. Ces fichiers se trouvent désormais à la racine du fragment et le fichier Jar contient les traductions de toutes les ressources pouvant être traduites (comme les fichiers chargés via le chargeur de classe) dans le plug-in hôte.
Evidemment, la structure des fragments NL d'Eclipse 2.1 est encore prise en charge pour les plug-ins hôte 2.1 exécutés dans Eclipse 3.0. Toutefois, vous ne pouvez pas utiliser de fragment NL 2.1 dans un plug-in 3.0. Vous devez mettre à jour le fragment de sorte qu'il soit adapté à la nouvelle structure.
Le package org.eclipse.core.boot entier est déconseillé. BootLoader a été fusionné avec org.eclipse.core.runtime.Platform car il n'est plus nécessaire que l'amorçage et l'environnement d'exécution soit séparés. En fait, le code du plug-in org.eclipse.core.boot a été déplacé dans le nouvel environnement d'exécution ou dans la couche de compatibilité.
IPlatformConfiguration a toujours été un type défini par et pour le composant d'installation et de mise à jour d'Eclipse. Grâce à la réorganisation de l'environnement d'exécution, nous pouvons placer ce type à l'endroit approprié. Cette classe reste en grande partie inchangée et a été remise en forme dans org.eclipse.update.configurator.IPlatformConfiguration.
IPlatformRunnable a été déplacé dans org.eclipse.core.runtime.IPlatformRunnable.
La méthode getDeclaringPlugin()
(sur les deux classes) fournit un lien (vers le haut) au plug-in qui déclare l'extension ou le point d'extension (respectivement).
Le nouvel modèle de registre sépare les aspects liés à l'exécution des plug-ins des aspects liés aux extensions et aux points d'extension et ne contient plus
IPluginDescriptors.
Les utilisateurs de cette API doivent envisager d'utiliser la nouvelle méthode getParentIdentifier() qui se trouve sur
IExtension et IExtensionPoint.
Dans l'environnement d'exécution d'origine, le registre des plug-ins conservait une image complète de la configuration de l'environnement d'exécution. Dans Eclipse 3.0, cette image est répartie entre la structure OSGi et le registre des extensions. Ainsi, ces classes sont déconseillées. Les remarques y relatives détaillent la façon dont vous devez mettre à jour votre code.
Dans le nouvel environnement d'exécution, les objets Plugin ne sont plus gérés par l'environnement d'exécution et par conséquent, ne sont pas accessibles de façon générique via Platform. De même, le registre des plug-ins n'existe plus et ne permet plus l'accès aux descripteurs de plug-ins. Cependant, des méthodes de remplacement sont disponibles et détaillées dans la documentation Java (Javadoc) des méthodes déconseillées de ces classes.
Tous les types de ce package sont désormais déconseillés. Pour plus d'informations, voir l'article relatif aux registres.
Nous conseillons aux clients de la méthode IWorkspace.run(IWorkspaceRunnable,IProgressMonitor) de revoir leurs utilisations de cette méthode et d'envisager d'utiliser la méthode plus riche IWorkspace.run(IWorkspaceRunnable,ISchedulingRule,int,IProgressMonitor). L'ancienne méthode IWorkspace.run verrouille l'espace de travail entier pour toute la durée d'IWorkspaceRunnable. En d'autres termes, une opération effectuée à l'aide de cette méthode ne pourra pas s'exécuter en même temps que d'autres opérations qui modifient l'espace de travail. Dans Eclipse 3.0, de nombreuses opérations de longue durée ont été déplacées dans des unités d'exécution en arrière-plan, c'est pourquoi la probabilité de conflits entre les opérations est accrue. Si une opération modale en avant-plan est bloquée par une opération en arrière-plan de longue durée, l'interface utilisateur est bloquée jusqu'à ce que l'opération en arrière-plan se termine ou jusqu'à ce que l'une des opérations soit annulée.
Nous suggérons de modifier toutes les références à l'ancienne méthode IWorkspace.run de sorte qu'elles utilisent la nouvelle méthode avec un paramètre
de règle de planification. La règle de planification doit correspondre à la règle la plus précise qui englobe les règles pour toutes les modifications effectuées par cette opération. Si vous essayez de modifier des ressources qui se trouvent hors de la portée de la règle de planification, une exception d'exécution survient. La règle de planification spécifique requise par une opération d'espace de travail donnée n'est pas indiquée et peut varier selon le fournisseur de référentiel installé sur un projet précis. Utilisez la fabrique IResourceRuleFactory
afin d'obtenir la règle de planification pour une opération de modification de ressource. Vous pouvez également utiliser une règle MultiRule afin de spécifier plusieurs règles de ressource et la méthode MultiRule.combine pour combiner des règles provenant d'opérations de modification de ressource différentes.
Si le verrouillage n'est pas nécessaire, vous pouvez utiliser la règle de planification null. Elle permet à l'exécutable de modifier toutes les ressources de l'espace de travail mais n'empêche par d'autres unités d'exécution de modifier l'espace de travail simultanément. Pour des changements simples de l'espace de travail, il s'agit souvent de la solution la plus facile et la plus adaptée à la simultanéité.
filteredSelection
à partir de selection
:
IStructuredSelection filteredSelection = selection;
List selectedResources = IDE.computeSelectedResources(currentSelection);
if (!selectedResources.isEmpty()) {
filteredSelection = new
StructuredSelection(selectedResources);
}
IStructuredSelection filteredSelection = selection;
List selectedResources = IDE.computeSelectedResources(currentSelection);
if (!selectedResources.isEmpty()) {
filteredSelection = new
StructuredSelection(selectedResources);
}
if (selection.isEmpty()) { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null) { IWorkbenchPart part = window.getPartService().getActivePart(); if (part instanceof IEditorPart) { IEditorInput input = ((IEditorPart) part).getEditorInput(); if (input instanceof IFileEditorInput) { selection = new StructuredSelection(((IFileEditorInput) input).getFile()); } } } }
IActionBars actionBars= getActionBars(); if (actionBars != null) { actionBars.setGlobalActionHandler(IDEActionFactory.ADD_TASK.getId(), getAction(textEditor, IDEActionFactory.ADD_TASK.getId())); actionBars.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(), getAction(textEditor, IDEActionFactory.BOOKMARK.getId())); }
Il existe désormais la notion explicite de type d'annotation. Voir Annotation.getType() et Annotation.setType(). Le type d'une annotation peut changer. Un nouveau point d'extension a été ajouté pour la déclaration des types d'annotation : "org.eclipse.ui.editors.annotationTypes". Un type d'annotation est associé à un nom et peut être déclaré en tant que sous-type d'un autre type d'annotation déclaré. Une déclaration de type d'annotation peut aussi utiliser les attributs "markerType" et "markerSeverity" pour spécifier que les marqueurs d'un type et d'une sévérité donnés doivent être représentés dans les éditeurs de texte sous la forme d'annotations d'un type d'annotation particulier. N'utilisez plus les attributs "markerType" et "markerSeverity" de "org.eclipse.ui.editors.markerAnnotationSpecification". Les spécifications des annotations de marqueurs sont désormais indépendantes des marqueurs et leur nom n'est plus significatif. Ce dernier est cependant conservé afin d'assurer la compatibilité amont.
Les instances des sous-classes d'AbstractMarkerAnnotationModel détectent et définissent automatiquement les types d'annotation appropriés pour les annotations créées à partir de marqueurs. Pour extraire via un programme le type d'annotation pour un marqueur donné ou pour une paire spécifique markerType et markerSeverity, utilisez org.eclipse.ui.texteditor.AnnotationTypeLookup.
IAnnotationAccessExtension permet l'accès à la hiérarchie des types d'annotation. Pour un type d'annotation donné, vous pouvez obtenir la chaîne des supertypes et vérifier si un type d'annotation est un sous-type d'un autre type d'annotation. DefaultMarkerAnnotationAccess implémente cette interface.
Le type d'annotation est la clé qui permet de rechercher la spécification de l'annotation de marqueur associée. Etant donné que les types d'annotation peuvent étendre d'autres types d'annotation, il existe également une relation implicite entre les spécifications des annotations de marqueur. Par conséquent, une spécification d'annotation de marqueur pour un type d'annotation donné est complété par les spécifications d'annotations de marqueurs données pour le supertype du type d'annotation donné. Ainsi, il n'est plus nécessaire qu'une spécification d'annotation de marqueur soit complète. Les spécifications d'annotations de marqueurs sont extraites par AnnotationPreferences. Avec org.eclipse.ui.texteditor.AnnotationPreferenceLookup, vous pouvez extraire une préférence d'annotation pour un type d'annotation donné qui complète la préférence de façon transparente ainsi que la chaîne des supertypes de l'annotation.
La spécification d'annotation de marqueur a été étendue et comprend désormais trois nouveaux attributs qui permettent de personnaliser l'apparence d'un type d'annotation donné dans la règle verticale. Il s'agit d'"icon", de "symbolicIcon" et de "annotationImageProvider". La valeur d'"icon" correspond au chemin d'accès à un fichier contenant l'image de l'icône. La valeur de "symbolicIcon" peut être "error", "warning", "info", "task", "bookmark". L'attribut "symbolicIcon" permet d'indiquer à la plateforme que l'annotation doit être représentée par les images utilisées par la plateforme pour présenter les erreurs, les avertissements, les informations, les tâches et les signets, respectivement. La valeur d'"annotationImageProvider" correspond à une classe implémentant org.eclipse.ui.texteditor.IAnnotationImageProvider, qui permet de personnaliser entièrement la présentation d'une annotation.
La règle verticale utilise les éléments IAnnotationAccess/IAnnotationAccessExtension associés pour dessiner les annotations. Elle n'appelle plus Annotation.paint. En général, les annotations ne se dessinent plus elles-mêmes. Les méthodes "paint" et "getLayer" ont été rendues obsolètes pour que les annotations ne soient finalement plus dépendantes de l'interface utilisateur. DefaultMarkerAnnotationAccess sert d'implémentation par défaut d'IAnnotationAccess/IAnnotationAccessExtension. DefaultMarkerAnnotationAccess implémente la stratégie suivante pour le dessin des annotations : si une annotation implémente IAnnotationPresentation, IAnnotationPresentation.paint est appelé. Sinon, le fournisseur des images d'annotation est consulté dans les préférences de l'annotation. Le fournisseur des images de l'annotation n'est disponible que s'il a été spécifié et si le plug-in qui définit la spécification d'annotation de marqueur conteneur a déjà été chargé. Si un fournisseur d'images d'annotation est indiqué, l'appel lui est transmis. Sinon, l'"icône" spécifié est recherché. "symbolicIcon" est utilisé comme image de remplacement finale. Pour le dessin des annotations, la couche de présentation des annotations est pertinente. DefaultMarkerAnnotationAccess consulte la couche de présentation à l'aide de la stratégie suivante : si les préférences de l'annotation spécifie un couche de présentation, la couche indiquée est utilisée. Si aucune couche n'est spécifiée et si l'annotation implémente IAnnotationPresentation, IAnnotationPresentation.getLayer est utilisé. Dans les autres cas, la couche de présentation par défaut (qui est 0) est renvoyée.
Les types d'annotation suivants sont déclarés par le 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>
L'extension markerAnnotationSpecification définie ne fournit plus les attributs "markerType" et "markerSeverity". Elle associe l'attribut "symbolicIcon" à la valeur appropriée. Par conséquent, les méthodes MarkerAnnotation.paint et MarkerAnnotation.getLayer ne sont plus appelées ; en d'autres termes, leur remplacement n'a aucun impact. Les clients affectés doivent implémenter IAnnotationPresentation.
Avec l'introduction des modes de lancement extensibles dans la version 3.0, plusieurs délégations de lancement peuvent exister pour un type de configuration de lancement. Avant la version 3.0, une délégation de lancement uniquement était prise en charge par type de configuration de lancement. La méthode ILaunchConfigurationType.getDelegate()
est désormais déconseillée. A la place, utilisez la méthode getDelegate(String mode)
pour extraire la délégation de lancement pour un mode de lancement spécifique.
La méthode déconseillée a été modifiée de sorte à renvoyer la délégation de lancement pour le mode exécution
.
Les groupes d'onglets de lancement et les onglets de lancement ne sont plus notifiés lorsqu'un lancement aboutit. La méthode launched(ILaunch)
dans les interfaces ILaunchConfigurationTab
et ILaunchConfigurationTabGroup
est déconseillée et n'est plus appelée. L'utilisation de cette méthode pour le lancement a toujours été problématique, car les onglets n'existent que lorsque le lancement est effectué à partir de la boîte de dialogue de lancement. De plus, avec l'introduction du lancement en arrière-plan, cette méthode ne peut plus être appelée car la boîte de dialogue de lancement est fermée avant que l'objet de lancement résultant n'existe.
Deux méthodes ont été ajoutées à l'interface ILaunchConfigurationTab
- activated et deactivated. Ces nouvelles méthodes de cycle de vie sont appelées lorsque vous accédez à un onglet et que vous le quittez, respectivement. Les implémentations existantes d'ILaunchConfigurationTab
qui sous-classent la classe de type "abstract" mise à disposition par le plug-in de débogage
(AbstractLaunchConfigurationTab
) sont compatibles de façon binaire car les méthodes sont implémentées dans la classe de type "abstract".
Dans les versions précédentes, un onglet recevait le message initializeFrom
lorsqu'il était activé et le message
performApply
lorsqu'il était désactivé. De cette façon, la structure des onglets de configuration du lancement permettait la communication entre les onglets via une configuration de lancement (en mettant à jour la configuration avec les valeurs d'attribut en cours lorsqu'un utilisateur quittait l'onglet et en mettant à jour l'onglet nouvellement accédé). Toutefois, étant donné que plusieurs onglets ne permettent pas la communication entre les onglets, il se peut que cette méthode ne soit pas efficace. De plus, il était impossible de distinguer un onglet activé d'un onglet affichant une configuration de lancement sélectionnée pour la première fois. Les nouvelles méthodes permettent aux onglets de distinguer l'activation, l'initialisation et la désactivation et de sauvegarder les valeurs en cours.
L'implémentation par défaut de la méthode activated
, mise à disposition par l'onglet Abstrait, appelle initializeFrom
. L'implémentation par défaut de la méthode deactivated
appelle performApply
. Les onglets qui veulent profiter de la nouvelle API doivent remplacer ces méthodes selon leurs besoins.
En général, pour les onglets qui ne permettent pas la communication entre onglets, il est conseillé d'implémenter à nouveau ces méthodes de sorte qu'elles n'effectuent aucune opération.
Dans les versions précédentes, le passage d'une perspective à l'autre était spécifié dans une configuration de lancement, par le biais des attributs de configuration de lancement ATTR_TARGET_DEBUG_PERSPECTIVE
et ATTR_TARGET_RUN_PERSPECTIVE
. Avec l'ajout de modes de lancement extensibles dans la version 3.0, l'échelonnement n'est plus pris en compte. Le passage d'une perspective à l'autre est désormais spécifié en fonction du type de configuration de lancement, par mode de lancement qu'un type de configuration de lancement prend en charge. Une API a été ajoutée à DebugUITools
pour définir et obtenir la perspective associée à un type de configuration de lancement pour un mode de lancement spécifique.
Un élément supplémentaire facultatif launchMode
a été ajouté au point d'extension launchConfigurationTabGroup
, pour qu'un groupe d'onglets ajouté puisse spécifier une perspective par défaut pour un mode et un type de configuration de lancement.
A partir de l'interface utilisateur Eclipse, les utilisateurs peuvent éditer la perspective associée à un type de configuration de lancement en ouvrant la boîte de dialogue de type de configuration de lancement et en sélectionnant un noeud de type de configuration de lancement dans l'arborescence (plutôt qu'une configuration individuelle). Un onglet apparaît, qui permet à l'utilisateur de définir une perspective pour chaque mode de lancement pris en charge.
Deux méthodes ont été ajoutées à la classe VMRunnerConfiguration
pour prendre en charge la définition et l'extraction des variables d'environnement. Les implémenteurs d'IVMRunner
doivent appeler VMRunnerConfiguration.getEnvironment()
et transmettre cet environnement à la machine virtuelle Java (JVM) en cours d'exécution. Pour ce faire, les clients qui utilisent DebugPlugin.exec(String[]
cmdLine, File workingDirectory)
peuvent appeler DebugPlugin.exec(String[]
cmdLine, File workingDirectory, String[] envp)
à la place. Le simple fait de transmettre le résultat de
getEnvironment()
suffit.
Dans les versions précédentes, la classe VMRunnerConfiguration
décrivait un chemin d'amorçage à l'aide d'un attribut. Il s'agissait d'une série de chaînes
figurant dans l'argument -Xbootclasspath
. Trois nouveaux attributs ont été ajoutés à
VMRunnerConfiguration pour prendre en charge les machines virtuelles Java (JVM) qui autorisent l'ajout sous la forme de suffixe ou de préfixe à un chemin d'amorçage. Les nouvelles méthodes/attributs sont les suivantes :
getPrependBootClassPath()
- renvoie une série d'entrées à ajouter sous la forme d'un préfixe au chemin d'amorçage
(argument -Xbootclasspath/p
)getMainBootClassPath()
- renvoie une série d'entrées à placer sur le chemin d'amorçage (argument -Xbootclasspath
)getAppendBootClassPath()
- renvoie une série d'entrées à ajouter sous la forme d'un suffixe au chemin d'amorçage (argument -Xbootclasspath/a
)L'ancien attribut, getBootClassPath()
, existe encore et contient un chemin complet équivalent à celui des trois nouveaux attributs. Toutefois, la classe VMRunners
qui prend en charge les nouvelles options du chemin d'amorçage devrait profiter des nouveaux attributs.
La fonction de copie d'un modèle Java a été améliorée dans la version 3.0. Avant la version 3.0, le modèle Java permettait la création de copies de travail individuelles d'unités de compilation. L'utilisateur pouvait modifier la copie de travail puis valider les changements. La fonction d'analyse limitée d'une copie de travail dans le contexte du reste du modèle Java était prise en charge. Cependant, ces analyses étaient incapables de prendre en compte plusieurs copies de travail à la fois.
Les modifications apportées à la version 3.0 permettent de créer et de gérer des ensembles de copies de travail d'unités de compilation et d'effectuer des analyses pour toutes les copies de travail d'un ensemble. Par exemple, un client comme JDT refactoring peut désormais créer des copies de travail pour une ou plusieurs unités de compilation qu'il envisage de modifier puis résoudre les références des types entre les copies de travail. Avant, cette opération n'était possible qu'après validation des modifications apportées aux copies de travail de l'unité de compilation.
Deux modifications ont été apportées à l'API du modèle Java en vue de l'amélioration de la prise en charge :
(1) la fonctionnalité qui se trouvait dans IWorkingCopy
et héritée par ICompilationUnit
a été consolidée dans ICompilationUnit
.
L'interface IWorkingCopy
était uniquement utilisée à cet emplacement et était plus générale que nécessaire. Cette modification simplifie l'API. La classe IWorkingCopy
est déconseillée. D'autres emplacements dans l'API où IWorkingCopy
est utilisée comme paramètre ou type de résultat ont été déconseillés également ; les
méthodes de l'API de remplacement indiquent ICompilationUnit
au lieu d'IWorkingCopy
.
(2) L'interface IBufferFactory
a été remplacée par WorkingCopyOwner
.
La prise en charge améliorée des copies de travail requiert qu'un objet soit propriétaire des copies de travail. Bien qu'IBufferFactory
soit bien situé, son nom n'indique pas la façon dont le nouveau mécanisme de copie fonctionne. WorkingCopyOwner
est plus suggestif. De plus, WorkingCopyOwner
est déclarée en tant que classe de type "abstract", et non comme interface, pour que la notion de propriétaire de copie de travail puisse évoluer. La méthode d'IBufferFactory
est déplacée vers WorkingCopyOwner
sans subir de modification. WorkingCopyOwner
n'implémente pas
IBufferFactory
pour qu'il soit clair qu'IBufferFactory
est obsolète. La classe IBufferFactory
est déconseillée. D'autres emplacements dans l'API où
IBufferFactory
apparaît sous la forme d'un paramètre ou d'un type de résultat sont également déconseillés ; les méthodes de l'API de remplacement indiquent WorkingCopyOwner
à la place d'IBufferFactory
.
Ces modifications n'ont pas d'effet sur la compatibilité binaire.
Lors de la migration, toutes les références au type IWorkingCopy
doivent pointer vers ICompilationUnit
à la place. L'implémentation d'IWorkingCopy
implémente aussi ICompilationUnit
, c'est-à-dire que des objets de type IWorkingCopy
peuvent être transmis en toute sécurité vers ICompilationUnit
.
Une classe qui implémente IBufferFactory
doit être remplacée par une sous-classe de WorkingCopyOwner
. Bien que WorkingCopyOwner
n'implémente pas la classe IBufferFactory
elle-même, vous pouvez déclarer la sous-classe
de WorkingCopyOwner
qui implémente IBufferFactory
et crée un pont entre l'ancienne et la nouvelle classe
(IBufferFactory
déclare createBuffer(IOpenable)
alors que WorkingCopyOwner
déclare createBuffer(ICompilationUnit)
; ICompilationUnit
étend IOpenable
).
Etant donné que les modifications qui impliquent IWorkingCopy
et IBufferFactory
sont liées, nous vous conseillons de traiter les deux en même temps. Vous trouverez les détails des obsolescences ci-dessous.
IWorkingCopy
(package org.eclipse.jdt.core
)
public void commit(boolean, IProgressMonitor)
est déconseillée.
ICompilationUnit
:
public void commitWorkingCopy(boolean, IProgressMonitor)
wc.commit(b,monitor)
sous la forme ((ICompilationUnit)
wc).commitWorkingCopy(b,monitor)
public void destroy()
est déconseillée.
ICompilationUnit
:
public void discardWorkingCopy(boolean, IProgressMonitor)
wc.destroy()
sous la forme ((ICompilationUnit)
wc).discardWorkingCopy()
public IJavaElement findSharedWorkingCopy(IBufferFactory)
est déconseillée.
ICompilationUnit
:
public ICompilationUnit findWorkingCopy(WorkingCopyOwner)
WorkingCopyOwner
remplace IBufferFactory.
public IJavaElement getOriginal(IJavaElement)
est déconseillée.
IJavaElement
:
public IJavaElement getPrimaryElement()
wc.getOriginal(elt)
sous la forme elt.getPrimaryElement()
IWorkingCopy.getOriginal
, IJavaElement.getPrimaryElement
ne renvoie par la valeur
null
si le récepteur ne correspond pas à une copie de travail.public IJavaElement getOriginalElement()
est déconseillée.
ICompilationUnit
:
public ICompilationUnit getPrimary()
wc.getOriginalElement()
sous la forme ((ICompilationUnit)
wc).getPrimary()
IWorkingCopy.getOriginalElement
, IWorkingCopy.getPrimary
ne renvoie par la valeur
null
si le récepteur ne correspond pas à une copie de travail.public IJavaElement[] findElements(IJavaElement)
est déconseillée.
ICompilationUnit
directement.wc.findElements(elts)
sous la forme ((ICompilationUnit)
wc).findElements(elts)
public IType findPrimaryType()
est déconseillée.
ICompilationUnit
directement.wc.findPrimaryType()
sous la forme ((ICompilationUnit)
wc).findPrimaryType()
public IJavaElement getSharedWorkingCopy(IProgressMonitor,
IBufferFactory, IProblemRequestor)
est déconseillée.
ICompilationUnit
:
public ICompilationUnit getWorkingCopy(WorkingCopyOwner,
IProblemRequestor, IProgressMonitor)
WorkingCopyOwner
remplace IBufferFactory.
public IJavaElement getWorkingCopy()
est déconseillée.
ICompilationUnit
:
public ICompilationUnit getWorkingCopy(IProgressMonitor)
wc.getWorkingCopy()
sous la forme ((ICompilationUnit)
wc).getWorkingCopy(null)
public IJavaElement getWorkingCopy(IProgressMonitor,
IBufferFactory, IProblemRequestor)
est déconseillée.
ICompilationUnit
:
public ICompilationUnit getWorkingCopy(WorkingCopyOwner,
IProblemRequestor, IProgressMonitor)
WorkingCopyOwner
remplace IBufferFactory.
public boolean isBasedOn(IResource)
est déconseillée.
ICompilationUnit
:
public boolean hasResourceChanged()
wc.isBasesOn(res)
sous la forme ((ICompilationUnit)
wc).hasResourceChanged()
public boolean isWorkingCopy()
est déconseillée.
ICompilationUnit
directement.wc.isWorkingCopy()
sous la forme ((ICompilationUnit)
wc).isWorkingCopy()
public IMarker[] reconcile()
est déconseillée.
ICompilationUnit
:
public void reconcile(boolean,IProgressMonitor)
wc.reconcile()
sous la forme ((ICompilationUnit)
wc).reconcile(false, null)
null
; la méthode de remplacement ne renvoie pas de résultat.public void reconcile(boolean, IProgressMonitor)
est déconseillée.
ICompilationUnit
directement.wc.reconcile(b,monitor)
sous la forme ((ICompilationUnit)
wc).reconcile(b.monitor)
public void restore()
est déconseillée.
ICompilationUnit
directement.wc.restore()
sous la forme ((ICompilationUnit)
wc).restore()
IType
(package org.eclipse.jdt.core
)
public ITypeHierarchy newSupertypeHierarchy(IWorkingCopy[],
IProgressMonitor)
est déconseillée.
public ITypeHierarchy newSupertypeHierarchy(c,
IProgressMonitor)
IWorkingCopy[]
à ICompilationUnit[]
.public ITypeHierarchy newTypeHierarchy(IWorkingCopy[],
IProgressMonitor)
est déconseillée.
public ITypeHierarchy newTypeHierarchy(ICompilationUnit[],
IProgressMonitor)
IWorkingCopy[]
à ICompilationUnit[]
.IClassFile
(package org.eclipse.jdt.core
)
public IJavaElement getWorkingCopy(IProgressMonitor,
IBufferFactory)
est déconseillée.
public ICompilationUnit getWorkingCopy(WorkingCopyOwner,
IProgressMonitor)
WorkingCopyOwner
remplace IBufferFactory.
JavaCore
(package org.eclipse.jdt.core
)
public IWorkingCopy[] getSharedWorkingCopies(IBufferFactory)
est déconseillée.
public ICompilationUnit[]
getWorkingCopies(WorkingCopyOwner)
WorkingCopyOwner
remplace IBufferFactory.
ICompilationUnit[]
à IWorkingCopy[]
.SearchEngine
(package org.eclipse.jdt.core.search
)
public SearchEngine(IWorkingCopy[])
est déconseillée.
public SearchEngine(ICompilationUnit[])
IWorkingCopy[]
à ICompilationUnit[]
.Le plug-in org.eclipse.help, qui conservait les API et les points d'extension permettant l'ajout d'éléments au système d'aide et son extension, ainsi qu'à afficher l'aide, ne contient plus désormais que des API et des points d'extension pour l'ajout et l'accès aux ressources d'aide. Une partie de l'implémentation de l'interface utilisateur d'aide par défaut contenue dans ce plug-in a été déplacée dans un nouveau plug-in, org.eclipse.help.base, avec des API permettant l'extension de l'implémentation. Les API et les points d'extension permettant l'ajout de l'interface utilisateur d'aide et l'affichage de l'aide ont été déplacés dans le plug-in org.eclipse.ui. Cette restructuration permet aux applications de disposer d'une plus grande souplesse par rapport au système d'aide ; les applications reposant sur le plan de travail générique peuvent fournir leur propre implémentation de l'interface utilisateur d'aide et/ou de l'aide, ou ignorer complètement le système d'aide.
Etant donné que les points d'extension et les packages d'API affectés sont conçus uniquement pour être utilisés par le système d'aide lui-même, il est peu probable que des plug-ins existants soit touchés par cette modification. Ils sont répertoriés ici uniquement pour que la liste soit exhaustive :
Une nouvelle API pour l'implémentation des recherches personnalisées a été ajoutée dans la version 3.0. L'API d'origine est déconseillée dans la version 3.0 et il est plus judicieux que les clients utilisent la nouvelle API dans les packages org.eclipse.search.ui et org.eclipse.search.ui.text.
Les clients doivent créer des implémentations d'ISearchQuery
, ISearchResult
et ISearchResultPage
. L'implémentation d'ISearchResultPage
doit ensuite être ajoutée au nouveau point d'extension org.eclipse.search.searchResultViewPages
.
Les implémentations par défaut de ISearchResult
et ISearchResultPage
se trouvent dans le package org.eclipse.search.ui.text
.
Avant la version 3.0, l'appel de DirectoryDialog.setMessage(String string) ou de MessageBox.setMessage(String string) avec une valeur null pour la chaîne entraînait l'apparition d'une boîte de dialogue sans titre. Ce comportement n'était pas défini (la transmission de la valeur null n'a jamais été autorisée) et crée des problèmes pour getMessage qui ne peut pas renvoyer de valeur null. Dans la version 3.0, la transmission de la valeur null entraîne désormais une exception IllegalArgumentException ; les spécifications ont été modifiées et le mentionnent sur la ligne de la méthode dans la superclasse Dialog.setMessage. Si vous utilisez Dialog.setMessage, vérifiez que la valeur de la chaîne transmise n'est pas "null". Transmettez simplement une chaîne vide pour afficher une boîte de dialogue sans titre.
La prise en charge d'opérations simultanées requiert des méthodes sophistiquées pour l'affichage de la progression modale. Dans le cadre des efforts relatifs à la réactivité, la prise en charge supplémentaire de la progression a été implémentée dans la classe IProgressService. La méthode existante permettant d'afficher la progression avec ProgressMonitorDialog fonctionne encore. Toutefois, pour améliorer votre expérience, nous vous conseillons de migrer vers la nouvelle méthode IProgressService.
Le document Showing Modal Progress in Eclipse 3.0 explique comment procéder à la migration vers la nouvelle méthode IProgressService.
Le point d'extension des groupes d'actions de débogage (org.eclipse.debug.ui.debugActionGroups) a été supprimé. Dans Eclipse 3.0, le plan de travail prend en charge les activités via le point d'extension org.eclipse.platform.ui.activities. Il fournit tous les éléments que le point d'extension des groupes d'actions de débogage mettait à disposition et son utilisation est plus facile (il prend en charge les masques ce qui évite de spécifier toutes les actions de façon exhaustive) et est associé à une API de prise en charge par programme. Aucune erreur ne survient si vous ne supprimez pas les références à l'ancien point d'extension. Ces dernières seront simplement ignorées. Nous encourageons les fournisseurs des produits à utiliser la prise en charge des activités du plan de travail pour l'association d'actions de débogage propres à un langage aux activités propres à ce langage (par exemple, les actions de débogage C++ peuvent être associées à une activité appelée "Développement C++").
IBreakpointManager définit désormais les méthodes setEnabled(boolean) et isEnabled(). Lorsque le gestionnaire des points d'arrêt est désactivé, les débogueurs doivent ignorer tous les points d'arrêt enregistrés. La plateforme de débogage fournit également un nouveau mécanisme de programme d'écoute, IBreakpointManagerListener, qui permet à un client de s'enregistrer auprès du gestionnaire des points d'arrêt afin d'être notifié lorsque son activation change. La vue Points d'arrêt appelle cette API à partir d'une nouvelle action d'activation/désactivation qui permet à l'utilisateur d'"ignorer tous les points d'arrêt". Les débogueurs qui ne respectent pas l'activation du gestionnaire des points d'arrêt ne fonctionneront pas si l'utilisateur tente d'utiliser cette fonction.
Les langages proche de Java (comme JSP, SQLJ, JWS, etc.) doivent pouvoir participer à la recherche Java. Les implémenteurs de tels langages, notamment, doivent pouvoir :
Un tel implémenteur est appelé participant à la recherche. Il étend la classe SearchParticipant. Les participants à la recherche sont transmis à de requêtes de recherche (voir SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)).
Pour l'indexation ou la localisation d'occurrences, un participant à la recherche doit définir une sous-classe de SearchDocument qui peut extraire le contenu du document en écrasant getByteContents() ou getCharContents(). Une instance de cette sous-classe est renvoyée dans getDocument(String).
Un participant à la recherche qui souhaite indexer un document utilise SearchParticipant.scheduleDocumentIndexing(SearchDocument, IPath) pour planifier l'indexation du document indiqué dans l'index donné. Une fois que le document est prêt pour l'indexation, la structure sous-jacente appelle SearchParticipant.indexDocument(SearchDocument, IPath). Le participant à la recherche extrait ensuite le contenu du document, l'analyse et ajoute des entrées d'index à l'aide de SearchDocument.addIndexEntry(char[], char[]).
Une fois l'indexation terminée, un utilisateur peut interroger les index et rechercher des occurrences avec SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor). Cette méthode demande d'abord à chaque participant à la recherche quels sont les index nécessaires à la requête avec SearchParticipant.selectIndexes(SearchPattern, IJavaSearchScope). Pour chaque entrée d'index qui correspond au modèle donné, un document de recherche est créé après demande au participant à la recherche (voir getDocument(String)). Tous ces documents sont transmis au participant à la recherche pour qu'il puisse localiser des occurrences à l'aide de locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor). Le participant à la recherche notifie l'objet SearchRequestor des occurrences trouvées avec acceptSearchMatch(SearchMatch) et en transmettant une instance d'une sous-classe de SearchMatch.
Un participant à la recherche peut déléguer une partie de son travail au participant à la recherche Java par défaut. Vous pouvez obtenir une instance du participant par défaut à l'aide de SearchEngine.getDefaultSearchParticipant(). Par exemple, lorsqu'il doit rechercher des occurrences, un participant SQLJ peut créer des documents .java à partir de ses documents .sqlj et déléguer le travail au participant par défaut en lui transmettant les documents .java.