Dokumenter og partitioner

Platformens tekststruktur definerer en dokumentmodel for tekst og stiller en fremviser til rådighed, som viser tekst vha. denne model.  Vi ser først på Java-editoreksemplet og den måde, editoren bruger modellen på. Vi fokuserer ikke på den grundlæggende mekanisme med registrering af en editorudvidelse, da vi allerede har gennemgået det i afsnittet om org.eclipse.ui.editors. I stedet ser vi nærmere på, hvordan editorklassen implementeres i eksemplet.

Dokumentudbydere og dokumenter

På arbejdsbænken åbnes en editor typisk når brugeren vælger et domæne-element (f.eks. en fil eller et element, som er gemt i en arkivfil) og åbner det. Når editoren oprettes, knyttes den sammen med et editorinput (IEditorInput), som beskriver det objekt, der redigeres.

Java-editoreksemplet åbnes, når brugeren åbner en fil med filtypen "*.jav". I dette tilfælde er inputtet til editoren IFileEditorInput. Platformens tekststruktur antager ikke ret meget om selve editorinputtet. Strukturen bruger en præsentationsmodel, som hedder IDocument, til inputtet, så den effektivt kan fremvise og manipulere tekst.

Det betyder, at der må være en metode til at tilknytte en forventet domænemodel (editorinputtet) til præsentationsmodellen vha. mapping. Denne mapping defineres i IDocumentProvider. Når dokumentudbyderen får et editorinput, returnerer den et relevant IDocument.

Java-editoreksemplet overtager den TextFileDocumentProvider, som defineres af plugin-funktionen org.eclipse.ui.editors. Udvidelsen org.eclipse.ui.editors.documentProviders bruges til at definere tilknytninger mellem editorinputtyper (eller filtyper) og dokumentudbydere vha. mapping. Plugin-editorfunktionen definerer sin dokumentudbyder på følgende måde:

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

Dette udvidelsespunkt gør det muligt for plugin-funktioner at registrere dokumentudbydere og knytte dem sammen med enten en filtype eller en editorinputklasse. Da Java-editoreksemplet ikke definerer sin egen dokumentudbyderudvidelse, overtager den den generiske dokumentudbyder, som angives for alle inputtyper, som er IStorageEditorInput. Når brugeren åbner en fil til redigering, håndterer platformen oplysningerne forbundet med at oprette den relevante forekomst af dokumentudbyderen. Hvis der registreres en bestemt dokumentudbyder for filtypen, bliver den brugt. Hvis der ikke er nogen bestemt dokumentudbyder til filtypen, bruges editorinputtypen til at finde den relevante udbyder.

Ved at benytte platformens generiske dokumentudbyder kan Java-editoreksemplet udnytte alle funktioner i dokumentudbyderen, f.eks. filbufferfunktioner og andre optimeringer.

Dokumentklargøring

Når Java-editoren bruger platformens tekstdokumentudbyder, hvordan kan den så levere en specialiseret funktionsmåde til håndtering af Java-filer?

Udvidelsen org.eclipse.core.filebuffers.documentSetup bruges til at definere tilknytninger mellem filtyper og IDocumentSetupParticipant. Klargøringsdeltageren klargør dokumentet med eventuelle specielle funktioner, når det er leveret til editoren.

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

Det er denne udvidelsesdefinition, som giver eksemplet chance for at klargøre dokumentet til Java-specifikke opgaver. Hvad gør JavaDocumentSetupParticipant så? Nu ser vi på en forenklet version af metoden setup.

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

Klargøringskoden konfigurerer et objekt, som kaldes en partitioner.

Partitioner

Partitioner-objektet (IDocumentPartitioner) er ansvarligt for at opdele dokumentet i ikke-overlappende områder, som hedder partitioner. Partitioner (som repræsenteres afITypedRegion) er praktiske, når forskellige afsnit af dokumentet skal behandles forskelligt, f.eks. med hensyn til syntaksfremhævning eller formatering.

I Java-editoreksemplet opdeles dokumentet i partitioner, som repræsenterer Javadoc-kommentarer, kommentarer på flere linjer og alt muligt andet. Hvert område tildeles en indholdstype og en placering i dokumentet. Placeringer opdateres, efterhånden som brugeren redigerer tekst.

Regelbaseret dokumentopdeling

Det er op til hver enkelt editor at bestemme den relevante implementering for en dokument-partitioner. org.eclipse.jface.text.rules indeholder hjælp til regelbaseret dokumentscanning. Når du bruger en regelbaseret scanner, kan en editor anvende den FastPartitioner, som stilles til rådighed af strukturen.

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

RuleBasedPartitionScanner er superklassen for regelbaserede scannere. Underklasser er ansvarlige for enumeration og implementering af de regler, som skal bruges til at skelne mellem tokens som f.eks. linjeafgrænsninger, tom plads og generiske mønstre, når et dokument scannes. Eksemplets JavaPartitionScanner definerer regler for sondring mellem kommentarer på en enkelt linjer, tegnkonstanter, Javadoc, kommentarer på flere linjer og ord. Det gøres i scannerens konstruktør:

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

	List rules= new ArrayList();
	// Tilføj regel for kommentarer på en enkelt linje.
	rules.add(new EndOfLineRule("//", Token.UNDEFINED)); 

	// Tilføj regel for strenge og tegnkonstanter.
	rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); 
	rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); 

	// Tilføj regel for specielt tilfælde af ord.
	rules.add(new WordPredicateRule(comment));

	// Tilføj regler for kommentarer på flere linjer og 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);
}

Klasserne i org.eclipse.jface.text.rules indeholder flere oplysninger om definition af regler og tilgængelige typer regler. Vi ser på scannerne igen, når vi ser på syntaksfarvning.