Определение и реализация переменных
При определении переменных контекста ваших устройств/агентов/серверов необходимо задать свойства их определений, т.е. имя, описание, формат, флажки чтения/записи, уровень прав доступа, текст справки и группу. Для объявления новой переменной создайте экземпляр объекта VariableDefinition
и задайте его свойства. Вот пример:
|
После этого добавьте определение переменной к контексту:
- Переменные контекста драйвера устройства, соответсвующие настройкам доступа устройства, должны добавляться вызовом
Context.addVariableDefinition()
из методаDeviceDriver.setupDeviceContext()
. - Определения переменных контекста драйвера устройства, соответствующие свойствам устройства (переменные настроек устройства), должны возвращаться переопределенным методом
DeviceDriver.readVariableDefinitions()
. - Плагины сервера должны добавлять переменные из методов
install()
иstart()
. - Агенты на базе Java должны добавлять переменные после создания объекта
Agent
черезAgent.getContext().addVariableDefinition()
. - Наконец, скрипты (как скрипты сервера, так и виджета) обычно не должны добавлять никаких переменных.
Для переменных сервера также необходимо задать уровень прав доступа для чтения/записи:
|
Переменные настроек устройства, предоставляемые драйвером устройства, вместе с переменными Agent должны принадлежать группе Группа переменных определяется вызовом
|
Переменные, добавляемые вручную (кроме переменных настроек устройства), должны также иметь ненулевой метод чтения, реализующий интерфейс VariableGetter
. Цель метода чтения - обеспечить пользовательский код чтения переменной. Записываемые переменные должны также иметь ненулевой метод установщика, реализующий интерфейс VariableSetter
. Метод установщика должен каким-то образом сохранять новое значение переменной, измененнное системными операторами или различными интсрументами сервера.
Формат таблицы данных, возвращенный методом установщика переменной, должен соответствовать формату, содержащемуся в ее определении. Несоблюдение данного правила приведет к потере данных, поскольку система попытается сконвертировать таблицу данных в формат, предоставленный определением, сохраняя как можно большее количество данных. |
Реализация чтения значения переменной
Этот раздел подробно описывает, как Context
выстраивает и возвращает DataTable
, представляющую значение переменной, когда кто-то вызывает метод getVariable()
.
Вся логика, описанная здесь, реализуется в классе AbstractContext
, включенном в комплект разработчика с открытым исходным кодом.
Чтобы вернуть результирующую DataTable
из метода getVariable()
, AbstractContext
выполняет следующее:
CallerController
) необходимый эффективный уровень прав доступа в текущем контексте для чтения этой переменной.public DataTable getV
variable(VariableDefinition def, CallerController caller, RequestController request) throws ContextException
Variable - это имя читаемой переменной.
Если находится метод с такой сигнатурой, он вызывается. Этот метод должен вернуть DataTable
, представляющую значение переменной.
VariableGetter
проверяется вызовом VariableDefinition.getGetter()
. Если VariableGetter
определен (не ноль), вызывается метод VariableGetter.get()
. Метод чтения должен вернуть DataTable
, представляющую значение переменной.VariableDefinition.getGetter()
возвращает ноль), AbstractContext
вызывает метод getVariableImpl()
. Этот метод может быть переопределен в подклассах AbstractContext
. Если реализация переопределения "понимает" переменную (т.е. "знает" ее имя), она должна вернуть DataTable
, представляющую значение переменной. В других случаях метод getVariableImpl()
должен вернуть ноль.getVariableImpl()
вернул ноль, AbstractContext
вызывает метод executeDefaultGetter()
. Метод чтения по умолчанию возвращает значение переменной, которая хранилась в базе данных (для кода сервера) или была кэширована в память (для всех других случаев).executeDefaultGetter()
проверяет, определяется ли значение переменной по умолчанию (ненулевое) вызовом VariableDefinition.getDefaultValue()
. Это значение должно быть ранее задано через VariableDefinition.setDefaultValue(DataTable value)
.VariableDefinition
, метод чтения по умолчанию выстраивает и возвращает значение по умолчанию вызовом new SimpleDataTable(variableDefinition.getFormat(), true)
.DataTable
, полученная из "метода чтения", методов VariableGetter, getVariableImpl() или метода чтения по умолчанию не сразу возвращается из getVariable()
. Сначала она проверяется на соответствие формату переменной (доступно через VariableDefinition.getFormat()
, этот шаг опускается, если возвращается ноль). Если формат таблицы данных соответствует формату, предоставленному определением (или расширяет его, добавляя некоторые поля), эта таблица возвращается в исходном виде. Если формат таблицы не соответствует и не расширяет формат определения, AbstractContext
конвертирует таблицу в "нужный" формат и сохраняет максимальное количество данных. Это делается вызовом метода DataTableReplication.copy()
.Если коду, реализующему "метод чтения", VariableGetter или getVariableImpl(), нужен доступ к значению переменной, хранящейся в базе данных или памяти, этот код должен напрямую вызывать метод |
Реализация установки значения переменной
Этот раздел подробно описывает, как Context
выстраивает и возвращает DataTable
, представляющую значение переменной, когда кто-то вызывает метод setVariable()
.
Вся логика, описанная здесь, реализуется в классе AbstractContext
, включенном в комплект разработчика с открытым исходным кодом.
Чтобы обработать DataTable
, представляющую новое значение переменной при вызове метода setVariable()
, AbstractContext
выполняет следующее:
CallerController
) необходимый эффективный уровень прав доступа в текущем контексте для записи этой переменной.DataTable
, представляющая новое значение переменной, сначала проверяется на соответствие формату переменной (доступному через VariableDefinition.getFormat()
, этот шаг опускается, если возвращается ноль). Если формат таблицы данных значения соответствует формату, предоставленному определением (или расширяет его путем добавления полей), эта таблица остается нетронутой. Если формат таблицы значений не соответствует и не расширяет формат определения, AbstractContext
коновертирует таблицу в "нужный" формат и сохраняет максимальное количество данных. Это выполняется вызовом метода DataTableReplication.copy()
.getVariable()
. Значения всех измененных полей "только для чтения" переустанавливаются на те, которые взяты из старой (текущей) таблицы.public void setV
variable(VariableDefinition def, CallerController caller, RequestController request, DataTable value) throws ContextException
Variable - это имя записываемой переменной.
Если находится метод с такой сигнатурой, он вызывается. Этот метод должен вернуть DataTable
, представляющую новое значение переменной.
VariableSetter
проверяется при помощи VariableDefinition.getSetter()
. Если определяется VariableSetter
(не ноль), вызывается метод VariableSetter.set()
. Метод установщика должен обработать DataTable
,представляющую новое значение переменной.VariableDefinition.getSetter()
возвращает ноль) или метод установщика возвращает false, AbstractContext
вызывает метод setVariableImpl()
. Этот метод может быть переопределен в подклассах AbstractContext
. Если реализация переопределения "понимает" переменную (т.е. "знает" ее имя), она должна обрабатывать DataTable
, представляющую новое значение переменной и возвращать true. В ином случае метод setVariableImpl()
должен вернуть false.setVariableImpl()
вернул false, AbstractContext
вызывает метод executeDefaultSetter()
. Метод установщика по умолчанию сохраняет новое значение переменной в базе данных (для кода сервера) или в кэше памяти (для всех других случаев).Если коду, реализующему "метод установщика", VariableSetter или setVariableImpl(), нужно хранить значение новой переменной в базе данных или памяти, этот код должен напрямую вызывать метод |