[_A-Za-z][_A-Za-z0-9|]*
и его длина не превышала 90 символов (необходимо использовать префикс или суффикс "Agent"
при разработке агента и запрещено использовать суффикс "Message"
при разработке ШС);src
) создать структуру подкаталогов, соответствующую пакету, в котором должнен(ы) располагаться класс(ы) программной единицы:
ru/dvo/iacp/is/iacpaas/mas/agents
(пакет — ru.dvo.iacp.is.iacpaas.mas.agents
)ru/dvo/iacp/is/iacpaas/mas/messages
(пакет — ru.dvo.iacp.is.iacpaas.mas.messages
)iacpaas-api-<1.0>.jar
) и, возможно, jar-архив, содержащий байт-код повторноиспользуемых пользовательских шаблонов сообщений (при наличии таковых у разрабатываемого агента) (<внутреннее имя агента>_ReusedMessageTemplates.jar
) рекомендуется полмещать в подкаталог — lib
.Impl
). Рекомендуется вручную не менять системный код, а использовать лишь предоставляемую редактором заготовку. Собственный код необходимо разработать на основе заготовки, в нём присутсвуют:
ru.dvo.iacp.is.iacpaas.mas.agents
;import
-секция — должна быть наполнена содержимым import
-секции класса-заготовки;public
);final
);IRunningService
(контекст запущенного сервиса) и IInforesource
(инфоресурс агента) — должен передавать эти аргументы конструктору класса-заготовки (используя ключевое слово super
);runProduction(...)
класса с системным кодом — эти методы необходимо переопределить[7] в данном классе собственной реализацией;runProduction(...)
реализовать логику работы соответствующего блока продукций (согласно спецификации агента в проекте);runProduction(...)
.IInforesource[] getInputs()
— возвращает массив инфоресурсов, указанных в сервисе как входные (подразумевается, что будет осуществляться только доступ на чтение), вызывается следующим образом: runningService.getService().getInputs()
;IInforesourceGenerator[] getOutputs()
— возвращает массив "генераторов" инфоресурсов, указанных в сервисе как выходные (подразумевается, что будет осуществляться полный доступ), вызывается следующим образом: runningService.getService().getOutputs()
;IInforesource[] getReadOnlyOwns()
— возвращает массив инфоресурсов, указанных в решателе как собственные с доступом только на чтение (подразумевается, что будет осуществляться только доступ на чтение), вызывается следующим образом: runningService.getService().getSolver().getReadOnlyOwns()
;IInforesourceGenerator[] getOwns()
— возвращает массив "генераторов" инфоресурсов, указанных в сервисе как собственные с полным доступом (подразумевается, что будет осуществляться полный доступ), вызывается следующим образом: runningService.getService().getSolver().getOwns()
;IInforesourceGenerator[] getTemps()
— возвращает массив "генераторов" инфоресурсов, создаваемых при запуске сервиса как временные (подразумевается, что будет осуществляться полный доступ), вызывается следующим образом: runningService.getTemps()
.IInforesource getInput(String paramName)
— возвращает соответствующий имени параметра paramName
в сервисе входной инфоресурс, к которому возможен доступ только на чтение (вызывается следующим образом: runningService.getService().getInput("...")
);Map<String, IInforesource> getInputsMap()
— возвращает ассоциативный массив с элементами вида <имя параметра - инфоресурс>, где инфоресурс — сопоставленный в сервисе параметру с данным именем входной инфоресурс, к которому возможен доступ только на чтение (вызывается следующим образом: runningService.getService().getInputsMap()
);IInforesourceGenerator getOutput(String paramName)
— возвращает соответсвующий имени параметра paramName
в сервисе выходной инфоресурс, к которому возможен полный доступ (вызывается следующим образом: runningService.getService().getOutut("...")
);Map<String, IInforesourceGenerator> getOutputsMap()
— возвращает ассоциативный массив с элементами вида <имя параметра - инфоресурс>, где инфоресурс — сопоставленный в сервисе параметру с данным именем выходной инфоресурс, к которому возможен полный доступ (вызывается следующим образом: runningService.getService().getOutputsMap()
);IInforesource getReadOnlyOwn(String paramName)
— возвращает соответсвующий имени параметра paramName
в решателе собственный инфоресурс с доступом только на чтение (вызывается следующим образом: runningService.getService().getSolver().getReadOnlyOwn("...")
);Map<String, IInforesource> getReadOnlyOwnsMap()
— возвращает ассоциативный массив с элементами вида <имя параметра - инфоресурс>, где инфоресурс — сопоставленный в решателе параметру с данными именем собственный инфоресурс с доступом только на чтение (вызывается следующим образом: runningService.getService().getSolver().getReadOnlyOwnsMap()
);IInforesource getFullAccessOwn(String paramName)
— возвращает соответсвующий имени параметра paramName
в решателе собственный инфоресурс с полным доступом (вызывается следующим образом: runningService.getService().getSolver().getFullAccessOwn("...")
);Map<String, IInforesource> getFullAccessOwnsMap()
— возвращает ассоциативный массив с элементами вида <имя параметра - инфоресурс>, где инфоресурс — сопоставленный в решателе параметру с данными именем собственный инфоресурс с полным доступом (вызывается следующим образом: runningService.getService().getSolver().getFullAccessOwnsMap()
);IInforesourceGenerator getTemp(String paramName)
— возвращает временный инфоресурс (объект, допускающий чтение и создание содержимого инфоресурса), созданный при запуске сервиса по соответсвующей имени параметра paramName
в решателе метаинформации временного инфоресурса (вызывается следующим образом: runningService.getTemp("...")
);Map<String, IInforesourceGenerator> getTempsMap()
— возвращает ассоциативный массив с элементами вида <имя параметра - инфоресурс>, где инфоресурс — созданный при запуске сервиса временный инфоресурс с возможностью полного доступа, метаинформация которого сопоставлена в решателе имени параметра временного инфоресурса (вызывается следующим образом: runningService.getTempsMap()
);IInforesource getProcessedInforesource(String paramName)
— возвращает инфоресурс, соответствующий имени параметра paramName, указанного в одном из множеств параметров сервиса/решателя (в этом случае в множествах входных, выходных, временных, собственных с полным доступом и собственных с доступом на чтение не должны быть одноименные параметры);Map<String, IInforesource> getProcessedInforesourcesMap()
— возвращает ассоциативный массив с элементами вида <имя параметра - инфоресурс>, где инфоресурс — входной или выходной или собственный с полным доступом или собственный на чтение или временный (вызывается следующим образом: runningService.getProcessedInforesourcesMap()
).getGenerator(...)
— для всего инфоресурса (IInforesource
);getGenerator(...)
, getEditor(...)
— для отдельных понятий (IConcept
) и отношений (IRelation
).IInforesource getProcessedInforesource(String paramName, Agent agent)
— возвращает соответствующий заданному в агенте agent
имени параметра paramName
инфоресурс (входной или выходной в сервисе, или собственный или собственный на чтение в решателе, или временный в работающем сервисе - см. далее) (для осуществления полного доступа необходимо использовать метод getGenerator(...)
), вызывается следующим образом: runningService.getProcessedInforesource("...", this)
.runProduction(UiParamsMessage msg, ...)
UiBuildHelper
, объект которого извлекается из входного сообщения следующим образом: UiBuildHelper ui = new UiBuildHelper(msg.getUIAbstractModel())
UiParamsMessage
(это первый параметр метода runProduction(...)
) следующих методов:
String getParam(String key)
— получить строковое значение конкретного параметра (есть вариант вызова с получением значения по-умолчанию в случае отсутствия такого параметра/значения в пришедших : getParam(String paramName, String defaultValue)
;Map<String, Object> getAllParams()
— получить карту из элементов <имя параметра - значение параметра>, включающую все поступившие параметры и их значения;String[] getParamValues(String key)
— получить все строковые значения, выбранные в выпадающем списке key
;UiParamsMessage.File getFile(String paramfilename)
— получить содержимое конкретного файла;Map<String, IConcept> getAllFiles()
получить карту из элементов <имя файла - вершина с данными файла>, включающую все поступившие файлы и их содержимое.//шаг 1 - обработка поступивших данных с выяснением, какая команда поступила String action = msg.getParam("action"); if ("my_action1".equals(action)) {...} else if ("my_action2".equals(action)) {...} ...Формирование нужного фрагмента пользовательского Web-интерфейса, состоящего из множества простых и/или составных интерфейсных элементов (контейнеров), выполняется посредством вызова функций API пользовательского интерфейса. Вызов каждой такой функции с требуемыми аргументами приводит к формированию декларативного описания соответствующего интерфейсного элемента или его атрибута (во временном инфоресурсе, формируемом агентом ВИД при поступлении UI-запроса от пользователя). Таким образом, формирование описания нужного фрагмента интерфейса состоит в построении композиции (суперпозиции) вызовов функций API пользовательского интерфейса, его обеспечивающей. В конечном итоге по сформированному инфоресурсу, содержащему (полное) описание интерфейса, агент ВИД выполнит формирование html-кода, который будет отображён на экране в ответ на поступивший запрос. Все методы формирования интерфейса предоставляются классом
UiBuildHelper
. В блоке продукций, который будет выполнять построение интерфейса, необходимо создать единственный объект такого класса, передав в конструктор инфоресурс с абстрактной моделью интерфейса. Данный инфоресурс поступает в работающем сервисе от агента ВИД к агену интерфейсный контроллер вместе с сообщением, сформированным по шалблону Запрос от агента ВИД (UiParamsMessage
), и извлекается с помощью метода getUIAbstractModel()
.
UiShowWindow
.
Отметим (повторно), что ответ агенту ВИД может содержать не только модель пользовательского интерфейса (по которой будет сформирован html код и отображён в браузере), но и (альтернативно) json или (альтернативно) строку - которые обычно предназначены для перехвата созданным разработчиком агенте JS-кодом (также являющимся частью агента интерфейсный контроллер), работающим в браузере, с целью выполнения над этими данными некоторых манипуляций.
UiShowWindowMessage
) — результат прикрепляется посредством вызова метода setInterface(IConcept interface)
;UiReturnStringMessage
) — результат прикрепляется посредством вызова метода setResult(String string)
;UiReturnJsonMessage
) — результат прикрепляется посредством вызова метода setResult(Json res)
;UiReturnInforesourceMessage
) — результат прикрепляется посредством вызова метода setResult(IInforesource ir)
.concept
, доступный для редактирования:IConcept commentEdit = ui.sec(ui.text("Комментарий:"), ui.textfield("concept_comment", concept.getComment()));
IConcept twoButtons = ui.blocks(button("Сохранить", "сохранить после редактирования"), button("Отменить", "отменить редактирование"));
TestAgent
при генерации исходного кода был автоматически помещён объект uiShowWindowMessage
), представляющий ответное сообщение, формируемое по шаблону Шаблон Отобразить окно (класс UiShowWindowMessage
) для отправки агенту ВИД, в котором размещён интерфейс, состоящий из надписи "Простой интерфейс":public void runProduction(UiParamsMessage msg, TestAgentImpl.UiParamsMessageResultCreator rc) throws PlatformException { //... //шаг 2 - построение UI модели с полным интерфейсом для ui-тэга из web-страницы IInforesource uiIr = msg.getUIAbstractModel(); UiBuildHelper ui = new UiBuildHelper(uiIr); //... вызов методов для формирования дочерних элементов в иерархии UI элементов - при необходимости их формирования ... IConcept iFace = ui.xxx(...); // вызов метода для формирования верхнего элемента в иерархии UI элементов, с указанием дочерних элементов в качестве параметров вызова //формирование и отправка ответного сообщения агенту ВИД с указанием построенной модели интерфейса rc.uiShowWindowMessage.create(getUiView(), uiIr).setInterface(iFace); }
local
класса агента. Метаинформацией, в соответствии с которой формируется (порождается/редактируется) данный инфоресурс, является поддерево, корневое понятие которого - "локальная структура данных", находящееся в инфоресурсе агента.
локальная структура данных { история { ~set состояние { ... } } }
Java
, создающий новое состояние в истории состояний, может иметь следующий вид:
IConceptGenerator history = (IConceptGenerator)local.generateFromRoot().getDirectSuccessor("история"); if (history == null) history = local.generateFromRoot().generateCopy("история"); history.generateCopy("состояние");
critical()
— сообщения о критических ошибках;error()
— сообщения об ошибках, возникших при работе блока продукций агента;warning()
— сообщения о предупреждениях (мелких проблемах), возникших при работе блока продукций агента;info()
— общее информационное сообщение (для протоколирования информации общего характера);debug()
— отладочное сообщение (для последующего использования при отладке);trace()
— сообщение для "пошагового" информирования о процессе выполнения блока продукций агента.<внутреннее имя шаблона сообщения>MessageResultCreator
(является типом второго параметра метода runProduction(...)
), описывающий шаблоны сообщений, которые могут быть отправлены агентом из соответствующего блока продукций (шаблоны выходных сообщений блока продукций).
public final <XXX>Message.Creator <xXX>ResultMessage = new <XXX>Message.Creator(this);
<XXX>
— внутреннее имя шаблона сообщения; <xXX>
— внутреннее имя шаблона сообщения, но первый символ в нижнем регистре.<XXX>Message msg = rc.<xXX>.create(<агент-адресат>);
msg
— экземпляр класса-шаблона сообщений <XXX>Message
(название произвольное, задаётся разработчиком агента при написании кода блока продукций);rc
— экземпляр класса-"создателя результатов" <XXX>MessageResultCreator
(является вторым параметром метода runProduction(...)
, название которого определяется решателем Генератор шаблонов кода агентов на этапе 3);<агент-адресат>
— агент, которому должно быть передано данное сообщение.<агент-адресат>
может быть идентифицирован одним из следующим способов:
<агент-адресат>
не является агентом-экземпляром);Long
(десятичная константа с суффиксом L в Java), где x — десятичный разряд(если <агент-адресат>
не является агентом-экземпляром);AgentPtr
(если <агент-адресат>
есть агент-экземпляр).Creator
.runProduction(...)
) коммуникационная система извлекает все созданные в нём сообщения и отправляет их агентам-адресатам.
ru/dvo/iacp/is/iacpaas
)java/math
java/text
java/util
java/time
java/nio/charset
java/lang
, кроме следующих классов:
Runnable
Class
ClassLoader
ClassValue
Compiler
InheritableThreadLocal
Package
Process
ProcessBuilder
ProcessBuilder/Redirect
Runtime
RuntimePermission
SecurityManager
StackTraceElement
System
Thread
ThreadGroup
ThreadLocal
Throwable
Void
ProcessBuilder/Redirect/Type
Thread/State
org/sharegov/mjson
— для работы с JSON
<dependency> <groupId>org.sharegov</groupId> <artifactId>mjson</artifactId> <version>1.4.1</version> </dependency>
MyAgent
, который принимает сообщение SomeMessage
, в ответ на которое высылает себе же сообщение AnotherMessage
и наоборот. На этапе генерации будет создан абстрактный класс-заготовка с именем MyAgent
, где каждому блоку продукций будет соответствовать метод runProduction
:
package ru.dvo.iacp.is.iacpaas.mas.agents; import java.util.Date; import ru.dvo.iacp.is.iacpaas.mas.Message; import ru.dvo.iacp.is.iacpaas.mas.Agent; import ru.dvo.iacp.is.iacpaas.mas.ResultCreator; import ru.dvo.iacp.is.iacpaas.mas.MasFacet; import ru.dvo.iacp.is.iacpaas.mas.exceptions.MasException; import ru.dvo.iacp.is.iacpaas.common.exceptions.PlatformException; import ru.dvo.iacp.is.iacpaas.storage.exceptions.StorageException; import ru.dvo.iacp.is.iacpaas.storage.IInforesource; import ru.dvo.iacp.is.iacpaas.mas.IRunningService; import ru.dvo.iacp.is.iacpaas.mas.messages.*; import ru.dvo.iacp.is.iacpaas.mas.messages.system.*; public abstract class MyAgent extends Agent { //Сгенерированный конструктор public MyAgent(IRunningService runningService, IInforesource agentInforesource) { super(runningService, agentInforesource); } //Сгенерированное описание продукций для диспетчера сообщений static { try { describeProduction( ru.dvo.iacp.is.iacpaas.mas.messages.SomeMessage.class, SomeMessageResultCreator.class, MyAgent.class); describeProduction( ru.dvo.iacp.is.iacpaas.mas.messages.AnotherMessage.class, AnotherMessageResultCreator.class, MyAgent.class); } catch(NoSuchMethodException ex) { throw new RuntimeException(ex); } } //создатель результатов для блока обработчика сообщений по шаблону "SomeMessage") public static final class SomeMessageResultCreator extends ResultCreator { public final ExternalRequestDataMessage.Creator anotherMessage; public SomeMessageResultCreator(MasFacet mas, IRunningService runningService) throws MasException { super(mas, runningService); anotherMessage = new AnotherMessage.Creator(this); } } //создатель результатов для блока обработчика сообщений по шаблону "AnotherMessage") public static final class ExternalRequestDataMessageResultCreator extends ResultCreator { public final SomeMessage.Creator someMessage; public AnotherMessageResultCreator(MasFacet mas, IRunningService runningService) throws MasException { super(mas, runningService); someMessage = new SomeMessage.Creator(this); } } //Сгенерированная заглушка метода runProduction для обработки сообщений по шаблону "SomeMessage" public void runProduction(SomeMessage message, SomeMessageResultCreator rc) throws PlatformException { throw new UnsupportedOperationException(); } //Сгенерированная заглушка метода runProduction для обработки сообщений по шаблону "AnotherMessage" public void runProduction(AnotherMessage message, AnotherMessageResultCreator rc) throws PlatformException { throw new UnsupportedOperationException(); } }
MyAgent
и называться MyAgentImpl
:
package ru.dvo.iacp.is.iacpaas.mas.agents; import java.util.Date; import ru.dvo.iacp.is.iacpaas.mas.Message; import ru.dvo.iacp.is.iacpaas.mas.Agent; import ru.dvo.iacp.is.iacpaas.mas.ResultCreator; import ru.dvo.iacp.is.iacpaas.mas.MasFacet; import ru.dvo.iacp.is.iacpaas.mas.exceptions.MasException; import ru.dvo.iacp.is.iacpaas.common.exceptions.PlatformException; import ru.dvo.iacp.is.iacpaas.storage.exceptions.StorageException; import ru.dvo.iacp.is.iacpaas.storage.IInforesource; import ru.dvo.iacp.is.iacpaas.mas.IRunningService; import ru.dvo.iacp.is.iacpaas.mas.messages.*; import ru.dvo.iacp.is.iacpaas.mas.messages.system.*; public final class MyAgentImpl extends MyAgent { public MyAgentImpl(IRunningService runningService, IInforesource agentInforesource) { super(runningService, agentInforesource); } //Метод runProduction для обработки сообщений по шаблону "SomeMessage" public void runProduction(SomeMessage message, SomeMessageResultCreator rc) throws PlatformException { //логика блока продукций - обработка SomeMessage //... //отправка сообщения AnotherMessage без каких-либо данных агенту (самому себе) по заданному адресу (в фонде) rc.anotherMessageResultCreator.create("<Логин пользователя>/ Мой фонд / Тестовый раздел / Мой агент"); } //Метод runProduction для обработки сообщений по шаблону "AnotherMessage" public void runProduction(AnotherMessage message, AnotherMessageResultCreator rc) throws PlatformException { //логика блока продукций - обработка AnotherMessage //... //отправка сообщения SomeMessage без каких-либо данных исходному агенту (самому себе) rc.someMessageResultCreator.create(rc.getSender()); } }
исполняемый код
. Если выполнены все необходимые условия: