Documentos e partições

O quadro de texto da plataforma define um modelo de documentos para texto e fornece um visualizador que apresenta texto com este modelo.  Começamos por abordar o exemplo de editor Java e como utiliza este modelo.  Não falaremos dos mecanismos básicos do registo de uma extensão de editor, visto que já os vimos na secção que descreve org.eclipse.ui.editors. Em contrapartida, veremos as especificidades de implementação da classe do editor no exemplo.

Fornecedores de documentos e documentos

Na área de trabalho, um editor abre-se normalmente quando o utilizador selecciona um elemento de domínio (como, por exemplo, um ficheiro ou um elemento armazenado num ficheiro de arquivo) e o abre.  Quando o editor é criado, fica associado a uma entrada de dados de editor (IEditorInput), a qual descreve o objecto em edição.

O exemplo do editor Java abre-se quando o utilizador abre um ficheiro com a extensão "*.jav".  Neste caso, a entrada de dados para o editor é uma IFileEditorInput. O quadro de texto da plataforma pouco depreende da entrada de dados do editor propriamente dita.  Em contrapartida, trabalha com um modelo de apresentação, denominado IDocument, para a entrada de dados, de modo a poder efectivamente apresentar e manipular texto.

Significa isto que tem de haver maneira de correlacionar um modelo de domínio esperado (a entrada de dados do editor) com o modelo de apresentação.  Esta correlação está definida num IDocumentProvider. Recebendo uma entrada de dados do editor, o fornecedor de documentos devolve um IDocument apropriado.

O exemplo de editor Java herda o TextFileDocumentProvider definido pelo plug-in org.eclipse.ui.editors. A extensão org.eclipse.ui.editors.documentProviders é utilizada para definir correlações entre tipos de entradas de dados do editor (ou extensões de ficheiros) e fornecedores de documentos. O plug-in do editor define o seu fornecedor de documentos da seguinte forma:

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

Este ponto de extensão permite aos plug-ins registarem fornecedores de documentos e associá-los quer a uma extensão de ficheiro quer a uma classe de entrada de dados do editor. Como o exemplo de editor Java não define a sua própria extensão de fornecedor de documentos, herdará o fornecedor de documentos genérico especificado para todos os tipos de entrada de dados que sejam IStorageEditorInput. Quando o utilizador abre um ficheiro para edição, a plataforma gere os detalhes da criação da instância do fornecedor de documentos propriamente dito. Se estiver registado um fornecedor de documentos específico para a extensão do ficheiro, será utilizado esse. Se não houver um fornecedor de documentos específico para a extensão do ficheiro, o tipo de entrada de dados do editor será utilizado para localizar o fornecedor apropriado.

Ao utilizar o fornecedor de documentos genérico da plataforma, o exemplo de editor Java pode tirar partido de todas as funções do fornecedor de documentos como, por exemplo, colocação de ficheiros em memória tampão e outras optimizações.

Configuração de documentos

Como o editor Java utiliza o fornecedor de documentos de texto da plataforma, como pode fornecer comportamentos especializados para tratar ficheiros Java?

A extensão org.eclipse.core.filebuffers.documentSetup é utilizada para definir correlações entre extensões de ficheiros e um IDocumentSetupParticipant. O participante na configuração irá configurar o documento com funções especiais assim que este seja fornecido ao 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 de extensão é o que dá ao exemplo a oportunidade de configurar o documento para tarefas específicas Java. Posto isto, que faz o JavaDocumentSetupParticipant? Vejamos uma versão simplificada do método setup.

 	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 objecto chamado particionador.

Partições

O particionador (IDocumentPartitioner) é responsável pela divisão do documento em região que não se sobreponham chamadas partições.  As partições (representadas pela ITypedRegion) são úteis para tratar diferentes secções do documento de modos distintos, relativamente a funções como, por exemplo, destaque de sintaxe ou formatação.

No caso do exemplo de editor Java, o documento está dividido em partições que representam os comentários javadoc, comentários multi-linha e tudo o mais.  É atribuído um tipo de conteúdo a cada região e a respectiva posição no documento.  As posições são actualizadas à medida que o utilizador editar texto.

Particionamento de documentos baseado em regras

Compete a cada editor determinar a implementação apropriada para um particionador de documentos.   O suporte é facultado em org.eclipse.jface.text.rules para leitura de documentos baseada em regras.  Ao utilizar um leitor baseado em regras, o editor pode utilizar o FastPartitioner fornecido pelo quadro.

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

RuleBasedPartitionScanner é a superclasse para leitores baseados em regras.  As subclasses são responsáveis pela enumeração e implementação das regras que devem ser seguidas para distinguir sinais como, por exemplo, delimitadores de linhas, espaços em branco e padrões genéricos, aquando da leitura de um documento.  O JavaPartitionScanner do exemplo define regras para distinguir comentários de linha única, constantes de caracteres, javadoc, comentários multi-linha e  palavras.  Tal realiza-se no construtor do leitor:

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

	List rules= new ArrayList();
	// Add rule for single line comments.
	rules.add(new EndOfLineRule("//", Token.UNDEFINED)); 

	// Add rule for strings and character constants.
	rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); 
	rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); 

	// Add special case word rule.
	rules.add(new WordPredicateRule(comment));

	// Add rules for multi-line comments and 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 mais detalhes sobre definição de regras e tipos de regras disponíveis.  Voltaremos aos leitores quando virmos a coloração da sintaxe.