diff --git a/documentation/JSON Models Generation.md b/documentation/JSON Models Generation.md new file mode 100644 index 0000000..6e56893 --- /dev/null +++ b/documentation/JSON Models Generation.md @@ -0,0 +1,124 @@ +## Описание генератора JSON моделей + +Генератор JSON моделей - это скрипт, который автоматически создает классы JSON моделей на основе описания их схемы в файле формата YAML. + +Генерируется 2 типа классов: +- классы, описывающие enum; +- классы, описывающие модели. + +Классы моделей размечаются для работы с библиотекой LoganSquare и наследуется от абстракного класса `ApiModel`, содержащего логику валидации. + +Классы моделей содержат в себе: +- конструктор без параметров; +- конструктор со всеми возможными параметрами в случае, если модель не наследуется ни от какой другой модели; +- приватные поля, описывающие параметры модели; +- публичный `getter` и `setter` для каждого поля модели; +- метод `validate` для валидации модели; +- метод `equals` и `hashCode` на основе всех содержащихся полей; +- метод `writeObject` и `readObject` для стандартной сериализации объекта; +- метод `copy` для создания копии объекта. Создается только в случае, если модель не наследуется ни от какой другой модели. + +**ВАЖНО!** Копирование через метод `copy` не гарантирует копирование всех объектов, содержащихся во всех полях. + +## Подключение и использование генератора + +Подключаем сабмодуль [BuildScripts](https://github.com/TouchInstinct/BuildScripts) в папку libraries. + +Чтобы подключить скрипт, добавьте в конец файл `build.gradle` модуля следующую строку: +```gradle + apply from: "${rootDir}/libraries/BuildScripts/gradle/jsonModelsGeneration.gradle" +``` + +Чтобы зарегистрировать YAML файлы для генерации моделей, в секцию `android` надо добавить: +```gradle +android { + extensions.jsonModelsMapping = ["schemes/api_models.yaml -> ${defaulConfig.applicationId}.logic.api.model", + "schemes/internal_models.yaml -> ${defaulConfig.applicationId}.logic.model"] + } +``` +- `schemes/api_models.yaml` - путь к файлу схемы. По умолчанию относительно папки модуля, но можно указать и абсолютный путь; +- `->` - разделитель; +- `${applicationId}.logic.api.model` - package-name моделей, которые будут сгенерированы на основе этого файла. + +## Структура файла YAML + +YAML файл может содержать 3 типа объектов: описание модели, описание enum, импортированные классы. + +### Описание модели +Описание начинается с `class MyModel:`, где `MyModel` - это имя класса, который будет сгенерирован. + +Затем для класса идет описание параметров класса: +- параметр `typeArguments: TResponse, TData` добавляет к классу указанные аргументы: `class MyModel`; +- параметр `extends: BaseResponse` наследует класс от указанного класса: `class MyModel extends BaseResponse`; +- параметры, описывающие поля класса, например `name: string` добавляет поле типа `String` с названием `name`. + +### Описание параметра поля класса +В простом виде поле добавляется, как `name: string`. То есть, указывается имя поля и его тип. + +Вообще, поле может быть описано следующими параметрами: +1. Название параметра - это имя поля; +2. `jsonName`, необязательное - имя параметра в разметке JSON, соответсвующее полю. По умолчанию берется ; +3. `type`, обязательное - тип поля. Разрешенные типы: + - строки `string`, `String`; + - целые числа `int`, `Integer`, `long`, `Long`; + - дробные числа `float`, `Float`, `double`, `Double`; + - буленовские значения `boolean`, `Boolean`; + - дата/время `date`, `datetime`, `DateTime`; + - списки `List<*>`; + - мапы `Map; + - описанные в этом же файле enum'ы; + - описанные в этом же файле импортированные классы; +4. `flags`, необязательное - флаги для валидации объекта. Перечисляются через запятую, могут быть: + - `nullable` - в поле может прийти null. По умолчанию все поля считаются `non-null`; + - `missable` - JSON может не содержать такого поля. По умолчанию все поля считаются `non-missable`; + - `solid` - если поле содержит коллекцию, то все элементы в ней обязаны быть валидными. По умолчанию не валидные элементы исключаются из коллекции на этапе валидации; + - `non-empty` - если поле содержит коллекцию, то она не должна быть пустой. По умолчанию пустые коллекции разрешены. + +### Пример описания моделей: +```yaml +class SimpleModel: + name: string + age: int + birthDate: date + +class ComplexModel: + id: + type: long + jsonName: object_id + usersList: + type: List + flags: solid, non-empty + hasSomeInfo: + type: boolean + jsonName: has_info + flags: nullable +``` + +### Описание enum'a +Описание начинается с `enum MyEnum:`, где `MyEnum` - это имя enum'a, который будет сгенерирован. + +Затем идет перечисление всех возможных значений в формате `VALUE: json_value`, где `VALUE` - имя значения в enum'e, а `json_value` - соответствующая этому значению строка в JSON. + +Пример: +```yaml +enum SimpleEnum: + MALE: male_gender + FEMALE: female_gender +``` + +### Описание импортированных классов +Импортированные классы добавляются списком в разделе `imports`. Все классы должны быть указаны полным именем. + +Пример: +```yaml +imports: + - android.util.Pair + - com.myproject.model.UserExtension + +class MyModel: + pair: Pair + users: List +``` +Импортированные классы нужно использовать в двух случаях: +1. Для них заргеистрированы конвертеры в LoganSquare; +2. Это расширенные или кастомные модели, описанные для LoganSquare вручную. diff --git a/gradle/staticAnalysis.gradle b/gradle/staticAnalysis.gradle index e1db99a..0e8d4dc 100644 --- a/gradle/staticAnalysis.gradle +++ b/gradle/staticAnalysis.gradle @@ -13,9 +13,7 @@ gradle.projectsEvaluated { "-Xlint:deprecation" << "-Xlint:finally" << "-Xlint:overrides" << - "-Xlint:path" << - "-Xlint:unchecked" << - "-Werror" + "-Xlint:path" } def excludes = rootProject.extensions.findByName("staticAnalysisExcludes") diff --git a/lint/lint.xml b/lint/lint.xml index dab6ff4..a52b865 100644 --- a/lint/lint.xml +++ b/lint/lint.xml @@ -204,7 +204,6 @@ - @@ -266,5 +265,6 @@ + \ No newline at end of file