La struttura del testo della piattaforma definisce un modello di documento per il testo e fornisce un visualizzatore che visualizza il testo servendosi di questo modello. Verrà illustrato come l'editor di esempio Java utilizza questo modello. Non verranno analizzati i meccanismi di base della registrazione di un estensione di un editor, dal momento che questo aspetto è stato già affrontato nella sezione relativa a org.eclipse.ui.editors. Verranno invece descritte le specifiche relative alle modalità di implementazione della classe dell'editor nell'esempio.
Nel workbench, un editor viene generalmente aperto quando l'utente seleziona un elemento di dominio (ad esempio un file o un elemento archiviato all'interno di un file di archivio) e lo apre. Quando viene creato, l'editor viene associato all'input di un editor (IEditorInput), che descrive l'oggetto sottoposto a modifica.
L'esempio di editor Java si apre quando l'utente apre un file con estensione "*.jav". In questo caso, l'input dell'editor è costituito da IFileEditorInput. La struttura del testo della piattaforma non utilizza tutto l'input dell'editor. Per l'input si serve di un modello di presentazione, denominato IDocument, che consente di visualizzare effettivamente e di modificare il testo.
Ciò significa che deve esistere un modo per eseguire l'associazione tra un modello di dominio previsto (l'input dell'editor) e il modello di presentazione. Tale associazione viene definita in un IDocumentProvider. Dato un input dell'editor, il fornitore di documenti restituisce un IDocument appropriato.
L'esempio di editor Java definisce un JavaDocumentProvider che restituisce il documento appropriato. Come viene stabilita la relazione tra il fornitore del documento appropriato e l'estensione "*.jav"? Tale relazione viene stabilita nell'estensione org.eclipse.ui.documentProviders. Questa estensione viene utilizzata per definire l'associazione tra i tipi di file e i fornitori di documenti. L'esempio definisce il fornitore di documenti come segue:
<extension point="org.eclipse.ui.documentProviders"> <provider extensions="jav" class="org.eclipse.ui.examples.javaeditor.JavaDocumentProvider" id="org.eclipse.ui.examples.javaeditor.JavaDocumentProvider"> </provider> </extension>
Quando l'utente apre un file con l'estensione specificata, il workbench gestisce i dettagli relativi alla creazione dell'istanza del fornitore di documenti. Il workbench crea l'istanza del fornitore di documenti solo una volta e condivide l'istanza tra editor diversi.
Non è necessario che il plug-in utilizzi questo punto di estensione per registrare il rispettivo fornitore di documenti. Un altro modo per associare un fornitore di documenti a un editor consiste nel fare in modo che sia il plug-in stesso a gestire il fornitore di documenti. Questa situazione si verifica generalmente nella classe del plug-in in uso. Quando un elemento di input viene impostato nell'editor, l'editor chiede alla classe del plug-in il fornitore di documenti appropriato. Il plug-in può gestire la creazione e i riferimenti al fornitore di documenti. Questa tecnica potrebbe risultare vantaggiosa quando il fornitore di documenti è impegnato in un'operazione speciale di inizializzazione o in un'altra elaborazione. Vedere ClassFileEditor nella strumentazione JDT per un esempio in merito.
Una volta associato il fornitore di documenti appropriato a un editor, la principale attività di quest'ultimo consiste nel creare un documento dall'input dell'editor e nel configurare un oggetto appropriato per la suddivisione del documento in partizioni.
Verranno illustrati i documenti e le partizioni nelJavaDocumentProvider. Quando viene creato un documento, un IDocumentPartitioner viene creato e impostato nel documento.
protected IDocument createDocument(Object element) throws CoreException { IDocument document= super.createDocument(element); if (document != null) { IDocumentPartitioner partitioner= createJavaPartitioner(); document.setDocumentPartitioner(partitioner); partitioner.connect(document); } return document; }
Lo strumento di suddivisione dei documenti è responsabile della suddivisione del documento in porzioni che non si sovrappongono, denominate partizioni. Le partizioni (rappresentate in ITypedRegion) sono utili per il trattamento diversificato delle sezioni del documento che tenga conto di funzioni quali formattazione o evidenziazione della sintassi.
Nel caso dell'esempio dell'editor Java, il documento viene suddiviso in partizioni che rappresentano i commenti javadoc, i commenti su più righe e tutti gli altri elementi. A ciascuna regione viene assegnato un tipo di contenuto e la relativa posizione nel documento. Le posizioni vengono aggiornate in base alle modifiche apportate al testo dall'utente.
L'implementazione appropriata per lo strumento di suddivisione in partizioni dipende dal singolo editor. In org.eclipse.jface.text.rules viene fornito supporto per la scansione del documento basata su regole. L'utilizzo di una scansione basata su regole consente l'utilizzo da parte di un editor del DefaultPartitioner fornito dalla struttura.
private IDocumentPartitioner createJavaPartitioner() { return new DefaultPartitioner(getJavaPartitionScanner(), TYPES); }
RuleBasedPartitionScanner è la superclasse per gli scanner basati su regole. Le sottoclassi sono responsabili del conteggio e dell'implementazione delle regole da utilizzare per distinguere token quali i delimitatori di riga, lo spazio e modelli generici durante la scansione di un documento. Lo JavaPartitionScanner dell'esempio definisce regole per la distinzione dei commenti a riga singola, le costanti di caratteri, la javadoc, i commenti su più righe e le parole. Questa operazione viene eseguita nel costruttore dello scanner:
public JavaPartitionScanner() { super(); IToken javaDoc= new Token(JAVA_DOC); IToken comment= new Token(JAVA_MULTILINE_COMMENT); List rules= new ArrayList(); // Aggiungere una regola per i commenti a riga singola. rules.add(new EndOfLineRule("//", Token.UNDEFINED)); // Aggiungere una regola per stringhe e costanti di caratteri. rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); // Aggiungere una speciale regola per la distinzione tra maiuscole e minuscole. rules.add(new WordPredicateRule(comment)); // Aggiungere regole per commenti multilinea e javadoc. rules.add(new MultiLineRule("/**", "*/", javaDoc, (char) 0, true)); rules.add(new MultiLineRule("/*", "*/", comment, (char) 0, true)); IPredicateRule[] result= new IPredicateRule[rules.size()]; rules.toArray(result); setPredicateRules(result); }
Vedere le classi in org.eclipse.jface.text.rules per ulteriori dettagli sulla definizione di regole e sui tipi di regole disponibili. L'argomento degli scanner verrà ripreso quando verrà illustrata la colorazione della sintassi.
Oltre a fornire un documento appropriato per l'input di un editor, un'altra attività importante di un fornitore di documenti consiste nel fornire un IAnnotationModel appropriato da utilizzare con l'input di un editor. Questo modello viene utilizzato per la gestione delle annotazioni aggiunte ai documenti. Se il fornitore di documenti fornisce il modello, l'editor potrà utilizzare un modello appropriato per il tipo di contenuto. Le annotazioni verranno illustrate più dettagliatamente nella sezione successiva.