Разработка кодов операций над инфоресурсами
Операции над инфоресурсом являются механизмом для хранения кода, доступного агентам для вызова без необходимости использования более весомого механизма - обмена сообщениями с другими агентами. При использовании (вызове) кода операции не теряется местоположение в потоке управления исполняемого блока продукций, тогда как после обращения к другому агенту ответное сообщение инициирует работу блока продукций исходного агента с её начала, что не всегда является удобным.
Цель разработки кодов операций для некоторого набора инфоресурсов (сформированных по единой метаинформации) - сформировать библиотеку методов, реализующих некрупные операции исключительно над одним обрабатываемым информационным ресурсом, которые могли бы быть полезны различным агентам, но в то же время группировка их в отдельный агент не является целесообразной. Набор операций над инфоресурсом прикрепляется к метаинформации, а их исполнение вызывается для некоторого целевого инфоресурса, созданного по этой метаинформации.
Процесс реализации кода операций над инфоресурсом состоит из следующих шагов:
- написание исходного кода на Java с применением API платформы - разработка класса Operations;
- формирование байткода этого класса;
- формирование архива с необходимыми файлами;
- загрузка архива в платформу с прикреплени к инфоресурсу-метаинформации.
После этого данные коды операций могут быть вызваны из кода блоков продукций некоторого агента (и, при необходимости, из других кодов операций).
При написании исходного кода каждой операции над информационным ресурсом необходимо использовать следующий шаблон (класс: Operations, пакет: ru.dvo.iacp.is.iacpaas.storage, файл: Operations.java):
package ru.dvo.iacp.is.iacpaas.storage;
import ru.dvo.iacp.is.iacpaas.storage.exceptions.StorageException;
@SuppressWarnings({"UnusedDeclaration"})
public class Operations
{
// DO NOT CHANGE THIS PART - START
private IInforesource ir;
private Object caller;
public Operations(IInforesource ir, Object caller)
{
this.ir = ir;
this.caller = caller;
}
// DO NOT CHANGE THIS PART - END
/** uncomment and write your operation signature and code:
* 1) replace "operationName" with your name and set its return type instead of "Object" prior to name (leave "public"!)
* 2) define types (instead of "Object") and names (instead of "param1", ...) of parameters (they may be absent)
* 3) if StorageException can occur - uncomment it
* 4) write operation codes as if in a productions block of an agent
* 5) return object of appropriate class (if needed)
*/
// public Object operationName(Object param1, Object param2, ...) // may return some POD or Fund objects or ever arrays/sets
// // throws StorageException
// {
// //place code
//
// //return value if needed
// }
}
Скачать заготовку исходного кода
Скачать API
Данный файл с классом необходимо в проекте разработки используемой IDE разместить в папке исходников в подпапках согласно имени пакета - ru / dvo / iacp / is / iacpaas / storage. Также в проект разработки необходимо подключить API платформы (аналогично его подключению при разработке кода блоков продукций агентов).
При написания кода операции следует:
- снять комментарии // ;
- указать требуемый тип возвращаемого значения (вместо Object);
- задать имя операции (вместо operationName);
- перечислить требуемые параметры и их типы (вместо Object param1, ...);
- написать код (вместо …code…), используя caller для проверки доступа при вызовах методов API;
- вернуть объект требуемого класса, если это необходимо (операция не void).
По окончании написания исходного кода его необходимо скомпилировать в байт-код, используя средства применяемой IDE или компилятор из JDK.
Результирующий файл Operations.class необходимо поместить в zip-архив вместе с файлом исходного кода (Operations.java - он может быть использован в дальнейшем для доработки и добавления новых операций) и файлом текстовых описаний этих операций в произвольном виде (Operations.txt - для ознакомления перед использованием/вызовом). Эти три файла располагаются в корне архива - без каких-либо каталогов.
Данных архив необходимо прикрепить к инфоресурсу, представляющему метаинформацию, при помощи его редактирования. Для этого в редакторе нужно перейти в меню "операции", нажать кнопку "Обзор", указать в диалоге архивный файл. После этого он будет прикреплён к инфоресурсу и об этом будет сообщаться в первйо строке данного меню: "Вычислительные операции: исходный код - загружен; байт-код - загружен; описание - загружено.". Этот же пункт меню необходимо использовать для ознакомления с имеющимися кодами операций перед их использованием и для их доработки - кнопка "Скачать архив с кодами операций".
Для вызова и исполнения операций в блоках продукций агентов в API платформы (интерфейс IInforesource) присутствует метод callOperation. То есть его вызов осуществляется у объекта, реализующего этот интерфейс и представляющего целевой инфоресурс (т.е. это может быть входной, выходной, временный инфоресурс сервиса или собственный инфоресурс решателя). При вызове метода ему в параметрах необходимо передать:
- имя операции – строка
- вызывающий объект - ссылка на агента (для проверок доступа к обрабатываемому ИР)
- набор параметров операции – объекты некоторых классов, согласно сигнатуре операции
Возвращаемое значение в коде агента необходимо кастовать от типа Object к требуемому типу.
На языке Java сигнатура метода callOperation выглядит так:
public Object callOperation(String operationName, Object caller, Object params)
При исполнении этого метода платформа выполняет следующие шаги:
- извлекает из метаинформации обрабатываемого инфоресурса класс с байткодом операций;
- находит указанный метод (operationName) с набором указанных параметрв (params) в этом классе;
- в случае наличия такого метода - создаёт объект этого класса, вызав конструктор, после чего вызывает этот метод.
Пример.
Ниже приводится исходный код операции по получению первой истории болезни для заданного имени из архива историй болезни.
package ru.dvo.iacp.is.iacpaas.storage;
import ru.dvo.iacp.is.iacpaas.storage.exceptions.StorageException;
@SuppressWarnings({"UnusedDeclaration"})
public class Operations
{
private IInforesource ir;
private Object caller;
public Operations(IInforesource ir, Object caller)
{
this.ir = ir;
this.caller = caller;
}
public IConcept getCaseRecordForName(String name)
throws
StorageException
{
for (IConcept caseRecord : ir.getRoot(caller).getChildren())
if (caseRecord.getName().equals(name))
return caseRecord;
return null;
}
}
Вызов операции происходит следующим образом:
runProduction(InMessage msg, ...)
//...
{
//...
//получить архив историй болезни
IInforesource archive = msg.getCaseRecordArchive();
IConcept petrovCaseRecord = (IConcept)archive.callOperation("getCaseRecordForName", this, "Петров");
//...
}
Описание операции в файле Operations.txt помещается, например, такое:
Список операций над базой историй болезни:
1) IConcept getCaseRecordForName(String name)
возвращает первую попавшуюся историю болезни (корень поддерева, представляющего историю болезни) для пациента с указанным именем
входные параметры - String name - имя пациента (имя истории болезни должно полностью с ним совпадать)
результат - IConcept - корень поддерева, представляющего эту историю болезни