# Урок 8. Дополнительные возможности В данном уроке рассматриваются: - Поиск по шаблону - Универсальный фильтр - Работа с файлами - Точки расширений - Проектное переопределение кода - Шаблоны thymeleaf - Логирование - Мониторинг производительности - SSH-сервис сервера приложений - Локализация приложений - Миграция данных ## Поиск по шаблону [Руководство разработчика: Сервисные возможности для классов # Поиск по шаблону](books/AppGuide/030_class/070_сервисы_класса.md#поиск-по-шаблону) ## Универсальный фильтр Универсальный фильтр - сервис позволяющий осуществлять фильтрацию в списках. Позволяет фильтровать записи по коллекциям и значениям атрибутов объектов, на которые ссылаются объекты текущего класса. [Руководство по универсальному фильтру](books/AppGuide/040_selection/160_универсальный_фильтр.md) ## Работа с файлами Сервис прикрепленных файлов позволяет прикреплять к объектам класса произвольные файлы, которые сохраняются в специальном хранилище на сервере и сопоставляются с конечным объектом-владельцем. [Руководство разработчика: Сервисы класса # Сервис прикрепленных файлов](books/AppGuide/030_class/070_сервисы_класса.md#сервис-прикрепленных-файлов) ## Шаблоны Thymeleaf Шаблонизатор [Thymeleaf](https://www.thymeleaf.org/) используется для реализации наследования разметки выборки. [Руководство разработчика: Выборки # Использование шаблонов в разметке](books/AppGuide/040_selection/080_выборка.md#разметка-выборки) Кроме использования шаблонизации в разметке, есть возможность использования шаблонов и в прикладном коде, например, формировать текст для html-фреймов. ## Точки расширений Функционал для исполнения кода в модулях, от которых нет зависимости. [Руководство разработчика: Дополнительные возможности # Точка расширения](books/AppGuide/080_addition/030_проектные_расширения.md#точка-расширения) ## Проектное переопределение кода С помощью проектного переопределения возможно заменить оригинальные выборки/отображения или исполняемые методы проектными. [Руководство разработчика: Дополнительные возможности # Проектное перекрытие кода Api, Avi, Lib, Pkg](books/AppGuide/080_addition/030_проектные_расширения.md#проектное-перекрытие-кода-api,-avi,-lib,-pkg) ## Логирование Для логирования существует сразу несколько инструментов: - Логирование через `Btk_Log` Использует специальную коллекцию переменной ссылочности `Btk_Log` и пишет данные в базу. Для логирования коллекция подключается как обычно, после чего доступны для использования методы вставки записей через обычные транзакции или автономные - Логирование сервера приложений Использует `Logger` сервера для вывода информации в консоль. Для логирования есть методы `trace`, `debug`, `info`, `warn` и `error`, которые сохраняют в консоли сервера переданные сообщения с соответствующим уровнем. Пример использования - ```scala _logger.info("Пересчет регистра прав ролей") ``` - Логирование в инфо-панель Использует `InfoLog` приложения для записи информации в лог сообщений. Для вывода сообщений создано отображение `Btk_InfoLogAvi#Default`, которое принято выводить на отдельной панели для основной выборки приложения в нижней части. Для логирования есть методы `info`, `warn`, `error` и `confirm`, которые сохраняют в логере переданные сообщения с соответствующим уровнем. Пример использования - ```scala application.infoLog.error("Отмена загрузки файла") ``` Пример открытия инфо-панели - ```scala val vMaster = application.mainSelection if (vMaster.form.findSelection(Btk_InfoLogAvi.default()) == null) { vMaster.createPanelBuilder(Btk_InfoLogAvi.default()).align(Align.bottom).toggle() } ``` Вручную инфо-панель можно открыть/закрыть из меню `Сервис -> Открыть информационную панель` - Логирование действий пользователя Используется для отслеживания процесса выполнения запросов и подстановки параметров, последовательности вызова операций и открытия форм. [Руководство разработчика: Отладка приложений # Логирование на сторону клиента](books/AppGuide/050_tools/130_отладка_приложений.md#логирование-на-сторону-клиента) ## Мониторинг производительности [Руководство разработчика: Отладка приложений # Мониторинг производительности](books/AppGuide/050_tools/130_отладка_приложений.md#мониторинг-производительности) Наиболее часто используется [VisualVM](https://visualvm.github.io/) для поиска узких мест в части обращений к базе данных. Пример результата мониторинга производительности с использованием `VisualVM`: ![G3System](img/VisualVMExample.png) По данным можно определить наличие одинаковых повторяющихся обращений к базе данных или запросы, которые выполняются слишком долго, для дальнейшей оптимизации работы бизнес-логики ## SSH-сервис сервера приложений [Руководство разработчика: Сервисы сервера приложений # SSH консоль сервера](books/AppGuide/080_addition/140_сервисы_сервера.md#ssh-консоль-сервера) ## Локализация приложений [Руководство разработчика: Сервисы сервера приложений # SSH консоль сервера](books/AppGuide/080_addition/010_локализация_приложения.md) ## Миграция данных [Руководство разработчика: Релиз прикладного решения](books/AppGuide/070_development/030_релизы.md#релиз-прикладного-модуля) ## Практическое задание ### Поиск по шаблону 1. Для книг добавьте поле "Описание" в перечень полей, по которым будет работать поиск. Проверьте, что при вводе части описания книги осуществляется подбор книги в ссылочном поле. 1. Для книг переопределите метод поиска по шаблону, сделайте возможность поиска по автору и году публикации книги. Например, при вводе значения `Иванов 2002` искались книги, чей автор `Иванов` и год публикации `2002` Для этого: - Переопределите метод поиска по шаблону в `Api` класса `Книга` - Если текст не содержит пробелов, то вызывайте стандартный метод поиска по шаблону. - Входящий текст бейте на 2 части, определяя автора и год выпуска. - Если вторая часть текста - число, то: - осуществите поиск авторов по первой части введенного текста (вызовите метод поиска по шаблону) - если авторы найдены, то запросите книги по этим авторам, чей год публикации подходит под условие поиска. - если записей не найдено, то вызывайте стандартный метод поиска по шаблону Проверьте, что при вводе автора и года выпуска в ссылочное на книгу поле осуществляется новая логика поиска (в позициях документа). ~~~{note} Для проверки, что строка является числом, используйте метод `org.apache.commons.lang3.math.NumberUtils#isCreatable` ~~~ ### Универсальный фильтр 1. Отключите доступность фильтрации по полю "Описание" для списка книг. 1. Для книг подключите новую коллекцию универсального фильтра, позволяющую фильтроваться по позициям заказов `Lbr_InOrderDet`. 1. Из списка авторов реализуйте операцию открытия книг текущего автора, для этого передайте в открываемый список книг условие универсального фильтра, наложенное по полю `idAuthor` ### Работа с файлами 1. Создайте на диске `C` папку `storage` и настройте в системе файловые хранилища, указав данный путь `c:\storage` и тип хранилища `Локальное` [Руководство разработчика: Сервисы класса # Файловое хранилище](books/AppGuide/030_class/070_сервисы_класса.md#файловое-хранилище) 2. В odm класса `Lbr_InAct` настройте сервис прикрепленных файлов в простом режиме. 3. Запустите кодогенерацию, скомпилитесь, обновите код, библиотеки, orm. 4. В справочнике закладок найдите закладку с системным именем `Btk_AttachItemAvi.List_SimpleAttach` и добавьте в детализацию класс `Lbr_InAct` 5. В справочнике типов объекта отфильтруйтесь по классу `Lbr_InAct` и для найденных типов настройте новую закладку `Прикрепленные файлы` 6. После сброса всех кэшей, переоткройте карточку накладной и на новой закладке попробуйте добавить файлы (например `readme.txt`) ### Точки расширений 1. Добавьте scala class для расширений `Lbr_BtkExt` (шаблон для создания Global Ext) 2. Добавьте расширением метода `deleteObjectTypeBefore`, в котором будет проверка, что для удаляемого типа объекта нет документов, в которых он был бы указан. ### Проектное переопределение кода 1. Переопределите в модуле `lbr` класс `Bs_PersonAvi` 1. Создайте `avm`-файл, и унаследуйте его от базовой `avm` используя язык шаблонов. 1. Добавьте в переопределенную выборку фильтр-галку "С невыполненными приходными накладными". При включенном фильтре должны выводиться только те записи, на которые есть ссылки в документах `Lbr_InAct` с состоянием < 300 1. Убедитесь, что при открытии списка физических лиц выводится новый фильтр (список можно открыть из карточки Приходной накладной - атрибута "Библиотекарь") ### Логирование 1. В позициях возврата книг `Lbr_InOrderDet` на создание записей по мультиселекту добавьте запись в инфо-панель с перечнем книг, добавленных по операции. 1. При создании позиции `Lbr_InOrderDet` должна открываться инфо-панель, если она закрыта. ### Мониторинг производительности 1. Подключите `VisualVM` к запущенному серверу 1. Запустите запись отслеживания соединений с БД 1. Добавьте книги в позиции возврата книг `Lbr_InOrderDet` и посмотрите результат мониторинга ### SSH-сервис сервера приложений 1. Используя Putty подключитесь к SSH-серверу 1. Подключитесь к базе данных для выполнения сервисных операций 1. Выполните создание/обновление объектов схемы БД ### Миграция данных 1. Создайте миграционный пакет для модуля `lbr` 1. Добавьте в него `upTask`, в котором для всех объектов класса `Lbr_Publisher`, которые не входят не в одну из групп, будет регистрироваться запись в `Btk_ObjectGroup` и устанавливаться корневая группа класса. 1. Запустите миграцию по модулю `lbr` через `external tools` - `Run Migrations` 1. Создайте миграционные скрипты модуля `lbr` 1. Напишите скрипт, который обновит для таблицы `lbr_book` колонку `sDesc`. Для всех записей, у которых не заполнена это колонка, установите в него значение колонки `sCaption` 1. Запустите миграцию по модулю `lbr` через `external tools` - `Run Migrations`