diff --git a/README.MD b/README.MD index 48a7df3b4..3ca8037bd 100644 --- a/README.MD +++ b/README.MD @@ -12,9 +12,18 @@ [![GitHub Releases](https://img.shields.io/github/downloads/1c-syntax/mdclasses/latest/total?style=flat-square)](https://github.com/1c-syntax/mdclasses/releases) ## Сайт проекта (документация) + - [Релизная версия](https://1c-syntax.github.io/mdclasses/) - [Текущая (Develop) версия](https://1c-syntax.github.io/mdclasses/dev/) +## Лицензия + +Проект распространяется под лицензией [GNU LGPL v3](https://www.gnu.org/licenses/lgpl-3.0.ru.html). + +## Связанные проекты + +- [BSL Language Server](https://github.com/1c-syntax/bsl-language-server) - языковой сервер для языка 1С:Предприятие + ## Спасибо контрибьютерам diff --git a/docs/ru/examples.md b/docs/ru/examples.md index 73358ee61..b69c84a04 100644 --- a/docs/ru/examples.md +++ b/docs/ru/examples.md @@ -1,3 +1,410 @@ -# Примеры использования +# Примеры использования MDClasses -*В разработке* +В этом документе представлены примеры использования библиотеки MDClasses для работы с метаданными 1С. + +## Оглавление + +- [Базовые операции](#базовые-операции) +- [Работа с конфигурацией](#работа-с-конфигурацией) +- [Работа с метаданными](#работа-с-метаданными) +- [Работа с формами](#работа-с-формами) +- [Работа с модулями](#работа-с-модулями) +- [Поиск и фильтрация объектов](#поиск-и-фильтрация-объектов) +- [Практические сценарии](#практические-сценарии) + +## Базовые операции + +### Инициализация парсера и чтение конфигурации + +```java +// Сначала стандартные библиотеки Java +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +// Затем библиотеки сторонних разработчиков +import com.github._1c_syntax.bsl.mdclasses.MDClasses; +import com.github._1c_syntax.bsl.mdo.AccumulationRegister; +import com.github._1c_syntax.bsl.mdo.Catalog; +import com.github._1c_syntax.bsl.mdo.Configuration; +import com.github._1c_syntax.bsl.mdo.Document; +import com.github._1c_syntax.bsl.mdo.Form; +import com.github._1c_syntax.bsl.mdo.FormItem; +import com.github._1c_syntax.bsl.mdo.InformationRegister; +import com.github._1c_syntax.bsl.mdo.MD; +import com.github._1c_syntax.bsl.mdo.MdoReference; +import com.github._1c_syntax.bsl.mdo.Module; +import com.github._1c_syntax.bsl.mdo.ModuleType; +import com.github._1c_syntax.bsl.mdo.Right; +import com.github._1c_syntax.bsl.mdo.Role; +import com.github._1c_syntax.bsl.mdo.Subsystem; +// ... и другие объекты метаданных + +// Путь к каталогу конфигурации +Path configurationPath = Paths.get("path/to/configuration"); + +// Чтение конфигурации +Configuration configuration = MDClasses.createConfiguration(configurationPath); +``` + +### Получение основной информации о конфигурации + +```java +// Название конфигурации +String name = configuration.getName(); +System.out.println("Имя конфигурации: " + name); + +// Синоним конфигурации +String synonym = configuration.getSynonym(); +System.out.println("Синоним конфигурации: " + synonym); + +// Версия конфигурации +String version = configuration.getVersion(); +System.out.println("Версия: " + version); + +// Поставщик +String vendor = configuration.getVendor(); +System.out.println("Поставщик: " + vendor); +``` + +## Работа с конфигурацией + +### Обход подсистем + +```java +// Получение всех подсистем верхнего уровня +configuration.getSubsystems().forEach(subsystem -> { + System.out.println("Подсистема: " + subsystem.getName()); + + // Получение дочерних подсистем + subsystem.getSubsystems().forEach(childSubsystem -> { + System.out.println(" - Дочерняя подсистема: " + childSubsystem.getName()); + }); +}); +``` + +### Получение списка всех объектов конфигурации + +```java +// Получение всех объектов конфигурации +List allObjects = configuration.getAllMdo(); + +// Для работы со справочниками +List catalogs = configuration.getCatalogs(); + +// Для работы с документами +List documents = configuration.getDocuments(); + +// Вывод количества объектов по типам +Map objectCountByType = allObjects.stream() + .collect(Collectors.groupingBy( + obj -> obj.getClass().getSimpleName(), + Collectors.counting() + )); + +objectCountByType.forEach((type, count) -> { + System.out.println(type + ": " + count); +}); +``` + +## Работа с метаданными + +### Работа со справочниками + +```java +// Получение всех справочников +List catalogs = configuration.getCatalogs(); + +catalogs.forEach(catalog -> { + System.out.println("Справочник: " + catalog.getName()); + + // Получение реквизитов справочника + catalog.getAttributes().forEach(attribute -> { + System.out.println(" Реквизит: " + attribute.getName() + + ", Тип: " + attribute.getType().getDescription()); + }); + + // Получение табличных частей + catalog.getTabularSections().forEach(section -> { + System.out.println(" Табличная часть: " + section.getName()); + + // Получение реквизитов табличной части + section.getAttributes().forEach(attribute -> { + System.out.println(" Реквизит ТЧ: " + attribute.getName() + + ", Тип: " + attribute.getType().getDescription()); + }); + }); +}); +``` + +### Работа с документами + +```java +// Получение всех документов +List documents = configuration.getDocuments(); + +documents.forEach(document -> { + System.out.println("Документ: " + document.getName()); + + // Получение реквизитов документа + document.getAttributes().forEach(attribute -> { + System.out.println(" Реквизит: " + attribute.getName()); + }); + + // Получение табличных частей + document.getTabularSections().forEach(section -> { + System.out.println(" Табличная часть: " + section.getName()); + }); + + // Получение регистраторов движений + document.getRegisterRecords().forEach(registerRecord -> { + System.out.println(" Регистратор: " + registerRecord.getName()); + }); +}); +``` + +### Работа с регистрами + +```java +// Работа с регистрами накопления +configuration.getAccumulationRegisters().forEach(register -> { + System.out.println("Регистр накопления: " + register.getName()); + System.out.println(" Вид регистра: " + register.getRegisterType()); + + // Получение измерений регистра + register.getDimensions().forEach(dimension -> { + System.out.println(" Измерение: " + dimension.getName()); + }); + + // Получение ресурсов регистра + register.getResources().forEach(resource -> { + System.out.println(" Ресурс: " + resource.getName()); + }); +}); + +// Работа с регистрами сведений +configuration.getInformationRegisters().forEach(register -> { + System.out.println("Регистр сведений: " + register.getName()); + System.out.println(" Периодичность: " + register.getPeriodicity()); + + // Получение измерений регистра + register.getDimensions().forEach(dimension -> { + System.out.println(" Измерение: " + dimension.getName()); + }); +}); +``` + +## Работа с формами + +### Получение и анализ форм + +```java +// Получение всех форм +List
allForms = configuration.getAllForms(); +System.out.println("Всего форм в конфигурации: " + allForms.size()); + +// Анализ конкретной формы +allForms.stream() + .filter(form -> "ФормаДокумента".equals(form.getName())) + .findFirst() + .ifPresent(form -> { + System.out.println("Анализ формы: " + form.getName()); + + if (form.getFormData() != null) { + // Получение элементов формы + FormItem rootItem = form.getFormData().getItems(); + analyzeFormItem(rootItem, 0); + } + }); + +// Рекурсивный метод для анализа элементов формы +private static void analyzeFormItem(FormItem item, int level) { + if (item == null) return; + + String indent = " ".repeat(level); + System.out.println(indent + "Элемент: " + item.getName() + ", Тип: " + item.getType()); + + // Обработка дочерних элементов + if (item.getChildItems() != null) { + item.getChildItems().forEach(child -> analyzeFormItem(child, level + 1)); + } +} +``` + +## Работа с модулями + +### Получение и анализ модулей + +```java +// Получение всех модулей +List allModules = configuration.getAllModules(); +System.out.println("Всего модулей в конфигурации: " + allModules.size()); + +// Группировка модулей по типу +Map> modulesByType = allModules.stream() + .collect(Collectors.groupingBy(Module::getModuleType)); + +// Вывод количества модулей каждого типа +modulesByType.forEach((type, modules) -> { + System.out.println("Модули типа " + type.getName() + ": " + modules.size()); +}); + +// Анализ содержимого конкретного модуля +allModules.stream() + .filter(module -> module.getModuleType() == ModuleType.ObjectModule) + .filter(module -> module.getOwner().getName().equals("ИмяОбъекта")) + .findFirst() + .ifPresent(module -> { + System.out.println("Содержимое модуля:"); + String[] lines = module.getContent().split("\n"); + for (int i = 0; i < Math.min(10, lines.length); i++) { + System.out.println((i+1) + ": " + lines[i]); + } + }); +``` + +## Поиск и фильтрация объектов + +### Поиск объекта по ссылке + +```java +// Создание ссылки на объект метаданных +MdoReference reference = MdoReference.create("Справочник.Товары"); + +// Поиск объекта по ссылке +Optional mdoOptional = configuration.findChild(reference); + +mdoOptional.ifPresentOrElse( + mdo -> System.out.println("Найден объект: " + mdo.getName()), + () -> System.out.println("Объект не найден") +); +``` + +### Фильтрация объектов по условию + +```java +// Найти все справочники с табличными частями +List catalogsWithTabularSections = configuration.getCatalogs().stream() + .filter(catalog -> !catalog.getTabularSections().isEmpty()) + .collect(Collectors.toList()); + +System.out.println("Справочники с табличными частями:"); +catalogsWithTabularSections.forEach(catalog -> { + System.out.println(catalog.getName() + " (" + catalog.getTabularSections().size() + " ТЧ)"); +}); + +// Найти все объекты с определенным префиксом имени +String prefix = "ПрефиксИмени"; +List objectsWithPrefix = configuration.getAllMdo().stream() + .filter(obj -> obj.getName().startsWith(prefix)) + .collect(Collectors.toList()); + +System.out.println("Объекты с префиксом '" + prefix + "':"); +objectsWithPrefix.forEach(obj -> { + System.out.println(obj.getClass().getSimpleName() + ": " + obj.getName()); +}); +``` + +## Практические сценарии + +### Построение диаграммы зависимостей объектов + +```java +// Упрощенный пример построения графа зависимостей между объектами +Map> dependencies = new HashMap<>(); + +// Сбор зависимостей из типов реквизитов справочников +configuration.getCatalogs().forEach(catalog -> { + String catalogKey = "Catalog." + catalog.getName(); + dependencies.putIfAbsent(catalogKey, new HashSet<>()); + + catalog.getAttributes().forEach(attribute -> { + if (attribute.getType() != null) { + String typeDescription = attribute.getType().getDescription(); + // Проверяем, что тип ссылается на другой объект метаданных + if (typeDescription != null && typeDescription.contains("CatalogRef.")) { + String referencedObject = typeDescription.replace("CatalogRef.", "Catalog."); + dependencies.get(catalogKey).add(referencedObject); + } + } + }); +}); + +// Вывод зависимостей +dependencies.forEach((object, refs) -> { + if (!refs.isEmpty()) { + System.out.println(object + " зависит от:"); + refs.forEach(ref -> System.out.println(" - " + ref)); + } +}); +``` + +### Анализ прав доступа + +```java +// Получение всех ролей +List roles = configuration.getRoles(); + +// Анализ прав доступа к объектам для каждой роли +roles.forEach(role -> { + System.out.println("Роль: " + role.getName()); + + if (role.getRights() != null) { + // Группировка прав по объектам + Map> rightsByObject = role.getRights().stream() + .collect(Collectors.groupingBy(Right::getName)); + + // ... existing code ... + } +}); +``` + +### Поиск неиспользуемых реквизитов + +```java +// Упрощенный пример поиска неиспользуемых реквизитов +// (в реальном сценарии нужен более сложный анализ кода модулей) + +// Сбор всех реквизитов справочников +Map> catalogAttributes = new HashMap<>(); + +configuration.getCatalogs().forEach(catalog -> { + String catalogName = catalog.getName(); + Set attributes = new HashSet<>(); + + catalog.getAttributes().forEach(attr -> { + attributes.add(attr.getName()); + }); + + catalogAttributes.put(catalogName, attributes); +}); + +// Простой анализ использования в модулях +catalogAttributes.forEach((catalogName, attributes) -> { + System.out.println("Проверка реквизитов справочника: " + catalogName); + + attributes.forEach(attrName -> { + boolean found = false; + + // Поиск использования реквизита в модулях + for (Module module : configuration.getAllModules()) { + if (module.getContent().contains(attrName)) { + found = true; + break; + } + } + + if (!found) { + System.out.println(" Потенциально неиспользуемый реквизит: " + attrName); + } + }); +}); +``` + +Эти примеры демонстрируют базовые возможности библиотеки MDClasses. В реальных сценариях вы можете комбинировать и расширять их для решения конкретных задач по анализу и обработке метаданных 1С. diff --git a/docs/ru/features.md b/docs/ru/features.md index 61f952337..d5774ca8e 100644 --- a/docs/ru/features.md +++ b/docs/ru/features.md @@ -4,19 +4,21 @@ ## Общее -Библиотека предоставляет возможность чтения описания объектов из каталога исходных файлов проектов 1С:Предприятие. Поддерживаются оба официальных формата +Библиотека предоставляет возможность чтения описания объектов из каталога исходных файлов проектов 1С:Предприятие. Поддерживаются оба официальных формата: + - формат выгрузки конфигуратора - формат проектов EDT ## Поддерживаемые типы контейнеров объектов метаданных -На данный момент библиотека предоставляет возможность чтения информации +На данный момент библиотека предоставляет возможность чтения информации: + - конфигураций - расширений конфигураций - внешних отчетов и обработок Эти объекты в контексте библиотеки являются некими "контейнерами метаданных", т.е. для чтения необходимо указывать расположение именно корневых объектов, а не файлов объектов метаданных, форм и т.д. -Реализация объектов-контейнеров метаданных располагается в пакете [mdclasses](com.github._1c_syntax.bsl.mdclasses), там же расположена фабрика для создания объекта из каталога файлов. +Реализация объектов-контейнеров метаданных располагается в пакете [mdclasses](com.github._1c_syntax.bsl.mdclasses), там же расположена фабрика для создания объекта из каталога файлов. ## Поддерживаемые метаданные @@ -24,6 +26,7 @@ Актуальное содержимое того или иного вида объекта метаданных можно всегда находится в классе его реализации в пакете [mdo](com.github._1c_syntax.bsl.mdo). Немного о структуре пакета: + - в корне расположены классы видов объектов метаданных (Справочники, Документы, Перечисления и т.д.), базовые интерфейсы - в пакете `children` находятся классы с дочерними (несамостоятельными) объектами (формы, макеты, модули т.д.) - в пакете `storage` расположены хранилища вспомогательной информации (содержимое макетов, XDTO-схем и т.д.) diff --git a/docs/ru/index.md b/docs/ru/index.md index 8474caff7..a5921b339 100644 --- a/docs/ru/index.md +++ b/docs/ru/index.md @@ -1,9 +1,84 @@ # MDClasses -*В разработке* +## Обзор -## Полезная информация +MDClasses - это библиотека на Java для чтения и анализа метаданных 1С:Предприятие 8. Библиотека позволяет работать с конфигурациями, выгруженными в XML-формате (через конфигуратор или средствами сравнения/объединения конфигураций) или в формате EDT. -- [Примеры использования](examples.md) -- [Системные требования](systemRequirements.md) -- [Возможности](features.md) +## Основные возможности + +* Чтение конфигурации из формата XML и EDT +* Доступ к объектам метаданных через программный интерфейс +* Анализ структуры метаданных: справочники, документы, регистры и т.д. +* Работа с модулями 1С +* Анализ форм и их элементов +* Доступ к правам и ролям +* Построение зависимостей между объектами + +## Начало работы + +### Подключение библиотеки + +#### Maven + +```xml + + io.github.1c-syntax + mdclasses + версия_библиотеки + +``` + +#### Gradle + +```groovy +dependencies { + implementation 'io.github.1c-syntax:mdclasses:версия_библиотеки' +} +``` + +### Простой пример использования + +```java +import com.github._1c_syntax.bsl.mdclasses.MDClasses; +import com.github._1c_syntax.bsl.mdo.Configuration; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class Example { + public static void main(String[] args) { + // Путь к каталогу конфигурации + Path configurationPath = Paths.get("path/to/configuration"); + + // Чтение конфигурации + Configuration configuration = (Configuration) MDClasses.createConfiguration(configurationPath); + + // Вывод информации о конфигурации + System.out.println("Имя конфигурации: " + configuration.getName()); + System.out.println("Количество справочников: " + configuration.getCatalogs().size()); + } +} +``` + +## Структура документации + +* [README](../README.md) - общая информация о проекте +* [Требования к системе](systemRequirements.md) - требования к системе для использования библиотеки +* [Возможности](features.md) - описание возможностей библиотеки +* [Примеры использования](examples.md) - подробные примеры с кодом + +## Ограничения + +* Библиотека предназначена только для чтения метаданных, она не позволяет изменять конфигурацию +* Некоторые специфические возможности 1С могут быть не поддержаны в текущей версии + +## Сценарии использования + +MDClasses может использоваться для различных задач, связанных с анализом конфигураций 1С: + +* Статический анализ кода 1С +* Построение диаграмм зависимостей объектов метаданных +* Автоматизированное документирование конфигураций +* Миграция данных между различными конфигурациями +* Аудит безопасности конфигураций 1С +* Анализ производительности конфигураций +* Интеграция с другими инструментами разработки