structurize 2.18.1__tar.gz → 2.19.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {structurize-2.18.1/structurize.egg-info → structurize-2.19.0}/PKG-INFO +1 -1
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/_version.py +3 -3
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotocsharp.py +21 -2
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotojava.py +90 -36
- structurize-2.19.0/avrotize/cddltostructure.py +1841 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/commands.json +226 -0
- structurize-2.19.0/avrotize/constants.py +72 -0
- structurize-2.19.0/avrotize/dependencies/cpp/vcpkg/vcpkg.json +19 -0
- structurize-2.19.0/avrotize/dependencies/typescript/node22/package.json +16 -0
- structurize-2.19.0/avrotize/dependency_version.py +432 -0
- structurize-2.19.0/avrotize/structuretocddl.py +597 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretocsharp.py +311 -21
- structurize-2.19.0/avrotize/structuretojava.py +853 -0
- {structurize-2.18.1 → structurize-2.19.0/structurize.egg-info}/PKG-INFO +1 -1
- {structurize-2.18.1 → structurize-2.19.0}/structurize.egg-info/SOURCES.txt +24 -0
- structurize-2.18.1/avrotize/constants.py +0 -5
- {structurize-2.18.1 → structurize-2.19.0}/.gitignore +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/LICENSE +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/MANIFEST.in +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/README.md +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/__init__.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/__main__.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/asn1toavro.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotize.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotocpp.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotocsv.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotodatapackage.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotodb.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotogo.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotographql.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotoiceberg.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotojs.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotojsons.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotojstruct.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotokusto.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotomd.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotools.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotoparquet.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotoproto.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotopython.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotorust.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotots.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/avrotoxsd.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/common.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/csvtoavro.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/datapackagetoavro.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/dependency_resolver.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/jsonstoavro.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/jsonstostructure.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/jstructtoavro.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/kstructtoavro.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/kustotoavro.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/parquettoavro.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/proto2parser.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/proto3parser.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/prototoavro.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretocpp.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretocsv.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretodatapackage.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretodb.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretogo.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretographql.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretoiceberg.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretojsons.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretokusto.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretomd.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretoproto.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretopython.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretorust.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretots.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/structuretoxsd.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/avrotize/xsdtoavro.py +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/build.ps1 +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/build.sh +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/pyproject.toml +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/setup.cfg +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/structurize.egg-info/dependency_links.txt +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/structurize.egg-info/entry_points.txt +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/structurize.egg-info/requires.txt +0 -0
- {structurize-2.18.1 → structurize-2.19.0}/structurize.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: structurize
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.19.0
|
|
4
4
|
Summary: Tools to convert from and to JSON Structure from various other schema languages.
|
|
5
5
|
Author-email: Clemens Vasters <clemensv@microsoft.com>
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '2.
|
|
32
|
-
__version_tuple__ = version_tuple = (2,
|
|
31
|
+
__version__ = version = '2.19.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 19, 0)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'geec8f9840'
|
|
@@ -9,6 +9,15 @@ from typing import Any, Dict, List, Tuple, Union, cast
|
|
|
9
9
|
import uuid
|
|
10
10
|
|
|
11
11
|
from avrotize.common import build_flat_type_dict, inline_avro_references, is_generic_avro_type, pascal, process_template
|
|
12
|
+
from avrotize.constants import (
|
|
13
|
+
CSHARP_AVRO_VERSION,
|
|
14
|
+
NEWTONSOFT_JSON_VERSION,
|
|
15
|
+
SYSTEM_TEXT_JSON_VERSION,
|
|
16
|
+
SYSTEM_MEMORY_DATA_VERSION,
|
|
17
|
+
NUNIT_VERSION,
|
|
18
|
+
NUNIT_ADAPTER_VERSION,
|
|
19
|
+
MSTEST_SDK_VERSION,
|
|
20
|
+
)
|
|
12
21
|
import glob
|
|
13
22
|
|
|
14
23
|
JsonNode = Dict[str, 'JsonNode'] | List['JsonNode'] | str | None
|
|
@@ -957,7 +966,14 @@ class AvroToCSharp:
|
|
|
957
966
|
avro_annotation=self.avro_annotation,
|
|
958
967
|
system_xml_annotation=self.system_xml_annotation,
|
|
959
968
|
system_text_json_annotation=self.system_text_json_annotation,
|
|
960
|
-
newtonsoft_json_annotation=self.newtonsoft_json_annotation
|
|
969
|
+
newtonsoft_json_annotation=self.newtonsoft_json_annotation,
|
|
970
|
+
CSHARP_AVRO_VERSION=CSHARP_AVRO_VERSION,
|
|
971
|
+
NEWTONSOFT_JSON_VERSION=NEWTONSOFT_JSON_VERSION,
|
|
972
|
+
SYSTEM_TEXT_JSON_VERSION=SYSTEM_TEXT_JSON_VERSION,
|
|
973
|
+
SYSTEM_MEMORY_DATA_VERSION=SYSTEM_MEMORY_DATA_VERSION,
|
|
974
|
+
NUNIT_VERSION=NUNIT_VERSION,
|
|
975
|
+
NUNIT_ADAPTER_VERSION=NUNIT_ADAPTER_VERSION,
|
|
976
|
+
MSTEST_SDK_VERSION=MSTEST_SDK_VERSION))
|
|
961
977
|
if not glob.glob(os.path.join(output_dir, "test", "*.csproj")):
|
|
962
978
|
csproj_test_file = os.path.join(
|
|
963
979
|
output_dir, "test", f"{pascal(project_name)}.Test.csproj")
|
|
@@ -971,7 +987,10 @@ class AvroToCSharp:
|
|
|
971
987
|
avro_annotation=self.avro_annotation,
|
|
972
988
|
system_xml_annotation=self.system_xml_annotation,
|
|
973
989
|
system_text_json_annotation=self.system_text_json_annotation,
|
|
974
|
-
newtonsoft_json_annotation=self.newtonsoft_json_annotation
|
|
990
|
+
newtonsoft_json_annotation=self.newtonsoft_json_annotation,
|
|
991
|
+
NUNIT_VERSION=NUNIT_VERSION,
|
|
992
|
+
NUNIT_ADAPTER_VERSION=NUNIT_ADAPTER_VERSION,
|
|
993
|
+
MSTEST_SDK_VERSION=MSTEST_SDK_VERSION))
|
|
975
994
|
|
|
976
995
|
self.output_dir = output_dir
|
|
977
996
|
for avro_schema in (avs for avs in schema if isinstance(avs, dict)):
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
import json
|
|
5
5
|
import os
|
|
6
6
|
from typing import Dict, List, Tuple, Union
|
|
7
|
-
from avrotize.constants import AVRO_VERSION, JACKSON_VERSION, JDK_VERSION
|
|
7
|
+
from avrotize.constants import (AVRO_VERSION, JACKSON_VERSION, JDK_VERSION,
|
|
8
|
+
JUNIT_VERSION, MAVEN_COMPILER_VERSION, MAVEN_SUREFIRE_VERSION)
|
|
8
9
|
|
|
9
10
|
from avrotize.common import pascal, camel, is_generic_avro_type, inline_avro_references, build_flat_type_dict
|
|
10
11
|
|
|
@@ -46,13 +47,13 @@ POM_CONTENT = """<?xml version="1.0" encoding="UTF-8"?>
|
|
|
46
47
|
<dependency>
|
|
47
48
|
<groupId>org.junit.jupiter</groupId>
|
|
48
49
|
<artifactId>junit-jupiter-api</artifactId>
|
|
49
|
-
<version>
|
|
50
|
+
<version>{JUNIT_VERSION}</version>
|
|
50
51
|
<scope>test</scope>
|
|
51
52
|
</dependency>
|
|
52
53
|
<dependency>
|
|
53
54
|
<groupId>org.junit.jupiter</groupId>
|
|
54
55
|
<artifactId>junit-jupiter-engine</artifactId>
|
|
55
|
-
<version>
|
|
56
|
+
<version>{JUNIT_VERSION}</version>
|
|
56
57
|
<scope>test</scope>
|
|
57
58
|
</dependency>
|
|
58
59
|
</dependencies>
|
|
@@ -61,7 +62,7 @@ POM_CONTENT = """<?xml version="1.0" encoding="UTF-8"?>
|
|
|
61
62
|
<plugin>
|
|
62
63
|
<groupId>org.apache.maven.plugins</groupId>
|
|
63
64
|
<artifactId>maven-compiler-plugin</artifactId>
|
|
64
|
-
<version>
|
|
65
|
+
<version>{MAVEN_COMPILER_VERSION}</version>
|
|
65
66
|
<configuration>
|
|
66
67
|
<compilerArgs>
|
|
67
68
|
<arg>-Xmaxerrs</arg>
|
|
@@ -72,7 +73,7 @@ POM_CONTENT = """<?xml version="1.0" encoding="UTF-8"?>
|
|
|
72
73
|
<plugin>
|
|
73
74
|
<groupId>org.apache.maven.plugins</groupId>
|
|
74
75
|
<artifactId>maven-surefire-plugin</artifactId>
|
|
75
|
-
<version>
|
|
76
|
+
<version>{MAVEN_SUREFIRE_VERSION}</version>
|
|
76
77
|
<configuration>
|
|
77
78
|
<useSystemClassLoader>false</useSystemClassLoader>
|
|
78
79
|
</configuration>
|
|
@@ -693,7 +694,8 @@ class AvroToJava:
|
|
|
693
694
|
elif items_type in self.generated_types_java_package:
|
|
694
695
|
kind = self.generated_types_java_package[items_type]
|
|
695
696
|
if kind == "enum":
|
|
696
|
-
|
|
697
|
+
# Try to match the incoming text against Avro symbols
|
|
698
|
+
pred += f"n.elements().next().isTextual() && java.util.Arrays.stream({items_type}.values()).anyMatch(e -> e.avroSymbol().equals(n.elements().next().asText()))"
|
|
697
699
|
else:
|
|
698
700
|
pred += f"{items_type}.isJsonMatch(n.elements().next())"
|
|
699
701
|
else:
|
|
@@ -710,7 +712,8 @@ class AvroToJava:
|
|
|
710
712
|
elif values_type in self.generated_types_java_package:
|
|
711
713
|
kind = self.generated_types_java_package[values_type]
|
|
712
714
|
if kind == "enum":
|
|
713
|
-
|
|
715
|
+
# Try to match the incoming text against Avro symbols
|
|
716
|
+
pred += f"n.elements().next().isTextual() && java.util.Arrays.stream({values_type}.values()).anyMatch(e -> e.avroSymbol().equals(n.elements().next().asText()))"
|
|
714
717
|
else:
|
|
715
718
|
pred += f"{values_type}.isJsonMatch(n.elements().next())"
|
|
716
719
|
else:
|
|
@@ -730,7 +733,8 @@ class AvroToJava:
|
|
|
730
733
|
raw_const = const_value if isinstance(const_value, str) else str(const_value)
|
|
731
734
|
class_definition += f"(node.has(\"{field_name_js}\") && node.get(\"{field_name_js}\").isTextual() && node.get(\"{field_name_js}\").asText().equals(\"{raw_const}\"))"
|
|
732
735
|
else:
|
|
733
|
-
|
|
736
|
+
# Try to match the incoming text against Avro symbols
|
|
737
|
+
class_definition += f"(node.get(\"{field_name_js}\").isTextual() && java.util.Arrays.stream({field_type.type_name}.values()).anyMatch(e -> e.avroSymbol().equals(node.get(\"{field_name_js}\").asText())))"
|
|
734
738
|
else:
|
|
735
739
|
is_union = False
|
|
736
740
|
field_union = pascal(field_name) + 'Union'
|
|
@@ -802,7 +806,8 @@ class AvroToJava:
|
|
|
802
806
|
elif field_type.is_class:
|
|
803
807
|
class_definition += f"({null_check} || {field_type.type_name}.isJsonMatch({element_name}))"
|
|
804
808
|
elif field_type.is_enum:
|
|
805
|
-
|
|
809
|
+
# Try to match the incoming text against Avro symbols
|
|
810
|
+
class_definition += f"({null_check} || ({node_check}.isTextual() && java.util.Arrays.stream({field_type.type_name}.values()).anyMatch(e -> e.avroSymbol().equals({element_name}.asText()))))"
|
|
806
811
|
else:
|
|
807
812
|
is_union = False
|
|
808
813
|
field_union = pascal(element_name) + 'Union'
|
|
@@ -1022,8 +1027,8 @@ class AvroToJava:
|
|
|
1022
1027
|
get_method += f"{INDENT * 3}case {index}: return this.{field_name} != null ? this.{field_name}.entrySet().stream().collect(java.util.stream.Collectors.toMap(java.util.Map.Entry::getKey, e -> e.getValue() != null ? e.getValue().toObject() : null)) : null;\n"
|
|
1023
1028
|
elif field_type.is_enum:
|
|
1024
1029
|
# For enum fields, convert to GenericEnumSymbol for Avro serialization
|
|
1025
|
-
#
|
|
1026
|
-
get_method += f"{INDENT * 3}case {index}: return this.{field_name} != null ? new GenericData.EnumSymbol({field_type.type_name}.SCHEMA, this.{field_name}.
|
|
1030
|
+
# Use avroSymbol() to get the original Avro symbol name for serialization
|
|
1031
|
+
get_method += f"{INDENT * 3}case {index}: return this.{field_name} != null ? new GenericData.EnumSymbol({field_type.type_name}.SCHEMA, this.{field_name}.avroSymbol()) : null;\n"
|
|
1027
1032
|
else:
|
|
1028
1033
|
# For all other field types, return the field as-is
|
|
1029
1034
|
# Avro's SpecificDatumWriter will handle serialization internally
|
|
@@ -1104,7 +1109,8 @@ class AvroToJava:
|
|
|
1104
1109
|
put_method += f"{INDENT * 3}case {index}: this.{field_name} = value$ instanceof GenericData.Record ? new {field_type.type_name}((GenericData.Record)value$) : ({field_type.type_name})value$; break;\n"
|
|
1105
1110
|
elif type_kind == "enum":
|
|
1106
1111
|
# Enums need to be converted from GenericData.EnumSymbol
|
|
1107
|
-
|
|
1112
|
+
# Use fromAvroSymbol to match original Avro symbol names
|
|
1113
|
+
put_method += f"{INDENT * 3}case {index}: this.{field_name} = value$ instanceof GenericData.EnumSymbol ? {field_type.type_name}.fromAvroSymbol(value$.toString()) : ({field_type.type_name})value$; break;\n"
|
|
1108
1114
|
else:
|
|
1109
1115
|
# Check if this is a List<RecordType> or Map<String,RecordType>
|
|
1110
1116
|
is_list_of_records = False
|
|
@@ -1164,10 +1170,11 @@ class AvroToJava:
|
|
|
1164
1170
|
# Check if it's a List of enums
|
|
1165
1171
|
if element_type in self.generated_types_java_package and self.generated_types_java_package[element_type] == "enum":
|
|
1166
1172
|
# For List<Enum>, convert GenericEnumSymbol to actual enum values
|
|
1173
|
+
# Use fromAvroSymbol to match original Avro symbol names
|
|
1167
1174
|
put_method += f"{INDENT * 3}case {index}: {{\n"
|
|
1168
1175
|
put_method += f"{INDENT * 4}if (value$ instanceof List<?>) {{\n"
|
|
1169
1176
|
put_method += f"{INDENT * 5}List<?> list = (List<?>)value$;\n"
|
|
1170
|
-
put_method += f"{INDENT * 5}this.{field_name} = list.stream().map(item -> item instanceof GenericData.EnumSymbol ? {element_type}.
|
|
1177
|
+
put_method += f"{INDENT * 5}this.{field_name} = list.stream().map(item -> item instanceof GenericData.EnumSymbol ? {element_type}.fromAvroSymbol(item.toString()) : ({element_type})item).collect(java.util.stream.Collectors.toList());\n"
|
|
1171
1178
|
put_method += f"{INDENT * 4}}} else {{\n"
|
|
1172
1179
|
put_method += f"{INDENT * 5}this.{field_name} = null;\n"
|
|
1173
1180
|
put_method += f"{INDENT * 4}}}\n"
|
|
@@ -1211,20 +1218,44 @@ class AvroToJava:
|
|
|
1211
1218
|
self.generated_types_java_package[type_name] = "enum"
|
|
1212
1219
|
self.generated_avro_schemas[type_name] = avro_schema
|
|
1213
1220
|
symbols = avro_schema.get('symbols', [])
|
|
1214
|
-
# Convert symbols to valid Java identifiers
|
|
1221
|
+
# Convert symbols to valid Java identifiers in SCREAMING_CASE (uppercase)
|
|
1215
1222
|
# Replace invalid chars, prepend _ if starts with digit or is a reserved word
|
|
1223
|
+
# Keep track of mapping from Java symbol to original Avro symbol for serialization
|
|
1216
1224
|
java_symbols = []
|
|
1225
|
+
symbol_pairs = [] # (java_symbol, avro_symbol) pairs
|
|
1217
1226
|
for symbol in symbols:
|
|
1218
|
-
java_symbol = symbol.replace('-', '_').replace('.', '_')
|
|
1227
|
+
java_symbol = symbol.replace('-', '_').replace('.', '_').upper()
|
|
1219
1228
|
if java_symbol and java_symbol[0].isdigit():
|
|
1220
1229
|
java_symbol = '_' + java_symbol
|
|
1221
1230
|
# Check if the symbol is a Java reserved word and prefix with underscore
|
|
1222
|
-
if is_java_reserved_word(java_symbol):
|
|
1231
|
+
if is_java_reserved_word(java_symbol.lower()):
|
|
1223
1232
|
java_symbol = '_' + java_symbol
|
|
1224
1233
|
java_symbols.append(java_symbol)
|
|
1225
|
-
|
|
1234
|
+
symbol_pairs.append((java_symbol, symbol))
|
|
1235
|
+
|
|
1236
|
+
# Build enum with avroSymbol field for proper Avro serialization
|
|
1226
1237
|
enum_definition += f"public enum {enum_name} {{\n"
|
|
1227
|
-
|
|
1238
|
+
# Each enum constant has its original Avro symbol stored
|
|
1239
|
+
enum_constants = []
|
|
1240
|
+
for java_symbol, avro_symbol in symbol_pairs:
|
|
1241
|
+
enum_constants.append(f'{java_symbol}("{avro_symbol}")')
|
|
1242
|
+
enum_definition += f"{INDENT}" + ", ".join(enum_constants)
|
|
1243
|
+
|
|
1244
|
+
# Add avroSymbol field and method with Jackson annotations for proper JSON serialization
|
|
1245
|
+
enum_definition += f";\n\n{INDENT}private final String avroSymbol;\n\n"
|
|
1246
|
+
enum_definition += f"{INDENT}{enum_name}(String avroSymbol) {{\n{INDENT*2}this.avroSymbol = avroSymbol;\n{INDENT}}}\n\n"
|
|
1247
|
+
# @JsonValue tells Jackson to serialize the enum using avroSymbol() value
|
|
1248
|
+
enum_definition += f"{INDENT}@com.fasterxml.jackson.annotation.JsonValue\n"
|
|
1249
|
+
enum_definition += f"{INDENT}public String avroSymbol() {{\n{INDENT*2}return avroSymbol;\n{INDENT}}}\n\n"
|
|
1250
|
+
|
|
1251
|
+
# Add static lookup method to find enum by Avro symbol with @JsonCreator for deserialization
|
|
1252
|
+
enum_definition += f"{INDENT}@com.fasterxml.jackson.annotation.JsonCreator\n"
|
|
1253
|
+
enum_definition += f"{INDENT}public static {enum_name} fromAvroSymbol(String symbol) {{\n"
|
|
1254
|
+
enum_definition += f"{INDENT*2}for ({enum_name} e : values()) {{\n"
|
|
1255
|
+
enum_definition += f"{INDENT*3}if (e.avroSymbol.equals(symbol)) return e;\n"
|
|
1256
|
+
enum_definition += f"{INDENT*2}}}\n"
|
|
1257
|
+
enum_definition += f"{INDENT*2}throw new IllegalArgumentException(\"Unknown symbol: \" + symbol);\n"
|
|
1258
|
+
enum_definition += f"{INDENT}}}\n"
|
|
1228
1259
|
|
|
1229
1260
|
# Add Avro schema if annotations are enabled
|
|
1230
1261
|
if self.avro_annotation:
|
|
@@ -1245,9 +1276,7 @@ class AvroToJava:
|
|
|
1245
1276
|
[enum_schema_json[i:i+80] for i in range(0, len(enum_schema_json), 80)])
|
|
1246
1277
|
enum_schema_json = enum_schema_json.replace('§', '\\"')
|
|
1247
1278
|
|
|
1248
|
-
enum_definition += f"
|
|
1249
|
-
else:
|
|
1250
|
-
enum_definition += f";\n"
|
|
1279
|
+
enum_definition += f"\n{INDENT}public static final Schema SCHEMA = new Schema.Parser().parse(\n{INDENT}\"{enum_schema_json}\");\n"
|
|
1251
1280
|
|
|
1252
1281
|
enum_definition += "}\n"
|
|
1253
1282
|
if write_file:
|
|
@@ -1295,8 +1324,9 @@ class AvroToJava:
|
|
|
1295
1324
|
f"{INDENT*1}public {union_type.type_name} get{union_variable_name}() {{ return _{camel(union_variable_name)}; }}\n";
|
|
1296
1325
|
|
|
1297
1326
|
# For toObject(), wrap enums in GenericData.EnumSymbol so Avro can serialize them
|
|
1327
|
+
# Use avroSymbol() to get the original Avro symbol name for serialization
|
|
1298
1328
|
if union_type.is_enum:
|
|
1299
|
-
class_definition_toobject += f"{INDENT*2}if (_{camel(union_variable_name)} != null) {{\n{INDENT*3}return new GenericData.EnumSymbol({union_type.type_name}.SCHEMA, _{camel(union_variable_name)}.
|
|
1329
|
+
class_definition_toobject += f"{INDENT*2}if (_{camel(union_variable_name)} != null) {{\n{INDENT*3}return new GenericData.EnumSymbol({union_type.type_name}.SCHEMA, _{camel(union_variable_name)}.avroSymbol());\n{INDENT*2}}}\n"
|
|
1300
1330
|
else:
|
|
1301
1331
|
class_definition_toobject += f"{INDENT*2}if (_{camel(union_variable_name)} != null) {{\n{INDENT*3}return _{camel(union_variable_name)};\n{INDENT*2}}}\n"
|
|
1302
1332
|
|
|
@@ -1326,8 +1356,9 @@ class AvroToJava:
|
|
|
1326
1356
|
class_definition_fromobjectctor += f"{INDENT*2}if (obj instanceof org.apache.avro.util.Utf8) {{\n{INDENT*3}this._{camel(union_variable_name)} = obj.toString();\n{INDENT*3}return;\n{INDENT*2}}}\n"
|
|
1327
1357
|
|
|
1328
1358
|
# Handle Avro's GenericEnumSymbol for enum types
|
|
1359
|
+
# Use fromAvroSymbol to match original Avro symbol names
|
|
1329
1360
|
if self.avro_annotation and union_type.is_enum:
|
|
1330
|
-
class_definition_fromobjectctor += f"{INDENT*2}if (obj instanceof GenericData.EnumSymbol) {{\n{INDENT*3}this._{camel(union_variable_name)} = {union_type.type_name}.
|
|
1361
|
+
class_definition_fromobjectctor += f"{INDENT*2}if (obj instanceof GenericData.EnumSymbol) {{\n{INDENT*3}this._{camel(union_variable_name)} = {union_type.type_name}.fromAvroSymbol(obj.toString());\n{INDENT*3}return;\n{INDENT*2}}}\n"
|
|
1331
1362
|
|
|
1332
1363
|
class_definition_fromobjectctor += f"{INDENT*2}if (obj instanceof {union_type.type_name}) {{\n{INDENT*3}this._{camel(union_variable_name)} = ({union_type.type_name})obj;\n{INDENT*3}return;\n{INDENT*2}}}\n"
|
|
1333
1364
|
|
|
@@ -1356,7 +1387,8 @@ class AvroToJava:
|
|
|
1356
1387
|
else:
|
|
1357
1388
|
# For classes and enums, use duck typing with isJsonMatch() (C# pattern)
|
|
1358
1389
|
if union_type.is_enum:
|
|
1359
|
-
|
|
1390
|
+
# Use fromAvroSymbol to match original Avro symbol names
|
|
1391
|
+
class_definition_read += f"{INDENT*3}if (node.isTextual()) {{\n{INDENT*4}return new {union_class_name}({union_type.type_name}.fromAvroSymbol(node.asText()));\n{INDENT*3}}}\n"
|
|
1360
1392
|
elif union_type.is_class:
|
|
1361
1393
|
# Use isJsonMatch() to test if this type matches, then use fromData() to deserialize
|
|
1362
1394
|
class_definition_read += f"{INDENT*3}if ({union_type.type_name}.isJsonMatch(node)) {{\n{INDENT*4}return new {union_class_name}({union_type.type_name}.fromData(node, \"application/json\"));\n{INDENT*3}}}\n"
|
|
@@ -1449,9 +1481,15 @@ class AvroToJava:
|
|
|
1449
1481
|
const_value = field['const']
|
|
1450
1482
|
is_discriminator = field.get('discriminator', False)
|
|
1451
1483
|
|
|
1452
|
-
# For enum types, qualify with the enum type name
|
|
1484
|
+
# For enum types, qualify with the enum type name and convert to SCREAMING_CASE
|
|
1453
1485
|
if field_type.type_name not in ('String', 'int', 'Integer', 'long', 'Long', 'double', 'Double', 'boolean', 'Boolean'):
|
|
1454
|
-
|
|
1486
|
+
# Convert enum const value to uppercase to match Java enum constant naming convention
|
|
1487
|
+
const_value_upper = str(const_value).replace('-', '_').replace('.', '_').upper()
|
|
1488
|
+
if const_value_upper and const_value_upper[0].isdigit():
|
|
1489
|
+
const_value_upper = '_' + const_value_upper
|
|
1490
|
+
if is_java_reserved_word(const_value_upper.lower()):
|
|
1491
|
+
const_value_upper = '_' + const_value_upper
|
|
1492
|
+
const_value = f'{field_type.type_name}.{const_value_upper}'
|
|
1455
1493
|
elif field_type.type_name == 'String':
|
|
1456
1494
|
const_value = f'"{const_value}"'
|
|
1457
1495
|
|
|
@@ -1464,11 +1502,12 @@ class AvroToJava:
|
|
|
1464
1502
|
property_def += f"{INDENT}@JsonIgnore\n"
|
|
1465
1503
|
property_def += f"{INDENT}public {field_type.type_name} get{pascal(field_name)}Value() {{ return {safe_field_name}; }}\n"
|
|
1466
1504
|
# Generate the getter that returns String (Jackson will use this for serialization)
|
|
1505
|
+
# Use avroSymbol() to get the original Avro symbol name for serialization
|
|
1467
1506
|
# Use READ_ONLY since this is a const field that doesn't need deserialization
|
|
1468
1507
|
# Note: Not using @Override because not all discriminated union variants extend a base class
|
|
1469
1508
|
if self.jackson_annotations:
|
|
1470
1509
|
property_def += f"{INDENT}@JsonProperty(value=\"{field['name']}\", access=JsonProperty.Access.READ_ONLY)\n"
|
|
1471
|
-
property_def += f"{INDENT}public String get{pascal(field_name)}() {{ return {safe_field_name}.
|
|
1510
|
+
property_def += f"{INDENT}public String get{pascal(field_name)}() {{ return {safe_field_name}.avroSymbol(); }}\n"
|
|
1472
1511
|
else:
|
|
1473
1512
|
property_def += f"{INDENT}public {field_type.type_name} get{pascal(field_name)}() {{ return {safe_field_name}; }}\n"
|
|
1474
1513
|
else:
|
|
@@ -1651,14 +1690,14 @@ class AvroToJava:
|
|
|
1651
1690
|
jackson_annotation=self.jackson_annotations
|
|
1652
1691
|
)
|
|
1653
1692
|
elif type_kind == "enum":
|
|
1654
|
-
# Convert symbols to Java-safe identifiers (same logic as generate_enum)
|
|
1693
|
+
# Convert symbols to Java-safe identifiers in SCREAMING_CASE (same logic as generate_enum)
|
|
1655
1694
|
raw_symbols = avro_schema.get('symbols', [])
|
|
1656
1695
|
java_safe_symbols = []
|
|
1657
1696
|
for symbol in raw_symbols:
|
|
1658
|
-
java_symbol = symbol.replace('-', '_').replace('.', '_')
|
|
1697
|
+
java_symbol = symbol.replace('-', '_').replace('.', '_').upper()
|
|
1659
1698
|
if java_symbol and java_symbol[0].isdigit():
|
|
1660
1699
|
java_symbol = '_' + java_symbol
|
|
1661
|
-
if is_java_reserved_word(java_symbol):
|
|
1700
|
+
if is_java_reserved_word(java_symbol.lower()):
|
|
1662
1701
|
java_symbol = '_' + java_symbol
|
|
1663
1702
|
java_safe_symbols.append(java_symbol)
|
|
1664
1703
|
|
|
@@ -1808,9 +1847,15 @@ class AvroToJava:
|
|
|
1808
1847
|
# Generate test value for the field
|
|
1809
1848
|
if "const" in field and field["const"] is not None:
|
|
1810
1849
|
const_value = field["const"]
|
|
1811
|
-
# For enum types, qualify with the enum type name
|
|
1850
|
+
# For enum types, qualify with the enum type name and convert to SCREAMING_CASE
|
|
1812
1851
|
if is_enum or (field_type.type_name not in ('String', 'int', 'Integer', 'long', 'Long', 'double', 'Double', 'boolean', 'Boolean')):
|
|
1813
|
-
|
|
1852
|
+
# Convert enum const value to uppercase to match Java enum constant naming convention
|
|
1853
|
+
const_value_upper = str(const_value).replace('-', '_').replace('.', '_').upper()
|
|
1854
|
+
if const_value_upper and const_value_upper[0].isdigit():
|
|
1855
|
+
const_value_upper = '_' + const_value_upper
|
|
1856
|
+
if is_java_reserved_word(const_value_upper.lower()):
|
|
1857
|
+
const_value_upper = '_' + const_value_upper
|
|
1858
|
+
test_value = f'{field_type.type_name}.{const_value_upper}'
|
|
1814
1859
|
else:
|
|
1815
1860
|
test_value = f'"{const_value}"'
|
|
1816
1861
|
else:
|
|
@@ -1896,12 +1941,12 @@ class AvroToJava:
|
|
|
1896
1941
|
avro_schema = self.generated_avro_schemas.get(java_type, {})
|
|
1897
1942
|
symbols = avro_schema.get('symbols', [])
|
|
1898
1943
|
if symbols:
|
|
1899
|
-
# Convert symbol to valid Java identifier (same logic as in generate_enum)
|
|
1900
|
-
first_symbol = symbols[0].replace('-', '_').replace('.', '_')
|
|
1944
|
+
# Convert symbol to valid Java identifier in SCREAMING_CASE (same logic as in generate_enum)
|
|
1945
|
+
first_symbol = symbols[0].replace('-', '_').replace('.', '_').upper()
|
|
1901
1946
|
if first_symbol and first_symbol[0].isdigit():
|
|
1902
1947
|
first_symbol = '_' + first_symbol
|
|
1903
1948
|
# Check if the symbol is a Java reserved word and prefix with underscore
|
|
1904
|
-
if is_java_reserved_word(first_symbol):
|
|
1949
|
+
if is_java_reserved_word(first_symbol.lower()):
|
|
1905
1950
|
first_symbol = '_' + first_symbol
|
|
1906
1951
|
# Use fully qualified name to avoid conflicts with field names
|
|
1907
1952
|
return f'{java_type}.{first_symbol}'
|
|
@@ -2048,7 +2093,16 @@ class AvroToJava:
|
|
|
2048
2093
|
groupid = '.'.join(package_elements[:-1]) if len(package_elements) > 1 else package_elements[0]
|
|
2049
2094
|
artifactid = package_elements[-1]
|
|
2050
2095
|
with open(pom_path, 'w', encoding='utf-8') as file:
|
|
2051
|
-
file.write(POM_CONTENT.format(
|
|
2096
|
+
file.write(POM_CONTENT.format(
|
|
2097
|
+
groupid=groupid,
|
|
2098
|
+
artifactid=artifactid,
|
|
2099
|
+
AVRO_VERSION=AVRO_VERSION,
|
|
2100
|
+
JACKSON_VERSION=JACKSON_VERSION,
|
|
2101
|
+
JDK_VERSION=JDK_VERSION,
|
|
2102
|
+
JUNIT_VERSION=JUNIT_VERSION,
|
|
2103
|
+
MAVEN_COMPILER_VERSION=MAVEN_COMPILER_VERSION,
|
|
2104
|
+
MAVEN_SUREFIRE_VERSION=MAVEN_SUREFIRE_VERSION,
|
|
2105
|
+
PACKAGE=self.base_package))
|
|
2052
2106
|
output_dir = os.path.join(
|
|
2053
2107
|
output_dir, "src/main/java".replace('/', os.sep))
|
|
2054
2108
|
if not os.path.exists(output_dir):
|