Operadores

org.eclipse.ui.handlers

3.1

O ponto de extensão dos operadores é uma elaboração do elemento experimental handlerSubmission definido no Eclipse 3.0. Um operador é o comportamento de um comando numa determinada altura. Um comando pode ter zero ou mais operadores a ele associados. A determinada altura, contudo, um comando ou não terá nenhum operador activo ou terá um operador activo. O operador activo é aquele que é actualmente responsável por transmitir o comportamento do comando. Este é muito semelhante ao conceito de um operador de acção e a uma acção cujo destino pode ser alterado.

O ponto de extensão dos operadores permite que um programador de conector especifique um operador que deve ficar activo e/ou ser activado sob determinadas condições. Se um operador for inactivo, então nenhum comando irá delegar o respectivo comportamento ao operador. Se um operador estiver desactivado, então não se pedirá ao operador que execute uma acção; a execução do operador fica bloqueada. As condições são definidas utilizando o utilitário de linguagem de expressão adicionada durante a edição 3.0. São expressas utilizando as cláusulas activeWhen e enabledWhen.

A área de trabalho fornece algumas variáveis nas quais essas expressões podem basear-se. As variáveis suportadas são: os contextos activos, o editor activo, o componente activo e a selecção actual. Embora não seja suportada nesta edição inicial, é fácil ver como seria possível adicionar outras variáveis ou até permitir aos programadores de conectores incluírem outras variáveis.

Um operador que não especifica condições é um operador predefinido. Um operador predefinido só está activo se nenhum outro operador cumprir todas as condições. Se dois operadores tiverem condições cumpridos, então as condições serão comparadas. A ideia é seleccionar um operador cuja condição seja mais específica e mais local. Para o fazer, são investigadas as variáveis referidas pela condição. "Ganha" a condição que se refere à variável mais específica. A ordem da especificidade (da menos específica para a mais específica) é definida em org.eclipse.ui.ISources.

Se mesmo assim o conflito não for solucionado, então nenhum operador ficará activo. Se uma opção de rastreio específica estiver ligada, isso dá origem a uma mensagem no ficheiro de registo. Pode também ocorrer um conflito se existirem dois operadores predefinidos. É da responsabilidade dos programadores de conectores e testers de integração assegurar que isto não acontece. Estas condições são utilizadas para evitar o carregamento desnecessário do conector. Estas definições do operador são acomodadas num proxy. Para um proxy carregar o respectivo operador subjacente, têm de acontecer duas coisas: para o proxy ficar activo é necessário cumprir as condições, e é necessário pedir ao comando para fazer algo que terá de delegar (por exemplo, execute()).

<!ELEMENT extension (handler*)>

<!ATTLIST extension

point CDATA #REQUIRED

id    CDATA #IMPLIED

name  CDATA #IMPLIED>


<!ELEMENT handler (activeWhen? , class? , enabledWhen?)>

<!ATTLIST handler

commandId     CDATA #REQUIRED

class         CDATA #IMPLIED

helpContextId CDATA #IMPLIED>


<!ELEMENT activeWhen (not | and | or | instanceof | test | systemTest | equals | count | with | resolve | adapt | iterate)>



<!ELEMENT enabledWhen (not | and | or | instanceof | test | systemTest | equals | count | with | resolve | adapt | iterate)>



<!ELEMENT class (parameter*)>

<!ATTLIST class

class CDATA #IMPLIED>


<!ELEMENT parameter EMPTY>

<!ATTLIST parameter

name  CDATA #REQUIRED

value CDATA #REQUIRED>


<!ELEMENT enablement (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

Um elemento de raiz genérico. O elemento pode ser utilizado num ponto de extensão para definir a sua expressão de activação. Os elementos descendentes de uma expressão de activação são combinados através da utilização do operador and.



<!ELEMENT not (not | and | or | instanceof | test | systemTest | equals | count | with | resolve | adapt | iterate)>

Este elemento representa uma operação NOT no resultado da avaliação da sua expressão de subelemento.



<!ELEMENT and (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

Este elemento representa uma operação AND no resultado de avaliação de todas as respectivas expressões de subelemento.



<!ELEMENT or (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

Este elemento representa uma operação OR no resultado de avaliação de todas as respectivas expressões de subelemento.



<!ELEMENT instanceof EMPTY>

<!ATTLIST instanceof

value CDATA #REQUIRED>

Este elemento é utilizado para desempenhar uma verificação instanceof do objecto em questão. A expressão devolve EvaluationResult.TRUE se o tipo do objecto for um subtipo do tipo especificado pelo valor do atributo. De outro modo, devolve EvaluationResult.FALSE.



<!ELEMENT test EMPTY>

<!ATTLIST test

property CDATA #REQUIRED

args     CDATA #IMPLIED

value    CDATA #IMPLIED>

Este elemento é utilizado para avaliar o estado de propriedade do objecto em questão. O conjunto de propriedades verificáveis pode ser alargado através da utilização do ponto de extensão do dispositivo de testes de propriedade. A expressão do teste devolve EvaluationResult.NOT_LOADED se o dispositivo de testes de propriedade que está a fazer o teste ainda não estiver carregado.



<!ELEMENT systemTest EMPTY>

<!ATTLIST systemTest

property CDATA #REQUIRED

value    CDATA #REQUIRED>

Testa uma propriedade de sistema solicitando o método System.getProperty e compara o resultado com o valor especificado através do atributo value.



<!ELEMENT equals EMPTY>

<!ATTLIST equals

value CDATA #REQUIRED>

Este elemento é utilizado para desempenhar uma verificação equals do objecto em questão. A expressão devolve EvaluationResult.TRUE se o objecto for igual ao valor fornecido pelo atributo value. De outro modo, devolve EvaluationResult.FALSE.



<!ELEMENT count EMPTY>

<!ATTLIST count

value CDATA #REQUIRED>

Este elemento é utilizado para testar o número de elementos numa recolha.



<!ELEMENT with (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST with

variable CDATA #REQUIRED>

Este elemento altera o objecto a ser inspeccionado em todos os elementos descendentes, para o objecto referenciado pela dada variável. Se a variável não puder ser processada, a expressão apresenta ExpressionException quando estiver a fazer a avaliação. Os elementos descendentes de uma expressão with são combinados com recurso ao operador and.



<!ELEMENT resolve (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST resolve

variable CDATA #REQUIRED

args     CDATA #IMPLIED>

Este elemento altera o objecto a ser inspeccionado em todos os elementos descendentes, para o objecto referenciado pela dada variável. Se a variável não puder ser processada, a expressão apresenta ExpressionException quando estiver a fazer a avaliação. Os elementos descendentes de uma expressão with são combinados com recurso ao operador and.



<!ELEMENT adapt (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST adapt

type CDATA #REQUIRED>

Este elemento é utilizado para adaptar o objecto em questão ao tipo especificado pelo tipo do atributo. A expressão devolve not loaded se o adaptador ou o tipo referenciados ainda não estiverem carregados. Apresenta ExpressionException durante a avaliação se o nome do tipo não existir. Os elementos descendentes de uma expressão adapt são combinados com recurso ao operador and.



<!ELEMENT iterate (not , and , or , instanceof , test , systemTest , equals , count , with , resolve , adapt , iterate)*>

<!ATTLIST iterate

operator (or|and) >

Este elemento é utilizado para iterar numa variável que seja de tipo java.util.Collection. Se o objecto em questão não for do tipo java.util.Collection, surge ExpressionException durante a avaliação da expressão.



<extension point=

"org.eclipse.ui.handlers"

>

<handler commandId=

"commandId"

class=

"org.eclipse.compare.Command"

>

<activeWhen>

<with variable=

"selection"

>

<count value=

"1"

/>

<iterate operator=

"and"

>

<adapt type=

"IResource"

/>

</iterate>

</with>

</activeWhen>

</handler>

</extension>

Para evitar mais o carregamento do conector, é possível especificar quando o operador é activado. Se o proxy ainda não carregou o operador, então apenas é utilizadas a sintaxe de expressões para decidir se o operador será activado. Se o proxy carregou o operador, então a sintaxe de expressão é consultada primeiro. Se a sintaxe de expressões é definida como true, então pergunta-se ao operador se está activado. (Esta é uma operação "and" booleana de curto-circuito entre a sintaxe de expressões e o estado activado do operador.)

<extension point=

"org.eclipse.ui.handlers"

>

<handler commandId=

"commandId"

class=

"org.eclipse.Handler"

>

<enabledWhen>

<with variable=

"context"

>

<property id=

"id"

value=

"debugging"

/>

</with>

</enabledWhen>

</handler>

</extension>

Todos os operadores implementa a interface org.eclipse.core.commands.IHandler. Dentro da área de trabalho, é possível activar e desactivar operadores utilizando a interface org.eclipse.ui.handlers.IHandlerService. Esta interface pode ser recuperada a partir dos objectos da área de trabalho de suporte, como o próprio IWorkbench. Para recuperar o serviço, teria de fazer uma chamada como IWorkbench.getAdapter(IHandlerService.class).

Também é possível activar e desactivar os operadores utilizando o código de legado na área de trabalho. Isto pode ser efectuado através do mecanismo de legado que se mostra a seguir. Este mecanismo é útil para os clientes que utilizam acções para fazer contribuições para menus e barras de ferramentas.

 IWorkbenchPartSite mySite;
 IAction myAction;
 
 myAction.setActionDefinitionId(commandId);
 IKeyBindingService service = mySite.getKeyBindingService();
 service.registerAction(myAction);