Dokumenty a segmentace

Textový rámec platformy definuje model dokumentu pro text a poskytuje prohlížeč, který text s použitím tohoto modelu zobrazuje. Začneme tím, že se podíváme na ukázkový editor jazyka Java a jak je jím tento model používán. Nebudeme se zaměřovat na základní mechanizmy registrace rozšíření editoru, protože to jsme již viděli v oddílu, který popisuje org.eclipse.ui.editors.  Místo toho se podíváme na specifika implementace třídy editoru v tomto příkladu.

Poskytovatelé dokumentů a dokumenty

V pracovní ploše se editor zpravidla otevře, když uživatel vybere prvek domény (například soubor nebo prvek uložený uvnitř archivního souboru) a otevře jej.  Když se editor vytvoří, asociuje se se vstupem editoru (IEditorInput), který popisuje upravovaný objekt.

Ukázkový editor jazyka Java se otevře, když uživatel otevře soubor s příponou "*.jav".   V tomto případě je vstupem editoru IFileEditorInput.  Textový rámec platformy o samotném vstupu editoru téměř nic nepředpokládá.  Pracuje s prezentačním modelem vstupu, nazvaným IDocument, aby mohl efektivně zobrazovat text a manipulovat s ním.

To znamená, že musí existovat způsob, jak mapovat z očekávaného modelu domény (vstupu editoru) na prezentační model.   Toto rozhraní definuje poskytovatel dokumentů IDocumentProvider.  Pro daný vstup editoru vrací poskytovatel dokumentů příslušný IDocument.

Ukázkový editor jazyka Java dědí TextFileDocumentProvider definovaný modulem plug-in org.eclipse.ui.editors. Rozšíření org.eclipse.ui.editors.documentProviders se používá k definici mapování mezi typy vstupů editorů (nebo příponami souborů) a poskytovateli dokumentů. Modul plug-in editorů definuje svého poskytovatele dokumentů takto:

   <extension   
         point="org.eclipse.ui.editors.documentProviders">
<provider 
            class="org.eclipse.ui.editors.text.TextFileDocumentProvider"
            inputTypes="org.eclipse.ui.IStorageEditorInput"
            id="org.eclipse.ui.editors.text.StorageDocumentProvider">
      </provider>
    </extension>

Tento bod rozšíření umožňuje modulům plug-in registrovat poskytovatele dokumentů a asociovat je buď s příponou souboru, nebo třídou vstupu editoru. Protože ukázkový editor jazyka Java nedefinuje své vlastní rozšíření poskytovatele dokumentů, dědí obecného poskytovatele dokumentů, který je uveden pro všechny vstupy typu IStorageEditorInput. Když uživatel otevře soubor k úpravám, platforma spravuje podrobnosti vytváření náležité instance poskytovatele dokumentů. Je-li pro příponu souboru registrován určitý poskytovatel dokumentů, použije se. Není-li pro příponu souboru dán poskytovatel dokumentů, použije se k nalezení odpovídajícího poskytovatele typ vstupu editoru.

Díky použití obecného poskytovatele dokumentů platformy může ukázkový editor jazyka Java využívat všechny funkce poskytovatele dokumentů, například ukládání souboru do vyrovnávací paměti a další optimalizace.

Nastavení dokumentu

Editor jazyka Java používá textového poskytovatele dokumentů platformy, jak tedy může dodat specializované chování pro manipulaci se soubory v jazyce Java?

Rozšíření org.eclipse.core.filebuffers.documentSetup se používá k definování mapování mezi příponami souborů a účastníkem nastavení, IDocumentSetupParticipant. Účastník nastavení vybaví dokument speciálními funkcemi poté, co byl poskytnut editoru.

<extension   
	id="ExampleJavaDocumentSetupParticipant"
	name="%documentSetupParticipantName"
	point="org.eclipse.core.filebuffers.documentSetup">
	<participant
		extensions="jav"
		class="org.eclipse.ui.examples.javaeditor.JavaDocumentSetupParticipant">
	</participant>
    </extension>

Tato definice rozšíření je tím, co dává příkladu možnost nastavit dokumenty pro úlohy specifické pro jazyk Java. Takže, co JavaDocumentSetupParticipant dělá? Podíváme se na zjednodušenou verzi metody setup.

 	public void setup(IDocument document) {
		...
		IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES);
		partitioner.connect(document);
		...
	}

Nastavovací kód zkonfiguruje objekt nazvaný segmentovač ("partitioner").

Segmentace

Segmentovač (IDocumentPartitioner) odpovídá za rozdělení dokumentu na nepřekrývající se oblasti nazývané segmentace.  Segmentace (které reprezentuje ITypedRegion) jsou užitečné, chceme-li s různými sekcemi dokumentu zacházet různě ve funkcích, jako je zvýrazňování syntaxe nebo formátování.

V případě ukázkového editoru jazyka Java je dokument rozdělen do segmentů, které představují komentáře ve stylu dokumentace Javadoc, víceřádkové komentáře, a vše ostatní.   Každému regionu je přiřazen typ obsahu a jeho pozice v dokumentu.   Pozice se aktualizují s tím, jak uživatel text upravuje.

Vytváření segmentů dokumentu na bázi pravidel

Je na každém editoru, aby určil odpovídající implementaci segmentovače dokumentu. org.eclipse.jface.text.rules poskytuje podporu pro procházení dokumentu na bázi pravidel.  Použití skeneru na bázi pravidel editoru umožňuje použít FastPartitioner, který poskytuje rámec.

IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES);

RuleBasedPartitionScannerje supertřída pro skenery na bázi pravidel.  Podtřídy jsou zodpovědné za vytvoření výčtu a implementaci pravidel, která by se měla při procházení dokumentu použít pro rozlišení tokenů, například oddělovačů řádků, neviditelných znaků a obecných vzorů.  JavaPartitionScanner v příkladu definuje pravidla pro rozlišení jednořádkových komentářů, znakových konstant, dokumentace Javadoc, víceřádkových komentářů a slov.  To se provede v konstruktoru skeneru:

public JavaPartitionScanner() {
	super();
	IToken javaDoc= new Token(JAVA_DOC);
	IToken comment= new Token(JAVA_MULTILINE_COMMENT);

	List rules= new ArrayList();
	// Přidat pravidlo pro jednořádkové komentáře.
	rules.add(new EndOfLineRule("//", Token.UNDEFINED)); 

	// Přidat pravidlo pro řetězce a znakové konstanty.
	rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); 
	rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); 

	// Přidat pravidlo pro speciální případ slova.
	rules.add(new WordPredicateRule(comment));

	// Přidat pravidla pro víceřádkové komentáře a dokumentaci 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);
}

Viz třídy v org.eclipse.jface.text.rules, kde najdete další podrobnosti o definování pravidel a typech dostupných pravidel.  Na skenery se podíváme znovu, až se budeme zabývat barevným značením syntaxe.