Modifiche necessarie quando si adottano i meccanismi e le API 3.0

Questa sezione descrive le modifiche necessarie se si tenta di sostituire il plugin 2.1 per adottare i meccanismi e le API 3.0.

Rimozione di org.eclipse.core.runtime.compatibility

Il runtime di Eclipse 3.0 è molto diverso. L'implementazione sottostante è basata sulla specifica del framework OSGi. Il runtime di Eclipse 3.0 include un livello di compatibilità (nel plugin org.eclipse.core.runtime.compatibility) che mantiene le API 2.1. Gli sviluppatori di plugin interessati in prestazioni e funzioni supplementari devono considerare di adottare le API 3.0 e di rimuovere la dipendenza dal livello di compatibilità. Il codice di compatibilità viene visualizzato in tre situazioni:

Il testo in basso fornisce ulteriori dettagli sulle classi e i metodi presenti per scopi di compatibilità, oltre ad una guida su come aggiornare il plugin.

Plugin e insiemi

Il runtime di Eclipse è stato suddiviso in due parti, il caricamento classi e la gestione dei prerequisiti e la gestione delle estensioni/punti di estensione. Questa suddivisione consente l'adozione naturale e uniforme della specifica del framework OSGi per il caricamento classi e la gestione dei prerequisiti. Ciò abilita una serie di nuove funzioni nel runtime dall'installazione/aggiornamento/disinstallazione del plugin dinamico alla sicurezza e configurabilità migliorata.

Anche se si continua a parlare di plugin, nel nuovo runtime un plugin è in realtà un insieme a cui vengono aggiunte nuove estensioni e punti di estensione. Il termine insieme viene definito dalla specifica del framework OSGi e si riferisce ad una serie di tipi e risorse e di informazioni prerequisite sugli insiemi associati. Il registro di estensione è la nuova forma di registro di plugin e illustra nei dettagli solo le informazioni sulle estensioni e i punti di estensione. L'API del registro di estensione ha la stessa importanza dell'API del registro del plugin (per ulteriori informazioni, fare riferimento a Registri).

Nel runtime di Eclipse 2.x, l'oggetto plugin presenta un certo numero di ruoli e responsabilità:

Nel runtime di Eclipse 3.0, questi ruoli e responsabilità sono suddivisi in oggetti distinti.

Insieme
Gli insiemi sono unità di modularità OSGi. Esiste un caricatore classi per ciascun insieme e classi di insiemi come Eclipse che caricano le immagini di dipendenza possono essere create. Gli insiemi hanno cicli di vita per l'avvio e l'arresto e il framework OSGi trasmette gli eventi correlati agli insiemi (ad esempio, l'installazione, la risoluzione, l'avvio, l'arresto, la disinstallazione, ...) alle parti interessate. A differenza della classe Plugin di Eclipse, la classe Insieme di OSGi non è estensibile. Ciò significa che gli sviluppatori non hanno la possibilità di definire la propria classe di insiemi.
BundleActivator
BundleActivator è un'interfaccia definita dal framework OSGi. Ciascun insieme può definire una classe di attivazione insiemi, come un plugin può definire la propria classe Plugin. La classe specificata viene istanziata dal framework e utilizzata per implementare l'elaborazione dei cicli di vita start() e stop(). Esiste tuttavia una grande differenza nella natura dell'elaborazione di questo ciclo di vita. In Eclipse, è frequente (anche se non consigliato) che le classi Plugin eseguano l'inizializzazione e la registrazione. In OSGi, gli attivatori possono eseguire solo la registrazione. L'esecuzione di molte inizializzazioni (e altri lavori) in BundleActivator.start(), minaccia la sicurezza del sistema.
BundleContext
BundleContexts sono i meccanismi OSGi per offrire le funzioni generali del sistema ai singoli insiemi. Ciascun insieme presenta un'istanza univoca e privata di BundleContext che è possibile utilizzare per accedere alle funzioni del sistema (ad esempio, getBundles() per individuare tutti gli insiemi del sistema).
Plugin
Il nuovo Plugin è molto simile alla classe Plugin originale di Eclipse con le seguenti eccezioni: gli oggetti Plugin non sono più richiesti o gestiti dal runtime e vari metodi risultano ora obsoleti. Si tratta essenzialmente di un meccanismo conveniente che fornisce un host di funzioni e meccanismi utili ma non è più necessario. Molte funzioni sono disponibili anche nella classe Piattaforma del runtime.

La classe Plugin implementa anche BundleActivator. Questa classe riconosce l'utilità di un oggetto centrale che rappresenta il ciclo di vita e la semantica di un plugin. Ciò tuttavia non sanziona l'inizializzazione delle strutture di dati comune nei plugin attuali. Non è possibile insistere troppo sul fatto che i plugin possano essere attivati, in quanto una classe periferica è stata utilizzata come riferimento durante la verifica di una classe in altri plugin. Ciò significa che il fatto che il plugin sia stato attivato non necessariamente indica che la funzione del plugin sia necessaria. L'utente è libero di definire una classe BundleActivator diversa o di non avere un attivatore di insiemi.

La procedura necessaria per portare una classe Plugin 2.x a Eclipse 3.0 dipende dall'attività della classe. Come precedentemente indicato, il ciclo di vita di avvio rientra in una delle seguenti categorie:

Inizializzazione
L'inizializzazione della struttura dei dati e dei modelli è spesso eseguita in Plugin.startup(). L'associazione naturale e ovvia prevede l'esecuzione di questo lavoro in una classe BundleActivator.start() lasciando la funzione su Plugin. Questa soluzione è sconsigliata. Come per i plugin 2.x, i plugin/insiemi 3.0 possono essere avviati per molti motivi diversi in molte circostanze diverse.
Di seguito viene riportato un esempio di Eclipse 2.0. In questa applicazione, esisteva un plugin che inizializzava un modello di grandi dimensioni che richiedeva il caricamento di un codice di 11MB e di dati di molti megabyte. In molti casi di utilizzo, questo plugin veniva attivato per individuare se l'icona del progetto presentata nel pannello di selezione doveva essere decorata con un tag particolare. Questa verifica non richiedeva alcuna inizializzazione in startup(), ma tutti gli utenti, in tutti i casi di utilizzo, dovevano pagare una penale di tempo e memoria per questa inizializzazione.
L'approccio alternativo prevede l'inizializzazione in uno stile classico. Ad esempio, anziché inizializzare i modelli al momento dell'attivazione del plugin/insieme, eseguire l'inizializzazione quando è realmente necessaria (ad esempio, in un metodo di accesso al modello centralizzato). In molti casi di utilizzo, questa procedura viene realizzata nella stesso periodo di tempo ma, in altri scenari, questo approccio può posticipare l'inizializzazione (per un periodo di tempo indefinito). Si consiglia di riconsiderare la strategia utilizzata per l'inizializzazione dei plugin 2.1.
Registrazione
L'avvio del plugin è un momento opportuno per registrare i listener, i servizi e altri elementi e per avviare i thread di elaborazione di sfondo (ad esempio, la ricezione su un socket). Plugin.start() può essere un'ubicazione adatta all'esecuzione di questo lavoro. Potrebbe essere utile anche posticipare il lavoro fino all'attivazione di altri elementi (ad esempio, l'uso di determinate funzioni o dati).
Dati globali del plugin
La classe Plugin può continuare ad esercitare questo ruolo. Il problema principale sta nel fatto che gli oggetti Plugin non sono più globalmente accessibili mediante un elenco gestito dal sistema. In Eclipse 2.x, era possibile individuare tutti gli oggetti Plugin mediante il registro del plugin. Ciò non è più possibile. In molte circostanze, questo tipo di accesso non è necessario. I Plugin a cui si accede mediante il registro sono in genere utilizzati come Plugin generici anziché richiamare i metodi specifici dei domini. Lo stesso livello di funzionalità può essere ottenuto accedendo e modificando gli oggetti dell'insieme corrispondente.

Registri e modello di plugin

Nel nuovo runtime, esiste una separazione tra le informazioni e le strutture necessarie per eseguire un plugin, correlate alle estensioni e ai punti di estensione di un plugin. Le prime vengono definite e gestite dalla specifica del framework OSGi. Le seconde sono concetti specifici di Eclipse e vengono aggiunte dal codice di runtime Eclipse. Di conseguenza, il registro del plugin originale e gli oggetti correlati sono stati suddivisi in insiemi OSGi e nel registro di estensione Eclipse.

Le parti di IPluginRegistry relative alla specifica dell'esecuzione (ad esempio, IPluginDescriptor, ILibrary, IPrequisite) sono considerate obsolete e le parti restanti relative alle estensioni e ai punti di estensione sono state spostate su IExtensionRegistry. Inoltre, gli oggetti cosiddetti modello relativi al registro del plugin sono ora considerati tutti obsoleti. Questi tipi sono stati presentati e istanziati dal runtime soprattutto per supportare strumenti come PDE. Sfortunatamente, si verifica spesso il caso in cui il livello di informazioni necessarie supera le funzioni o gli interessi del runtime (ad esempio, i numeri di riga per gli elementi plugin.xml) e, alla fine, i potenziali consumatori delle informazioni sul runtime devono mantenere le proprie strutture.

Nel nuovo runtime, sono state rivalutate le funzioni fornite e vengono ora garantite solo le funzioni essenziali per l'esecuzione del runtime o estremamente difficili da eseguire. Come illustrato in precedenza, gli oggetti modello di registro del plugin risultano obsoleti, dal momento che il plugin sta analizzando l'API. Il registro delle nuove estensioni mantiene le informazioni essenziali relative alle estensioni. Una nuova struttura state (fare riferimento a org.eclipse.osgi.service.resolver.State e simili) rappresenta e consente la modifica delle informazioni essenziali relative all'esecuzione.

Struttura del frammento NL

In Eclipse 3.0, la struttura del frammento NL è stata aggiornata per maggiore coerenza. In passato, le conversioni dei file come plugin.properties venivano eseguite all'interno dei JAR forniti dai frammenti. Poiché i file originali si trovano nella directory principale del plugin dell'host, un'ubicazione più coerente prevede che i file convertiti siano situati nella directory principale dei frammenti NL. Ad esempio,

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

Il file nl1.jar avrebbe in passato contenuto le conversioni del file plugin.properties. Questi file si trovano ora nella directory principale del frammento o il JAR contiene le conversioni di tutte le risorse convertibili (ad esempio, i file caricati mediante il caricatore classi) nel plugin dell'host.

Naturalmente, la struttura del frammento NL di Eclipse 2.1 è ancora supportata per i plugin dell'host 2.1 in esecuzione su Eclipse 3.0. Non è possibile tuttavia utilizzare un frammento NL 2.1 su un plugin 3.0. Il frammento deve essere aggiornato nella nuova struttura.

Panoramica sulle modifiche API

org.eclipse.core.boot (package org.eclipse.core.boot)

L'intero pacchetto org.eclipse.core.boot risulta obsoleto. BootLoader è stato unito a org.eclipse.core.runtime.Platform perché non ha più senso distinguere tra boot e runtime. In realtà, il plugin org.eclipse.core.boot è stato eliminato e il codice spostato nel nuovo runtime o nel livello di compatibilità.

IPlatformConfiguration è sempre stato un tipo definito da e per il componente di installazione/aggiornamento di Eclipse. Con la riorganizzazione del runtime, è possibile riportare questo tipo alla sua esatta ubicazione. Questa classe resta invariata ed è stata aggiunta al pacchetto come org.eclipse.update.configurator.IPlatformConfiguration.

IPlatformRunnable è stato spostato su org.eclipse.core.runtime.IPlatformRunnable.

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

Il metodo getDeclaringPlugin() (su entrambe le classi) fornisce un collegamento verso l'alto al plugin che dichiara rispettivamente l'estensione o il punto di estensione. Il nuovo modello di registro separa gli aspetti dell'esecuzione dei plugin dagli aspetti dell'estensione/punto di estensione e non contiene più l'elemento IPluginDescriptors. Gli utenti di questa API devono considerare il nuovo metodo getParentIdentifier() individuato su IExtension e IExtensionPoint.

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

Nel runtime originale, il registro del plugin manteneva un'immagine completa della configurazione del runtime. In Eclipse 3.0, questa immagine è suddivisa tra il framework OSGi e il registro dell'estensione. Queste classi sono quindi considerate obsolete. Le relative informazioni contengono i dettagli sulla procedura di aggiornamento del codice.

Piattaforma e plugin (package org.eclipse.core.runtime)

Nel nuovo runtime, gli oggetti Plugin non sono più gestiti dal runtime, per cui in genere non è possibile accedervi mediante la piattaforma. Allo stesso modo, il registro del plugin non esiste più o fornisce l'accesso ai descrittori del plugin. Sono tuttavia disponibili metodi di sostituzione adatti, illustrati nei dettagli nel Javadoc dei metodi obsoleti presenti in queste classi.

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

Tutti i tipi di questo pacchetto sono ora considerati obsoleti. Per ulteriori informazioni, fare riferimento alla sezione relativa ai registri.

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

I client del metodo IWorkspace.run(IWorkspaceRunnable,IProgressMonitor) devono rivedere l'utilizzo di questo metodo e considerare l'utilizzo di un metodo più complesso IWorkspace.run(IWorkspaceRunnable,ISchedulingRule,int,IProgressMonitor). Il vecchio metodo IWorkspace.run acquisisce un blocco sull'intero spazio di lavoro per la durata di IWorkspaceRunnable. Ciò significa che un'operazione eseguita con questo metodo non potrà mai essere eseguita insieme ad altre operazioni che modificano lo spazio di lavoro. In Eclipse 3.0, molte operazioni di lunga durata sono state spostate nei thread di sfondo, per cui la possibilità di conflitti tra le operazioni è di gran lunga aumentata. Se un'operazione modale di primo piano è bloccata da un'operazione di sfondo di lunga durata, l'UI risulta bloccata fino a quando l'operazione di sfondo non viene completata o fino a quando una delle operazioni non viene annullata.

La soluzione consigliata prevede il passaggio di tutti i riferimenti al vecchioIWorkspace.run per utilizzare il nuovo metodo con un parametro delle regole di pianificazione. La regola di pianificazione deve essere la regola più dettagliata che riassume le regole relative a tutte le modifiche di quella operazione. Se l'operazione tenta di modificare le risorse al di fuori dell'ambito della regola di pianificazione, si verifica un'eccezione di runtime. La regola di pianificazione precisa, richiesta dall'operazione di un determinato spazio di lavoro, non è specificata e può cambiare in base al fornitore di repository installato su un determinato progetto. Il factory IResourceRuleFactory deve essere utilizzato per ottenere la regola di pianificazione per un'operazione di modifica delle risorse. Se si desidera, una regola MultiRule può essere utilizzata per specificare più regole di risorse e il metodo appropriato MultiRule.combine può essere utilizzato per unire le regole di varie operazioni di modifica delle risorse.

Se non è richiesto alcun blocco, può essere utilizzata una regola di pianificazione null. Ciò consente all'eseguibile di modificare tutte le risorse dello spazio di lavoro, ma non impedisce ad altri thread di modificare lo spazio di lavoro contemporaneamente. Per modifiche semplici allo spazio di lavoro questa è spesso la soluzione più semplice e più adatta alla simultaneità.

IWorkbenchPage (package org.eclipse.ui)

IEditorDescriptor (package org.eclipse.ui)

ISharedImages (pacchetto org.eclipse.ui)

IWorkbenchActionConstants (pacchetto org.eclipse.ui)

IWorkbenchPreferenceConstants (pacchetto org.eclipse.ui)

IExportWizard (pacchetto org.eclipse.ui)

IImportWizard (pacchetto org.eclipse.ui)

INewWizard (pacchetto org.eclipse.ui)

WorkbenchHelp (pacchetto org.eclipse.ui.help)

IHelp (pacchetto org.eclipse.help)

ITextEditorActionConstants (pacchetto org.eclipse.ui.texteditor)

IAbstractTextEditorHelpContextIds (pacchetto org.eclipse.ui.texteditor)

BasicTextEditorActionContributor (pacchetto org.eclipse.ui.texteditor)

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

Punto di estensione annotationTypes (plugin org.eclipse.ui.editors)

Esiste ora una nozione esplicita di un tipo di annotazione. Fare riferimento a Annotation.getType() e Annotation.setType(). Il tipo di annotazione può cambiare con il tempo. Un nuovo punto di estensione è stato aggiunto per la dichiarazione dei tipi di annotazione: "org.eclipse.ui.editors.annotationTypes". Un tipo di annotazione presenta un nome e può essere dichiarato come un sottotipo di un altro tipo di annotazione dichiarato. Una dichiarazione del tipo di annotazione può utilizzare anche gli attributi "markerType" e "markerSeverity" per specificare che gli indicatori di un determinato tipo e di una determinata gravità devono essere rappresentati negli editor di testo come annotazioni di un particolare tipo di annotazione. Gli attributi "markerType" e "markerSeverity" in "org.eclipse.ui.editors.markerAnnotationSpecification" non devono essere più utilizzati. Le specifiche relative alle annotazioni degli indicatori diventano quindi indipendenti dagli indicatori e il nome diventa quindi fuorviante. Tuttavia, il nome viene conservato, per garantire la compatibilità con le versioni precedenti.

Le istanze delle sottoclassi di AbstractMarkerAnnotationModel individuano automaticamente e impostano i tipi di annotazione corretti per le annotazioni create dagli indicatori. Per richiamare in modo programmatico il tipo di annotazione per un determinato indicatore o una determinata coppia di markerType e markerSeverity, utilizzare org.eclipse.ui.texteditor.AnnotationTypeLookup.

L'accesso alla gerarchia dei tipi di annotazione viene fornita da IAnnotationAccessExtension. Per un determinato tipo di annotazione, è possibile richiamare la catena di supertipi e verificare se un tipo di annotazione rappresenta un sottotipo di un altro tipo di annotazione. DefaultMarkerAnnotationAccess implementa questa interfaccia.

Punto di estensione markerAnnotationSpecification (plugin org.eclipse.ui.editors)

Il tipo di annotazione è la chiave con cui individuare la specifica dell'annotazione relativa all'indicatore associato. Poiché i tipi di annotazione possono estendersi ad altri tipi di annotazione, esiste una relazione implicita tra le specifiche delle annotazioni relative agli indicatori. Una specifica di annotazione relativa ad un indicatore per un determinato tipo di annotazione viene completata dalle specifiche delle annotazioni relative agli indicatori per i supertipi del tipo di annotazione specificato. Quindi, la specifica dell'annotazione relativa all'indicatore non deve essere completata come richiesto in precedenza. Le specifiche delle annotazioni relative agli indicatori sono richiamate da AnnotationPreferences. Utilizzando org.eclipse.ui.texteditor.AnnotationPreferenceLookup, è possibile richiamare una preferenza di annotazione per un determinato tipo di annotazione, in grado di eseguire in modo trasparente il completamento della preferenza insieme alla catena di supertipi di annotazioni.

La specifica dell'annotazione relativa all'indicatore è stata estesa con tre attributi supplementari per consentire la definizione di aspetti personalizzati di un determinato tipo di annotazione nel righello verticale. Questi attributi sono:"icon", "symbolicIcon" e "annotationImageProvider". Il valore di "icon" è il percorso a un file contenente l'immagine dell'icona. Il valore di "symbolicIcon" può essere "error", "warning", "info", "task", "bookmark". L'attributo "symbolicIcon" viene utilizzato per indicare la piattaforma con cui deve essere rappresentata l'annotazione, con le stesse immagini utilizzate dalla piattaforma per presentare rispettivamente errori, avvisi, informazioni e bookmark. Il valore di "annotationImageProvider" è una classe che implementa org.eclipse.ui.texteditor.IAnnotationImageProvider, che consente una presentazione personalizzata dell'annotazione.

Il righello verticale utilizza i valori di IAnnotationAccess/IAnnotationAccessExtension associati per rappresentare le annotazioni. Il righello verticale non richiama più Annotation.paint. In generale, le annotazioni non rappresentano più se stesse. I metodi "paint" e "getLayer" sono considerati obsoleti per rendere l'annotazione indipendente dall'UI. DefaultMarkerAnnotationAccess viene utilizzato come implementazione predefinita di IAnnotationAccess/IAnnotationAccessExtension. DefaultMarkerAnnotationAccess implementa la seguente strategia per la rappresentazione delle annotazioni: se un'annotazione implementa IAnnotationPresentation, viene richiamato IAnnotationPresentation.paint. Altrimenti, nella preferenza dell'annotazione viene ricercato il fornitore immagini delle annotazioni. Il fornitore immagini delle annotazioni è disponibile solo se specificato e se il plugin che definisce la specifica dell'annotazione relativa all'indicatore è già stato caricato. Se esiste un fornitore immagini delle annotazioni, la chiamata viene inoltrata a tale fornitore. Altrimenti, viene ricercato il valore "icon" specificato. "symbolicIcon" viene utilizzato come fallback finale. Per la rappresentazione delle annotazioni, è importante il livello di presentazione delle annotazioni. DefaultMarkerAnnotationAccess ricerca il livello di presentazione utilizzando la seguente strategia: se la preferenza dell'annotazione specifica un livello di presentazione, viene utilizzato il livello specificato. Se non è specificato alcun livello e l'annotazione implementa IAnnotationPresentation, viene utilizzato IAnnotationPresentation.getLayer, altrimenti viene restituito il livello di presentazione predefinito (pari a 0).

Migrazione al punto di estensione annotationTypes (plugin org.eclipse.ui.editors)

I seguenti tipi di annotazione sono dichiarati dal plugin 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'estensione markerAnnotationSpecification definita non fornisce più gli attributi "markerType" e "markerSeverity". Viene definito l'attributo "symbolicIcon" con il relativo valore. Non vengono più richiamati MarkerAnnotation.paint e MarkerAnnotation.getLayer, la sostituzione di questi metodi, ad esempio, non ha alcun effetto. I client interessati devono implementare IAnnotationPresentation.

ILaunchConfigurationType (pacchetto org.eclipse.debug.core)

Con l'introduzione delle modalità di avvio estensibili nella versione 3.0, più delegatidi avvio possono esistere per ciascun tipo di configurazione di avvio. I rilasci precedenti al 3.0 supportavano solo un delegato di avvio per ciascun tipo di configurazione di avvio. Il metodo ILaunchConfigurationType.getDelegate() è considerato ora obsoleto. Il metodo getDelegate(String mode) deve essere utilizzato in sostituzione per richiamare il delegato di avvio per una specifica modalità di avvio. Il metodo obsoleto è stato modificato per restituire il delegato di avvio per la modalità run.

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

I gruppi di schede di avvio e le schede di avvio non sono più notificate del completamento di un'operazione di avvio. Il metodo launched(ILaunch) nelle interfacce ILaunchConfigurationTab e ILaunchConfigurationTabGroup è considerato obsoleto e non viene più richiamato. Utilizzare questo metodo per la funzione di avvio è sempre stato un problema, dal momento che le schede vengono visualizzate solo quando l'avvio viene eseguito dalla finestra di dialogo di avvio. Inoltre, con l'introduzione dell'avvio di sfondo, questo metodo non può più essere richiamato, dal momento che la finestra di dialogo di avvio deve essere chiusa prima che venga visualizzato l'oggetto di avvio risultante.

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

Due metodi sono stati aggiunti all'interfaccia ILaunchConfigurationTab - attivati e disattivati. Questi due metodi del ciclo di vita vengono richiamati quando una scheda viene rispettivamente inserita e disinserita. Le implementazioni esistenti di ILaunchConfigurationTab che impostano come sottoclasse la classe astratta fornita dal plugin di debug (AbstractLaunchConfigurationTab) sono compatibili a livello binario, dal momento che i metodi sono implementati nella classe astratta.

Nei rilasci precedenti, una scheda conteneva il messaggio initializeFrom al momento dell'attivazione e performApply al momento della disattivazione. In questo modo, il framework della scheda della configurazione di avvio forniva la comunicazione tra schede mediante una configurazione di avvio (aggiornando la configurazione con i valori correnti degli attributi quando la scheda viene chiusa e aggiornando la scheda appena immessa). Tuttavia, poiché molte schede non eseguono la comunicazione tra schede, ciò può essere inefficace. Non esiste alcun modo per distinguere tra una scheda da attivare e una scheda che visualizza una configurazione di avvio selezionata per la prima volta. I metodi aggiunti di recente consentono alle schede di distinguere tra attivazione e inizializzazione e tra disattivazione e salvataggio dei valori correnti.

L'implementazione predefinita di activated, fornita dalla scheda astratta, richiama initializeFrom. Quindi, l'implementazione predefinita di deactivated richiama performApply. Le schede che desiderano trarre vantaggio dalla nuova API devono sostituire questi metodi come necessario. In genere, per le schede che non eseguono la comunicazione tra schede, l'approccio consigliato prevede la nuova implementazione di questi metodi.

Tipo di punto di estensione launchConfigurationTabGroup (pacchetto org.eclipse.debug.ui)

Nei rilasci precedenti, il passaggio da una prospettiva ad un'altra era specificato su una configurazione di avvio, mediante gli attributi della configurazione di avvio ATTR_TARGET_DEBUG_PERSPECTIVE e ATTR_TARGET_RUN_PERSPECTIVE. Con l'aggiunta delle modalità di avvio estensibili nella versione 3.0, questo approccio non viene più utilizzato. Il passaggio da una prospettiva ad un'altra viene ora specificato su una base per tipo di configurazione di avvio, per ciascuna modalità di avvio supportata da un tipo di configurazione di avvio. L'API è stata aggiunta a DebugUITools per impostare e richiamare la prospettiva associata ad un tipo di configurazione di avvio relativo a una specifica modalità di avvio.

Inoltre, facoltativamente, l'elemento launchMode è stato aggiunto al punto di estensione launchConfigurationTabGroup, consentendo ad un gruppo di schede di specificare una prospettiva predefinita per un tipo e una modalità di configurazione di avvio.

Dall'interfaccia utente Eclipse, gli utenti possono modificare la prospettiva associata ad un tipo di configurazione di avvio aprendo la finestra di dialogo della configurazione di avvio e selezionando un nodo per il tipo di configurazione di avvio nella struttura ad albero, anziché una singola configurazione. Viene visualizzata una scheda che consente all'utente di impostare una prospettiva con ciascuna modalità di avvio supportata.

[solo JDT] IVMRunner (pacchetto org.eclipse.jdt.launching)

Due metodi sono stati aggiunti alla classe VMRunnerConfiguration per supportare l'impostazione e il richiamo delle variabili di ambiente. Gli implementatori di IVMRunner devono richiamare VMRunnerConfiguration.getEnvironment() e trasferire quell'ambiente nel JVM eseguito. I client che utilizzano DebugPlugin.exec(String[] cmdLine, File workingDirectory) possono eseguire questa operazione richiamando DebugPlugin.exec(String[] cmdLine, File workingDirectory, String[] envp). È sufficiente trasferire semplicemente il risultato di getEnvironment().

[solo JDT] VMRunnerConfiguration e classi bootstrap (pacchetto org.eclipse.jdt.launching)

Nei rilasci precedenti, VMRunnerConfiguration presentava un attributo per descrivere un percorso di boot. L'attributo è un insieme di stringhe da specificare nell'argomento -Xbootclasspath. Tre nuovi attributi sono stati aggiunti a VMRunnerConfiguration per supportare i JVM che precedono e seguono il percorso di boot. I nuovi metodi/attributi aggiunti sono:

Il vecchio attributo, getBootClassPath(), esiste ancora e contiene un percorso completo equivalente a quello dei tre nuovi attributi. Tuttavia, VMRunners, che supporta le opzioni del nuovo percorso di boot, trae vantaggio dai nuovi attributi.

[solo JDT] Supporto perfezionato per copie di lavoro (pacchetto org.eclipse.jdt.core)

La funzione di copia di lavoro del modello Java è stata revocata nella versione 3.0 per fornire una funzione perfezionata. Prima della versione 3.0, il modello Java consentiva la creazione di singole copie di lavoro di unità di compilazione. Le modifiche potevano essere effettuate alla copia di lavoro ed essere successivamente sottoposte al commit. Esisteva un supporto per l'analisi limitata di una copia di lavoro nel contesto del resto del modello Java. Tuttavia, non esisteva alcun modo per tenere in considerazione queste analisi più di una copia di lavoro alla volta.

Le modifiche nella versione 3.0 consentono di creare e gestire gli insiemi di copie di lavoro delle unità di compilazione e di eseguire le analisi in presenza di tutte le copie di lavoro di un insieme. Ad esempio, è ora possibile per un client come JDT eseguire il refactoring per creare copie di lavoro per una o più unità di compilazione, il che significa considerare la modifica e quindi risolvere i riferimenti ai tipi tra le copie di lavoro. In passato, ciò era possibile solo dopo il commit delle modifiche alle copie di lavoro dell'unità di compilazione.

L'API del modello Java viene modificata in 2 modi per aggiungere questo supporto perfezionato:

(1) La funzionalità rilevata in precedenza su IWorkingCopy e ereditata da ICompilationUnit è stata consolidata in ICompilationUnit. L'interfaccia IWorkingCopy era utilizzata solo in questa circostanza ed era più generale di quanto fosse necessario. Questa modifica semplifica l'API. IWorkingCopy è considerato obsoleto. Altre circostanze dell'API in cui viene utilizzato IWorkingCopy come parametro o tipo di risultato sono considerate obsolete, i metodi API di sostituzione menzionano ICompilationUnit anziché IWorkingCopy.

(2) L'interfaccia IBufferFactory è stata sostituita da WorkingCopyOwner. Il supporto perfezionato per le copie di lavoro richiede che ci sia un oggetto per gestire le copie di lavoro. Nonostante IBufferFactory si trovi nella corretta posizione, il nome non esprime adeguatamente come funziona il meccanismo della nuova copia di lavoro. WorkingCopyOwner è molto più indicativo. Inoltre, WorkingCopyOwner è dichiarato come una classe astratta, anziché come un'interfaccia, per consentire alla nozione di proprietario della copia di lavoro di evolversi in futuro. L'unico metodo presente su IBufferFactory si sposta su WorkingCopyOwner. WorkingCopyOwner non implementa IBufferFactory per specificare che IBufferFactory fa parte del passato. IBufferFactory è considerato obsoleto. Altre circostanze dell'API in cui IBufferFactory viene visualizzato come parametro o tipo di risultato sono considerate obsolete, i metodi API di sostituzione menzionano WorkingCopyOwner anziché IBufferFactory.

Queste modifiche non interrompono la compatibilità binaria.

Durante la migrazione, tutti i riferimenti al tipo IWorkingCopy devono fare riferimento a ICompilationUnit. L'unica implementazione di IWorkingCopy implementa anche ICompilationUnit, il che significa che il cast degli oggetti di tipo IWorkingCopy può essere eseguito tranquillamente su ICompilationUnit.

Una classe che implementa IBufferFactory deve essere sostituita da una sottoclasse di WorkingCopyOwner. Nonostante WorkingCopyOwner non implementi IBufferFactory, è possibile dichiarare la sottoclasse WorkingCopyOwner che implementa IBufferFactory, creando un ponte tra il vecchio e il nuovo (IBufferFactory dichiara createBuffer(IOpenable), mentre WorkingCopyOwner dichiara createBuffer(ICompilationUnit); ICompilationUnit estende IOpenable).

Poiché le modifiche che coinvolgono IWorkingCopy e IBufferFactory sono collegate, si consiglia di utilizzarle contemporaneamente. I dettagli dell'obsolescenza sono i seguenti:

Ristrutturazione del plugin org.eclipse.help

Il plugin org.eclipse.help, utilizzato per contenere le API e i punti di estensione per contribuire ed estendere il sistema della guida e per visualizzare la guida, contiene ora solo le API e i punti di estensione per contribuire ed accedere alle risorse della guida. Una parte dell'implementazione predefinita dell'UI della guida contenuta in questo plugin è stata spostata in un nuovo plugin org.eclipse.help.base, insieme alle API per l'estensione dell'implementazione. Le API e il punto di estensione per fornire l'UI della guida e visualizzare la guida sono stati spostati nel plugin org.eclipse.ui. Questa ristrutturazione fornisce alle applicazioni maggiore flessibilità, tenendo considerazione del sistema della guida, la nuova struttura consente alle applicazioni basate sul workbench generico di fornire l'implementazione della guida e/o dell'UI della guida o di omettere il sistema della guida interamente.

Poiché i punti di estensione e i pacchetti API interessati possono essere utilizzati solo dal sistema della guida, è improbabile che i plugin esistenti vengano influenzati da questa modifica. Sono inclusi in questa sezione solo per completamento:

Nuova API dell'UI di ricerca

Una nuova API per l'implementazione delle ricerche personalizzate è stata aggiunta nella versione 3.0. L'API originale è considerata obsoleta nella versione 3.0 e si consiglia ai client di utilizzare la nuova API presente nei pacchetti org.eclipse.search.ui e org.eclipse.search.ui.text.

I client devono creare le implementazioni di ISearchQuery, ISearchResult e ISearchResultPage. L'implementazione di ISearchResultPage deve essere fornita nel nuovo punto di estensione org.eclipse.search.searchResultViewPages.

Le implementazioni predefinite per ISearchResult e ISearchResultPage sono fornite nel pacchetto org.eclipse.search.ui.text.

Messaggi null in MessageBox e DirectoryDialog (pacchetto org.eclipse.swt.widgets)

Prima della versione 3.0, la chiamata di DirectoryDialog.setMessage(String string) o MessageBox.setMessage(String string) di SWT con un valore null per la stringa avrebbe generato una finestra di dialogo senza alcun testo nel titolo. Questo comportamento non è stato specificato (il valore null non è mai stato consentito) e crea problemi con getMessage che non può restituire un valore null. Nella versione 3.0, un valore null dà come risultato un'eccezione IllegalArgumentException e la specifica è stata modificata per precisare ciò, portando tale valore nella riga con il metodo della superclasse Dialog.setMessage. Se si utilizzaDialog.setMessage, verificare che la stringa trasferita non sia mai null. Trasferire semplicemente una stringa vuota, se si desidera una finestra di dialogo senza testo nel titolo.

Miglioramento del feedback di avanzamento modale

Supportare operazioni contemporanee richiede modi più sofisticati per mostrare l'avanzamento modale. Come parte del tentativo per migliorare le prestazioni, è stato implementato un supporto supplementare di avanzamento nella classe IProgressService. Il modo esistente per visualizzare l'avanzamento con ProgressMonitorDialog funziona ancora. Tuttavia, per migliorare l'esperienza dell'utente, si consiglia di migrare alla nuova classe IProgressService.

Il documento Showing Modal Progress in Eclipse 3.0 descrive la procedura per la migrazione alla nuova classe IProgressService.

Gruppi di azioni di debug rimossi

Il punto di estensione Gruppi di azioni di debug (org.eclipse.debug.ui.debugActionGroups) è stato rimosso. In Eclipse 3.0, il workbench ha introdotto il supporto per le attività mediante il punto di estensione org.eclipse.platform.ui.activities. Questo supporto fornisce tutti gli elementi dei gruppi di azioni di debug, è più semplice da utilizzare (supporta i modelli anziché specificare tutte le azioni in modo esaustivo) e presenta un'API programmatica. Se i riferimenti al vecchio punto di estensione non vengono rimossi non viene generato alcun errore. I riferimenti al punto di estensione verranno semplicemente ignorati. I fornitori del prodotto sono incoraggiati ad utilizzare il supporto Attività del workbench per associare le azioni del debugger specifiche della lingua con le attività specifiche della lingua (ad esempio, le azioni di debug C++ possono essere associate ad un'attività definita "Sviluppo di C++").

BreakpointManager può essere disabilitato

IBreakpointManager definisce ora i metodi setEnabled(boolean) e isEnabled(). Quando viene disabilitato il gestore del punto di interruzione, i debugger devono ignorare tutti i punti di interruzione registrati. La piattaforma di debug fornisce anche un nuovo meccanismo listener, IBreakpointManagerListener, che consente la notifica ai client registrati con il gestore dei punti di interruzione quando l'abilitazione viene modificata. La vista Punti di interruzione richiama l'API da una nuova azione di attivazione, che consente all'utente di "ignorare tutti i punti di interruzione." I debugger che non rispettano l'abilitazione del gestore dei punti di interruzione appaiono danneggiati, se l'utente tenta di utilizzare questa funzione.

[solo JDT] Partecipanti di ricerca Java (pacchetto org.eclipse.jdt.core.search)

I linguaggi simili a Java (quali JSP, SQLJ, JWS, ecc.) devono essere in grado di partecipare alla ricerca Java. In particolare, gli implementatori di questi linguaggi devono essere in grado di:

Un simile implementatore viene definito partecipante di ricerca. Questo implementatore estende la classe SearchParticipant. I partecipanti di ricerca vengono trasferiti per la ricerca delle query (fare riferimento a SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)).

Per l'indicizzazione o l'individuazione di corrispondenze, un partecipante di ricerca deve definire una sottoclasse di SearchDocument che possa richiamare il contenuto del documento sostituendo getByteContents() o getCharContents(). Un'istanza di questa sottoclasse viene restituita in getDocument(String).

Un partecipante di ricerca che desidera indicizzare alcuni documenti utilizza SearchParticipant.scheduleDocumentIndexing(SearchDocument, IPath) per pianificare l'indicizzazione di un determinato documento nell'indice stabilito. Quando il documento è pronto per l'indicizzazione, il framework sottostante richiama SearchParticipant.indexDocument(SearchDocument, IPath). Il partecipante di ricerca richiama quindi il contenuto del documento, lo analizza e aggiunge le voci di indice, utilizzando SearchDocument.addIndexEntry(char[], char[]).

Una volta eseguita l'indicizzazione, è possibile interrogare gli indici e individuare le corrispondenze utilizzando SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor). Viene prima richiesto ciascun partecipante di ricerca per gli indici necessari a questa query utilizzando SearchParticipant.selectIndexes(SearchPattern, IJavaSearchScope). Per ciascuna voce di indice che corrisponde a un determinato modello, viene creato un documento di ricerca richiedendo il partecipante di ricerca (fare riferimento a getDocument(String)). Tutti questi documenti vengono trasferiti al partecipante di ricerca, in modo che possa individuare le corrispondenze utilizzando locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor). Il partecipante di ricerca notifica il SearchRequestor delle corrispondenze della ricerca utilizzando acceptSearchMatch(SearchMatch) e trasferendo un'istanza di una sottoclasse di SearchMatch.

Un partecipante di ricerca può delegare parte di questo lavoro al partecipante di ricerca Java predefinito. Un'istanza di questo partecipante predefinito viene ottenuta utilizzando SearchEngine.getDefaultSearchParticipant(). Ad esempio, quando si richiede di individuare le corrispondenze, un partecipante SQLJ può creare documenti .java dai documenti .sqlj e delegare il lavoro al partecipante predefinito trasferendolo sui documenti .java.