Обработчики

org.eclipse.ui.handlers

3.1

Точка расширения обработчиков - это развитие экспериментального элемента handlerSubmission, появившегося в Eclipse 3.0. Обработчики задают поведение команды в зависимости от различных условий. У команды может быть как несколько обработчиков, так и не одного. Но в любой момент времени у нее может быть только один активный обработчик, либо его вообще может не быть. Активный обработчик отвечает за поведение команды в данный момент времени. Такая концепция аналогична концепции обработчиков действий и действий с переменными объектами.

Точка расширения обработчиков позволяет разработчикам модулей задавать условия, при которых те или иные обработчики должны становиться активными. Если обработчик неактивный, то команды не будут его использовать. Если обработчик отключен, то он не будет выполняться; его выполнение будет блокировано. Условия задаются с помощью языка выражений, добавленного в версии 3.0, через предложения activeWhen и enabledWhen.

Рабочая среда предоставляет некоторые переменные, от которых эти выражения зависят. Поддерживаемые переменные: активные контексты, активный редактор, активный компонент, текущее выделение. Не смотря на то, что это не предусмотрено изначально, все же возможно добавлять другие переменные вручную или из модулей.

Обработчик по умолчанию - это обработчик без указанных условий. Он становится активным только если условия остальных обработчиков не выполняются. Если условия выполняются у нескольких обработчиков, то будет произведено сравнение условий по степени важности. Больший приоритет будет иметь обработчик с более конкретными или локальными условиями. Для этого просматриваются переменные, на которые ссылается каждое условие. Условие, ссылающееся на более подробные переменные получит больший приоритет. Степень подробности (от наименьшей до наибольшей) определяется в org.eclipse.ui.ISources.

Если конфликт разрешить не удается, то ни один их обработчиков не становится активным. При наличии соответствующей опции трассировки, это также приведет к записи сообщения в файл протокола. Конфликт также может возникнуть при наличии двух стандартных обработчиков. За то, чтобы это не произошло, должны отвечать разработчики модулей и интеграционные тестировщики. Условия используются для избежания ненужных загрузок модулей. За загрузку обработчиков отвечают классы-посредники. Для загрузки обработчика классом-посредником, должны выполняться условия обработчика, и он должен быть вызван командой.

<!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)*>

Шаблонный корневой элемент. Этот элемент может использоваться внутри точки расширения для определения ее выражения enablement. Для объединения подэлементов выражения enablement используется операция and.



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

Этот элемент представляет операцию НЕ над результатом вычисления выражения его подэлемента.



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

Этот элемент представляет операцию И над результатом вычисления выражений всех его подэлементов.



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

Этот элемент представляет операцию ИЛИ над результатом вычисления выражений всех его подэлементов.



<!ELEMENT instanceof EMPTY>

<!ATTLIST instanceof

value CDATA #REQUIRED>

Этот элемент позволяет проверить допустимость преобразования типа выбранного объекта к указанному типу. Выражение возвращает EvaluationResult.TRUE, если тип объекта является производным типом типа, указанного в значении атрибута. В противном случае возвращается EvaluationResult.FALSE.



<!ELEMENT test EMPTY>

<!ATTLIST test

property CDATA #REQUIRED

args     CDATA #IMPLIED

value    CDATA #IMPLIED>

Этот элемент используется для проверки состояния свойства выбранного объекта. Набор тестируемых свойств можно расширить с помощью точки расширения средства тестирования свойств. Выражение test возвращает EvaluationResult.NOT_LOADED, если средство тестирования свойств, выполняющее фактическую проверку, еще не загружено.



<!ELEMENT systemTest EMPTY>

<!ATTLIST systemTest

property CDATA #REQUIRED

value    CDATA #REQUIRED>

Тестирует системное свойство, вызывая для этого метод System.getProperty и сравнивая результат со значением, указанным в атрибуте value.



<!ELEMENT equals EMPTY>

<!ATTLIST equals

value CDATA #REQUIRED>

Этот элемент применяется для выполнения проверки equals объекта в фокусе. Выражение возвращает EvaluationResult.TRUE, если объект равен значению атрибута value. В противном случае возвращается EvaluationResult.FALSE.



<!ELEMENT count EMPTY>

<!ATTLIST count

value CDATA #REQUIRED>

Этот элемент применяется для проверки числа элементов в наборе.



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

<!ATTLIST with

variable CDATA #REQUIRED>

Этот элемент изменяет проверяемый объект для всех своих подэлементов, заменяя его объектом, на который указывает переменная в атрибуте variable. Если разрешить переменную невозможно, то при вычислении выражения возбуждается ситуация ExpressionException. Для объединения подэлементов выражения with используется операция and.



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

<!ATTLIST resolve

variable CDATA #REQUIRED

args     CDATA #IMPLIED>

Этот элемент изменяет проверяемый объект для всех своих подэлементов, заменяя его объектом, на который указывает переменная в атрибуте variable. Если разрешить переменную невозможно, то при вычислении выражения возбуждается ситуация ExpressionException. Для объединения подэлементов выражения with используется операция and.



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

<!ATTLIST adapt

type CDATA #REQUIRED>

Данный элемент используется для адаптации выбранного объекта к типу, указанному в атрибуте type. Если адаптер или указанный тип еще не загружены, выражение возвращает NOT_LOADED. Если имя типа вообще не существует, то при вычислении выражения возбуждается ситуация ExpressionException. Для объединения подэлементов выражения adapt используется операция and.



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

<!ATTLIST iterate

operator (or|and) >

Этот элемент используется для выполнения итераций с переменной, относящейся к типу java.util.Collection. Если тип выбранного объекта - не java.util.Collection, то при вычислении этого выражения возбуждается ситуация ExpressionException.



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

Для избежания загрузки модуля можно также указать условия, при каких он включен. Если класс-посредник еще не загрузил обработчика, то для определения, включен ли он, используются только выражения. Если обработчик уже загружен, то выражения используются первыми. Если выражения равны true, то самому обработчику поступает запрос о его состоянии (иными словами, это "логическое И" между выражениями и состоянием обработчика).

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

Все обработчики должны реализовывать org.eclipse.core.commands.IHandler. В рамках рабочей среды, обработчики можно активировать и дезактивировать с помощью интерфейса org.eclipse.ui.handlers.IHandlerService. Он может быть получен из объектов, поддерживающих рабочую среду, в т.ч. из самого IWorkbench. Для этого нужно использовать вызов наподобие IWorkbench.getAdapter(IHandlerService.class).

Активировать и дезактивировать обработчики можно также с помощью кода в рабочей среде. Для этого нужно использовать механизм, показанный ниже. Он полезен для клиентов, дополняющих меню и панели инструментов с помощью действий.

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