Skip to content

Commit 72b0356

Browse files
committed
Finish v0.16.0
2 parents a1281ac + aee04ef commit 72b0356

1,078 files changed

Lines changed: 160650 additions & 10756 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.coderabbit.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
reviews:
2+
path_filters:
3+
- "!src/test/resources/**"

.github/workflows/gh-pages.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
run: ./gradlew --no-daemon javadoc
3232

3333
- name: Set up Python
34-
uses: actions/setup-python@v5.6.0
34+
uses: actions/setup-python@v6.0.0
3535
with:
3636
python-version: '3.10'
3737
architecture: 'x64'

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ Gradle_*.xml
1919
*.cf
2020
**/ConfigDumpInfo.xml
2121
**/.metadata/
22+
benchmark-results/**

benchmark-analyze-results.py

Lines changed: 387 additions & 0 deletions
Large diffs are not rendered by default.

benchmark-compare.sh

Lines changed: 410 additions & 0 deletions
Large diffs are not rendered by default.

build.gradle.kts

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ plugins {
77
jacoco
88
id("org.cadixdev.licenser") version "0.6.1"
99
id("me.qoomon.git-versioning") version "6.4.4"
10-
id("io.freefair.lombok") version "8.14.2"
11-
id("io.freefair.javadoc-links") version "8.14.2"
12-
id("io.freefair.javadoc-utf-8") version "8.14.2"
13-
id("io.freefair.maven-central.validate-poms") version "8.14.2"
14-
id("com.github.ben-manes.versions") version "0.52.0"
10+
id("io.freefair.lombok") version "9.0.0"
11+
id("io.freefair.javadoc-links") version "9.0.0"
12+
id("io.freefair.javadoc-utf-8") version "9.0.0"
13+
id("io.freefair.maven-central.validate-poms") version "9.0.0"
14+
id("com.github.ben-manes.versions") version "0.53.0"
1515
id("ru.vyarus.pom") version "3.0.0"
16-
id("org.jreleaser") version "1.19.0"
17-
id("org.sonarqube") version "6.2.0.5505"
16+
id("org.jreleaser") version "1.20.0"
17+
id("org.sonarqube") version "7.0.0.6105"
18+
id("me.champeau.jmh") version "0.7.3"
1819
}
1920

2021
group = "io.github.1c-syntax"
@@ -44,6 +45,7 @@ gitVersioning.apply {
4445
repositories {
4546
mavenLocal()
4647
mavenCentral()
48+
maven("https://central.sonatype.com/repository/maven-snapshots")
4749
}
4850

4951
dependencies {
@@ -57,9 +59,11 @@ dependencies {
5759

5860
// прочее
5961
implementation("commons-io", "commons-io", "2.18.0")
60-
implementation("io.github.1c-syntax", "utils", "0.6.3")
61-
implementation("io.github.1c-syntax", "bsl-common-library", "0.8.1")
62-
implementation("io.github.1c-syntax", "supportconf", "0.14.3")
62+
implementation("io.github.1c-syntax", "bsl-common-library", "0.9.0")
63+
implementation("io.github.1c-syntax", "utils", "0.6.4")
64+
implementation("io.github.1c-syntax", "supportconf", "0.15.0") {
65+
exclude("io.github.1c-syntax", "bsl-common-library")
66+
}
6367

6468
// быстрый поиск классов
6569
implementation("io.github.classgraph", "classgraph", "4.8.179")
@@ -75,6 +79,10 @@ dependencies {
7579

7680
// логирование
7781
testImplementation("org.slf4j", "slf4j-reload4j", "2.1.0-alpha1")
82+
83+
// бенчмарк
84+
jmh("org.openjdk.jmh:jmh-core:1.37")
85+
jmhAnnotationProcessor("org.openjdk.jmh:jmh-generator-annprocess:1.37")
7886
}
7987

8088
java {
@@ -92,6 +100,14 @@ sourceSets {
92100
}
93101
}
94102

103+
jmh {
104+
warmupIterations = 3
105+
iterations = 5
106+
fork = 2
107+
resultFormat = "JSON"
108+
resultsFile = file("build/jmh-results.json")
109+
}
110+
95111
tasks.test {
96112
useJUnitPlatform()
97113
testLogging {
@@ -138,7 +154,10 @@ sonar {
138154
property("sonar.projectKey", "1c-syntax_mdclasses")
139155
property("sonar.projectName", "MDClasses")
140156
property("sonar.exclusions", "**/resources/**/*.*")
141-
property("sonar.coverage.jacoco.xmlReportPaths", "${layout.buildDirectory.get()}/reports/jacoco/test/jacoco.xml")
157+
property(
158+
"sonar.coverage.jacoco.xmlReportPaths",
159+
"${layout.buildDirectory.get()}/reports/jacoco/test/jacoco.xml"
160+
)
142161
}
143162
}
144163

docs/ru/examples.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- [Работа с метаданными](#работа-с-метаданными)
1010
- [Работа с формами](#работа-с-формами)
1111
- [Работа с модулями](#работа-с-модулями)
12+
- [Анализ типов данных](#анализ-типов-данных)
1213
- [Поиск и фильтрация объектов](#поиск-и-фильтрация-объектов)
1314
- [Практические сценарии](#практические-сценарии)
1415

@@ -269,6 +270,139 @@ allModules.stream()
269270
});
270271
```
271272

273+
## Анализ типов данных
274+
275+
При чтении описания метаданных для объектов и их атрибутов вычисляются описания типов. Все сущности, имеющие описания типов данных, реализуют интерфейс `ValueTypeOwner`.
276+
277+
Ниже приведены примеры, как можно использовать данную информацию.
278+
279+
### Получение описания типа реквизита справочника
280+
281+
Часть описания реквизита справочника
282+
283+
```xml
284+
<attributes uuid="dff5b5d8-762d-4490-a336-dcc8d93c17d5">
285+
<name>Реквизит2</name>
286+
<type>
287+
<types>Number</types>
288+
<numberQualifiers>
289+
<precision>10</precision>
290+
</numberQualifiers>
291+
</type>
292+
<minValue xsi:type="core:UndefinedValue"/>
293+
<maxValue xsi:type="core:UndefinedValue"/>
294+
<fillValue xsi:type="core:UndefinedValue"/>
295+
<fullTextSearch>Use</fullTextSearch>
296+
</attributes>
297+
```
298+
299+
Код, которым можно посмотреть описание типа
300+
301+
```java
302+
// найдем справочник из прочитанной конфигурации
303+
var childMDO = configuration.findChild("Catalog.Справочник1");
304+
305+
// проверим, что это на самом деле справочник
306+
if (childMDO.isPresent() && childMDO.get() instanceof Catalog catalog) {
307+
308+
// убедимся, что у справочника есть дочерние
309+
assertThat(catalog.getChildren()).isNotEmpty();
310+
311+
// найдем нужный дочерний (реквизит)
312+
var childAttribute = catalog.findChild(md -> "Реквизит2".equals(md.getName()));
313+
314+
// проверим, что он есть и нужного типа
315+
if (childAttribute.isPresent() && childAttribute.get() instanceof ObjectAttribute objectAttribute) {
316+
317+
// проверим наименование
318+
assertThat(objectAttribute.getName()).isEqualTo("Реквизит2");
319+
320+
// описание типа доступно через getValueType()
321+
assertThat(objectAttribute.getValueType()).isNotNull();
322+
// убедимся в наличии примитивного типа СТРОКА в составе описания
323+
assertThat(objectAttribute.getValueType().contains(PrimitiveValueType.NUMBER)).isTrue();
324+
// убедимся, что тип не составной
325+
assertThat(objectAttribute.getValueType().isComposite()).isFalse();
326+
// убедимся, что квалификаторы прочитаны
327+
assertThat(objectAttribute.getValueType().getQualifiers()).hasSize(1);
328+
329+
// убедимся, что прочитан квалификатор числа
330+
var qualifier = objectAttribute.getValueType().getQualifiers().get(0);
331+
assertThat(qualifier).isInstanceOf(NumberQualifiers.class);
332+
333+
// убедимся, что квалификатор числа содежржит верную информацию
334+
var numberQualifiers = (NumberQualifiers) qualifier;
335+
assertThat(numberQualifiers.getPrecision()).isEqualTo(10); // длина 10
336+
assertThat(numberQualifiers.getScale()).isEqualTo(0); // точность 0
337+
assertThat(numberQualifiers.isNonNegative()).isFalse(); // возможны любые знаки
338+
}
339+
}
340+
}
341+
```
342+
343+
### Определение состава определяемого типа
344+
345+
Часть описания определяемого типа
346+
347+
```xml
348+
<name>ЗначениеДоступа</name>
349+
<type>
350+
<types>CatalogRef.ПапкиФайлов</types>
351+
<types>CatalogRef.ВнешниеПользователи</types>
352+
<types>CatalogRef.КлючиДоступа</types>
353+
<types>CatalogRef.ИдентификаторыОбъектовРасширений</types>
354+
<types>CatalogRef.ГруппыВнешнихПользователей</types>
355+
<types>CatalogRef.ГруппыПользователей</types>
356+
<types>EnumRef.ДополнительныеЗначенияДоступа</types>
357+
<types>ChartOfCharacteristicTypesRef.ДополнительныеРеквизитыИСведения</types>
358+
<types>CatalogRef.ДополнительныеОтчетыИОбработки</types>
359+
<types>CatalogRef.Пользователи</types>
360+
<types>CatalogRef.ГруппыИсполнителейЗадач</types>
361+
<types>CatalogRef.УчетныеЗаписиЭлектроннойПочты</types>
362+
<types>CatalogRef.ИдентификаторыОбъектовМетаданных</types>
363+
</type>
364+
```
365+
366+
Код, которым можно посмотреть описание типа
367+
368+
```java
369+
370+
// найдем определяемый тип прочитанной конфигурации
371+
var childMDO = configuration.findChild("DefinedType.ЗначениеДоступа");
372+
if (childMDO.isPresent() && childMDO.get() instanceof DefinedType definedType) {
373+
assertThat(definedType.getName()).isEqualTo("ЗначениеДоступа");
374+
// убедимся, что тип прочитан
375+
assertThat(definedType.getValueType()).isNotNull();
376+
// убедимся, что в составе нет ЧИСЛА
377+
assertThat(definedType.getValueType().contains(PrimitiveValueType.NUMBER)).isFalse();
378+
// убедимся, что описание соответствует составному типу
379+
assertThat(definedType.getValueType().isComposite()).isTrue();
380+
// квалификаторов нет
381+
assertThat(definedType.getValueType().getQualifiers()).isEmpty();
382+
383+
// создадим тип по имени
384+
var typeContains = MetadataValueType.fromString("EnumRef.ДополнительныеЗначенияДоступа");
385+
386+
assertThat(typeContains).isNotNull();
387+
// полученный тип относится к перечислению
388+
assertThat(typeContains.getKind()).isEqualTo(MDOType.ENUM);
389+
// тип не составной
390+
assertThat(typeContains.isComposite()).isFalse();
391+
// есть имя на английском
392+
assertThat(typeContains.getName()).isEqualTo("EnumRef.ДополнительныеЗначенияДоступа");
393+
// и русском
394+
assertThat(typeContains.getNameRu()).isEqualTo("ПеречислениеСсылка.ДополнительныеЗначенияДоступа");
395+
396+
// второй тип
397+
var typeNotContains = MetadataValueType.fromString("CatalogRef.Контрагенты");
398+
assertThat(typeNotContains).isNotNull();
399+
// убедимся, что первый тип входит в состав описания
400+
assertThat(definedType.getValueType().contains(typeContains)).isTrue();
401+
// убедимся, что второй тип не входит в состав
402+
assertThat(definedType.getValueType().contains(typeNotContains)).isFalse();
403+
}
404+
```
405+
272406
## Поиск и фильтрация объектов
273407

274408
### Поиск объекта по ссылке

docs/ru/features.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
## Поддерживаемые метаданные
2424

25-
На данный момент поддерживается загрузка всех видов метаданных, существующих в версиях платформы 1С до 8.3.24. В заивисимости от типа объекта и потребностей, объем читаемой информации может различаться (реализация чтения дополнительной информации выполняется от задач).
25+
На данный момент поддерживается загрузка всех видов метаданных, существующих в версиях платформы 1С до 8.5. В зависимости от типа объекта и потребностей, объем читаемой информации может различаться (реализация чтения дополнительной информации выполняется от задач).
2626
Актуальное содержимое того или иного вида объекта метаданных можно всегда находится в классе его реализации в пакете [mdo](com.github._1c_syntax.bsl.mdo).
2727

2828
Немного о структуре пакета:
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* This file is a part of MDClasses.
3+
*
4+
* Copyright (c) 2019 - 2025
5+
* Tymko Oleg <olegtymko@yandex.ru>, Maximov Valery <maximovvalery@gmail.com> and contributors
6+
*
7+
* SPDX-License-Identifier: LGPL-3.0-or-later
8+
*
9+
* MDClasses is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 3.0 of the License, or (at your option) any later version.
13+
*
14+
* MDClasses is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public
20+
* License along with MDClasses.
21+
*/
22+
package com.github._1c_syntax.bsl.mdclasses.benchmark;
23+
24+
import com.github._1c_syntax.bsl.mdclasses.MDCReadSettings;
25+
import com.github._1c_syntax.bsl.mdclasses.MDClasses;
26+
import org.openjdk.jmh.annotations.Benchmark;
27+
import org.openjdk.jmh.annotations.BenchmarkMode;
28+
import org.openjdk.jmh.annotations.Fork;
29+
import org.openjdk.jmh.annotations.Measurement;
30+
import org.openjdk.jmh.annotations.Mode;
31+
import org.openjdk.jmh.annotations.OutputTimeUnit;
32+
import org.openjdk.jmh.annotations.Scope;
33+
import org.openjdk.jmh.annotations.Setup;
34+
import org.openjdk.jmh.annotations.State;
35+
import org.openjdk.jmh.annotations.Warmup;
36+
import org.openjdk.jmh.infra.Blackhole;
37+
38+
import java.nio.file.Path;
39+
import java.util.concurrent.TimeUnit;
40+
41+
@BenchmarkMode(Mode.AverageTime)
42+
@OutputTimeUnit(TimeUnit.MILLISECONDS)
43+
@State(Scope.Thread)
44+
@Warmup(iterations = 3, time = 2)
45+
@Measurement(iterations = 5, time = 3)
46+
@Fork(2)
47+
public class MDClassesBenchmark {
48+
49+
private final Path configPathEDT = Path.of("src/test/resources/ext/edt/ssl_3_1/configuration");
50+
private final Path configPathDesigner = Path.of("src/test/resources/ext/designer/ssl_3_1/src/cf");
51+
private static final MDCReadSettings SKIP_ALL = MDCReadSettings.builder()
52+
.skipSupport(true)
53+
.skipRoleData(true)
54+
.skipFormElementItems(true)
55+
.skipXdtoPackage(true)
56+
.skipDataCompositionSchema(true)
57+
.build();
58+
59+
@Setup
60+
public void setup() {
61+
// Предварительная загрузка для разогрева
62+
MDClasses.createConfiguration(configPathEDT);
63+
MDClasses.createConfiguration(configPathDesigner);
64+
}
65+
66+
@Benchmark
67+
public void test_EDT_CreateConfiguration_SkipSupport_False(Blackhole blackhole) {
68+
var model = MDClasses.createConfiguration(configPathEDT);
69+
blackhole.consume(model);
70+
}
71+
72+
@Benchmark
73+
public void test_EDT_CreateConfiguration_SkipSupport_True(Blackhole blackhole) {
74+
var model = MDClasses.createConfiguration(configPathEDT, SKIP_ALL);
75+
blackhole.consume(model);
76+
}
77+
78+
@Benchmark
79+
public void test_Designer_CreateConfiguration_SkipSupport_False(Blackhole blackhole) {
80+
var model = MDClasses.createConfiguration(configPathDesigner);
81+
blackhole.consume(model);
82+
}
83+
84+
@Benchmark
85+
public void test_Designer_CreateConfiguration_SkipSupport_True(Blackhole blackhole) {
86+
var model = MDClasses.createConfiguration(configPathDesigner, SKIP_ALL);
87+
blackhole.consume(model);
88+
}
89+
}

0 commit comments

Comments
 (0)