Перейти к основному содержанию
`Ctrl`+`K`

# Проектное переопределение

## Предисловие

Стоит отдельно указать, что помимо проектного переопределения существует так же опция наследования базовых файлов в проектных модулях. Для того чтобы выбрать нужный подход, следует понимать что требуется сделать:

- Переопределить базовую логику так, что бы изменилось поведение этой логики в любом месте системы.

  Например, если вы хотите во всей системе изменить выборку Bs_GoodsAvi#Card, добавить туда проектные атрибуты, изменить разметку выборки итд, и при этом вы хотите видеть эти изменения абсолютно во всех местах где вызывается эта выборка (аналогично с переопределением api и иных файлов).

Проектное переопределение

- Дополнить базовую логику работы и использовать её локально, в определенных ситуациях.

  Например, если вы хотите дополнить вкладку Bs_GoodsAvi#Card проектными атрибутами, изменить её разметку и т.д при этом измененную вкладку вы хотите видеть в каком-то конкретном отображении, а в остальной системе оставить вид этой выборки базовым (аналогично с переопределением api и иных файлов).

Наследование базовой логики

# Наследование базовой логики

Обычное наследование функционала. Реализуется с помощью ключевого слова `extends`. Определимся только с установленными практиками наименования и расположения наследующих файлов. В остальном работают обычные правила наследования. Рассмотрим пример наследования от `Rpl_QueryAvi`, и создание нового трейта с измененной логикой.

## Расположение наследующего файла

Наследующий файл в вашем проекте должен располагаться в соответствующем модуле для проектных переопределений. Так же желательно повторять структуру директорий базового модуля. Так, если `Rpl_QueryAvi` расположен по следующему пути:

    ru.bitec.app.rpl.channel.intg.out.Rpl_QueryAvi,

Наследующий его файл рекомендуется располагать в:

    ru.bitec.app.<Имя проектного модуля переопределений>.channel.intg.out.<Имя наследующего файла>

## Наименование наследующего файла

При наследовании базового файла в ваш имя наследующего файла рекомендуется формировать следующим образом:

`<Имя проектного модуля переопределений>_<Имя базового класса БЕЗ имени базового модуля>`. Например, для `Rpl_QueryAvi` имя наследующего файла будет выглядеть так - `<Имя проектного модуля переопределений>_QueryAvi`.

### Пример наследующего файла

        package ru.bitec.app.<Имя проектного модуля переопределений>.channel.intg.out

        import ru.bitec.app.rpl.channel.intg.out.Rpl_QueryAvi
        import ru.bitec.gtk.core.AvmFile

        @AvmFile(name = "Файл разметки.avm.xml")
        class <Имя проектного модуля переопределений>_QueryAvi extends Rpl_QueryAvi{

            override def card(): Card = {
                new Card {
                    override def meta = this
                }
            }

            trait Card extends Default with super.Card {
                ...
            }

        }

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

# Проектные переопределения

Рассмотрим проектное переопределение на примере класса. Проектное переопределение выборок без класса, `pkg` и `lib` файлов происходит аналогично.

## Проектное переопределение файлов окружения класса

- Часто возникает необходимость переопределить или дополнить функционал определенного класса, в таком случае переопределяются нужные элементы окружения класса. Переопределяются обычно `Avi`, `Api` и `avm.xml` файлы окружения класса.

### Переопределение Api

1. Внутри проектного модуля `.../src/main/scala/ru.bitec.app.проектный_модуль.<Если файл вложен в поддиректории, то нужно повторить их структуру>` создайте api-файл.

   - Имя файла задавайте по следующему шаблону: `<Имя Класса С ИМЕНЕМ БАЗОВОГО МОДУЛЯ ЭТОГО ДЛЯ КЛАССА>OverrideApi`.

     Примечание

     Обычно имена классов и файлов получаются с использованием имени модуля и имени класса `***_ИмяКласса`, однако для переопределяемых файлов не рекомендуется использовать такой подход. Лучше модифицировать имя базового файла. Например: `Bs_GoodsApi` -> `Bs_GoodsOverrideApi`.

     Внимание

     ВАЖНО! При составлении имени файла НЕ используйте имя текущего модуля! В имя файла добавляется только суффикс `Override`

2. Содержание файла должно быть следующим:

       package ru.bitec.app.<имя проектного модуля>.bs

       import ...

       class Bs_GoodsOverrideApi extends Bs_GoodsApi {
           Код класса
       }

       object Bs_GoodsOverrideApi extends ApiFactory[
           java.lang.Long,
           Bs_GoodsAro,
           Bs_GoodsOverrideApi
       ]

3. Внутри тела класса можете переопределять существующие методы и добавлять новые.

### Переопределение Avi

1. В том же пакете что и api: `.../src/main/scala/ru.bitec.app.проектный_модуль/bs.<Если файл вложен в поддиректории, то нужно повторить их структуру>`, создайте Avi-файл:

   - Имя файла получаем аналогично имени api-файла.

     Например: `Bs_GoodsAvi` -> `Bs_GoodsOverrideAvi`.

         package ru.bitec.app.<имя проектного модуля>.bs

         import ...

         object Bs_GoodsOverrideAvi extends Bs_GoodsOverrideAvi

         @AvmFile(name = "Bs_GoodsOverride.avm.xml")
         class Bs_GoodsOverrideAvi extends Bs_GoodsAvi {
             Код выборок
         }

     Внимание

     ВАЖНО! При составлении имени файла НЕ используйте имя текущего модуля! В имя файла добавляется только суффикс `Override`

   - Общая структура файла аналогично обычному Avi-файлу.

   - Объект-компаньон должен иметь имя как у переопределяемого файла.

   - Аннотация `@AvmFile(name = "Bs_GoodsOverride.avm.xml")` не обязательна. Если ее не указывать, то будет взята настройка базового файла.

2. Внутри тела выборки можете переопределять существующие трейты и их методы, а так же создавать новые трейты и методы (в т.ч. внутри переопределенных трейтов).

### Переопределение Avm

1. Рекомендуется создавать avm-файл в директории: `.../src/main/resources/ru.bitec.app.проектный_модуль.<Если файл вложен в поддиректории, то нужно повторить их структуру>`, и уже в нем создавайте файл с разметкой.

- Структуры каталогов в разных ветках будут идентичны.

  Например:

  `.../src/main/`scala`/ru.bitec.app.проектный_модуль/bs` - для проектной логики .

  `.../src/main/`resources`/ru.bitec.app.проектный_модуль/bs` - для проектной разметки.

2. Базовая структура полностью аналогична обычным amv-файлам.

   - В теге `view` указываем имя класса и дополнительное свойство `th:extends`:

         <view xmlns="http://www.global-system.ru/xsd/global3-view-1.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.global-system.ru/xsd/global3-view-1.0"
         xmlns:th="http://www.global-system.ru/xsd/global3-view-template-1.0"
         name="Bs_GoodsOverride" th:extends="Bs_Goods.avm.xml">

   - `name` - имя переопределенного файла, получаем аналогично прошлым пунктам.

     Внимание

     ВАЖНО! При составлении имени файла НЕ используйте имя текущего модуля! В имя файла добавляется только суффикс `Override`

   - `th:extends` - базовый avm-файл, нужен для того, что бы в переопределенном файле указывать только проектную разметку. Остальные настройки будут вытягиваться из базового файла.

3. Если вы переопределили Avi-файл и создали там новый трейт, или переопределили существующий трейт Avi-файла, изменив возвращаемые данные(добавили новые атрибуты выборки, переименовали старые итд) тогда в avm нужно создать тег `representation` с именем, соответствующим имени этого трейта, и настроить разметку.

4. Так же, если вам требуется проектно переопределить только разметку, нужно помимо этого переопределить Avi-файл и указать переопределенный файл разметки в аннотации.

   Внимание

   Включение переопределенных файлов разметки отличается от включения переопределенной логики `Api` и `Avi` Что бы подключить переопределенную разметку, нужно в соответствующем Avi-файле для класса использовать аннотацию @AvmFile(name = «Bs_GoodsOverride.avm.xml»)

### Включение проектной логики

- После того, как вы создали необходимые вам переопределения проектной логики, требуется связать переопределяемый и переопределяющий файлы.

- Для этого в проектном модуле, в каталоге `/src/main/resources/META-INF` откройте или создайте файл `overrides.xml`

      <?xml version="1.0" encoding="UTF-8"?>
      <overrides>
          <replace-with class="ru.bitec.app.<Имя проектного модуля>.<Имя модуля, которому принадлежит переопределяемый файл>.<Имя переопределенного файла>">
              <when-type-is class="ru.bitec.app.<Имя модуля, которому принадлежит переопределяемый файл>.<Имя переопределяемого файла>"/>
          </replace-with>
      </overrides>

  - В теге `replace-with` укажите свойство `class` - относительный путь до переопределенного файла начиная с каталога `ru.bitec.app`.

  - В теге `when-type-is`, вложенном в предыдущий тег, укажите относительный путь до базового файла, так же начиная с каталога `ru.bitec.app`.

- Так например, если вы переопределили Api и Avi:

      <?xml version="1.0" encoding="UTF-8"?>
      <overrides>
          ....
          <replace-with class="ru.bitec.app.<ProjectModule>.bs.Bs_GoodsOverrideAvi">
              <when-type-is class="ru.bitec.app.gds.Bs_GoodsAvi"/>
          </replace-with>
          <replace-with class="ru.bitec.app.<ProjectModule>.bs.Bs_GoodsOverrideApi">
              <when-type-is class="ru.bitec.app.gds.Bs_GoodsApi"/>
          </replace-with>
          ....
      </overrides>

Примечание

Так же стоит заметить, что если вы переопределили какой-либо api/avi-файл, и в нем переопределили метод(ы) базового api/avi, тогда в другой части кода вы можете вызывать эти методы используя имя базового файла, ваша проектная логика будет подхватываться системой и вызываться от имени базового файла. Однако, если вы добавили новый метод, который отсутствует в базовом файле, вызывать его придется, используя имя переопределенного файла.