Documentos e Partições

A estrutura de texto da plataforma define um modelo de documento para o texto e fornece um visualizador que exibe texto utilizando este modelo. Nós iniciaremos examinando o exemplo de editor Java e como ele utiliza esse modelo.  Nós não focalizaremos a mecânica básica de registrar uma extensão do editor, pois já vimos isso na seção que descreve o org.eclipse.ui.editors.  Em vez disso, veremos as especificações de como a classe do editor é implementada no exemplo.

Fornecedores de Documento e Documentos

No workbench, um editor é normalmente aberto quando o usuário seleciona um elemento de domínio (como um arquivo ou um elemento armazenado dentro de um arquivo archive) e o abre.  Quando o editor é criado, ele é associado a uma entrada do editor (IEditorInput), que descreve o objeto que está sendo editado.

O exemplo de editor Java é aberto quando o usuário abre um arquivo com a extensão "*.jav".   Nesse caso, a entrada para o editor é um IFileEditorInput.  A estrutura de texto da plataforma assume pouco sobre a entrada do editor em si.  Ela funciona com um modelo de apresentação, denominado IDocument, para a entrada, para que possa exibir e manipular eficazmente o texto.

Isso significa que deve haver uma maneira de mapear a partir de um modelo de domínio esperado (a entrada do editor) para o modelo de apresentação.  Esse mapeamento é definido em um IDocumentProvider.  Para uma determinada entrada do editor, o fornecedor de documento retorna um IDocument apropriado.

O exemplo do editor Java herda o TextFileDocumentProvider definido pelo plug-in org.eclipse.ui.editors. A extensão org.eclipse.ui.editors.documentProviders é utilizada para definir mapeamentos entre os tipos de entrada do editor (ou extensões de arquivo) e fornecedores de documentos. O plug-in dos editores define seu fornecedor de documentos conforme a seguir:

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

Essa extensão permite que os plug-ins registrem os fornecedores de documentos e os associe a uma extensão de arquivo ou uma classe de entrada do editor. Já que o exemplo do editor Java não define sua própria extensão do fornecedor de documentos, ele herda o fornecedor de documentos genérico, especificado para todos os tipos de entrada que sãoIStorageEditorInput. Quando o usuário abre um arquivo para edição, a plataforma gerencia os detalhes de criação da instância do fornecedor de documento apropriado. Se um fornecedor de documentos específico é registrado para a extensão do arquivo, esse será utilizado. Se não houver um fornecedor de documento específico para a extensão do arquivo, o tipo de entrada do editor será utilizado para encontrar o fornecedor apropriado.

Utilizando o fornecedor de documentos da plataforma genérica, o exemplo do editor Java pode aproveitar todos os recursos do fornecedor de documentos, como colocação de arquivos em buffer e outras otimizações.

Configuração de Documentos

Já que o editor Java utiliza o fornecedor de documento de texto da plataforma, como pode fornecer um comportamento especializado para a manipulação de arquivos Java?

A extensão org.eclipse.core.filebuffers.documentSetup é utilizada para definir mapeamentos entre as extensões de arquivo e umIDocumentSetupParticipant. O participante da configuração irá configurar o documento com recursos especiais, uma vez que tenha sido fornecido para o editor.

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

Esta definição da extensão é o que dá uma chance ao exemplo para configurar o documento para as tarefas específicas de Java. O que JavaDocumentSetupParticipant faz? Veremos uma versão simplificada do método de configuração.

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

O código de configuração configura um objeto chamado de particionador.

Partições

O particionador (IDocumentPartitioner) é responsável pela divisão do documento em regiões não-sobrepostas denominadas partições.  As partições (representadas por ITypedRegion) são úteis para tratar diferentes seções do documento, diferentemente em relação aos recursos como realce ou formatação da sintaxe.

No caso do exemplo de editor Java, o documento é dividido em partições que representam os comentários de javadoc, comentários de várias linhas e outros.  Cada região é atribuída a um tipo de conteúdo e sua posição no documento.  As posições são atualizadas enquanto o usuário edita o texto.

Particionamento Baseado em Regras do Documento

Compete a cada editor determinar a implementação apropriada para um particionador de documento.  O suporte é fornecido em org.eclipse.jface.text.rules para a varredura baseada em regras do documento.  Utilizar um scanner com base em regras permite que um editor utilize o FastPartitioner fornecido pela estrutura.

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

RuleBasedPartitionScanneré a superclasse para os scanners baseados em regras.  As subclasses são responsáveis por enumerar e implementar as regras que devem ser utilizadas para diferenciar os símbolos, como delimitadores de linha, espaço em branco e padrões genéricos ao varrer um documento.  O JavaPartitionScanner do exemplo define regras para diferenciar comentários de linha única, constantes de caracteres, javadoc, comentários de várias linhas e  palavras.  Isso é feito no construtor do scanner:

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

	List rules= new ArrayList();
	// Adicionar regra para comentários de linha única.
	rules.add(new EndOfLineRule("//", Token.UNDEFINED)); 

	// Adicionar regra para cadeias e constantes de caracteres.
	rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); 
	rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); 

	// Adicionar regra de palavra em caixa especial.
	rules.add(new WordPredicateRule(comment));

	// Adicionar regras para comentários de várias linhas 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);
}

Consulte as classes em org.eclipse.jface.text.rules para obter detalhes adicionais sobre como definir regras e os tipos de regras disponíveis.  Nós veremos novamente os scanners quando examinarmos a coloração da sintaxe.