-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathgenerate_serializers.py
225 lines (202 loc) · 9.19 KB
/
generate_serializers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# This file implements the code generator for generating schema and resolvers for FHIR
# It reads the FHIR XML schema and generates resolvers in the resolvers folder and schema in the schema folder
import os
import shutil
from os import path
from pathlib import Path
from typing import Union, List, Dict, Any
from fhir_xml_schema_parser import FhirXmlSchemaParser
from search_parameters import search_parameter_queries
from fhir_xml_schema_parser import FhirEntity
def my_copytree(
src: Union[Path, str],
dst: Union[Path, str],
symlinks: bool = False,
# ignore: Union[
# None,
# Callable[[str, List[str]], Iterable[str]],
# Callable[[Union[str, os.PathLike[str]], List[str]], Iterable[str]],
# ] = None,
) -> None:
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isdir(s):
shutil.copytree(s, d, symlinks)
else:
shutil.copy2(s, d)
def clean_duplicate_lines(file_path: Union[Path, str]) -> None:
print(f"Removing duplicate lines from {file_path}")
with open(file_path, "r") as file:
lines: List[str] = file.readlines()
new_lines: List[str] = []
for line in lines:
if (
not line.strip()
or not line.lstrip().startswith("from")
or (
line not in new_lines
and line.lstrip() not in [c.lstrip() for c in new_lines]
)
):
new_lines.append(line)
with open(file_path, "w") as file:
file.writelines(new_lines)
def main() -> int:
data_dir: Path = Path(__file__).parent.joinpath("./")
fhir_dir = Path(__file__).parent.joinpath("../")
serializers_dir: Path = fhir_dir.joinpath("serializers/4_0_0/")
serializer_template_file_name = 'template.javascript.class_serializer.jinja2'
# clean out old stuff for serializers
serializers_resources_folder = serializers_dir.joinpath("resources")
if os.path.exists(serializers_resources_folder):
shutil.rmtree(serializers_resources_folder)
os.mkdir(serializers_resources_folder)
serializers_complex_types_folder = serializers_dir.joinpath("complex_types")
if os.path.exists(serializers_complex_types_folder):
shutil.rmtree(serializers_complex_types_folder)
os.mkdir(serializers_complex_types_folder)
serializers_backbone_elements_folder = serializers_dir.joinpath("backbone_elements")
if os.path.exists(serializers_backbone_elements_folder):
shutil.rmtree(serializers_backbone_elements_folder)
os.mkdir(serializers_backbone_elements_folder)
fhir_entities: List[FhirEntity] = FhirXmlSchemaParser.generate_classes()
# now print the result
for fhir_entity in fhir_entities:
# use template to generate new code files
resource_name: str = fhir_entity.cleaned_name
entity_file_name = fhir_entity.name_snake_case
if fhir_entity.is_value_set: # valueset
pass
elif fhir_entity.is_resource:
search_parameters_for_all_resources: Dict[str, Dict[str, Any]] = (
search_parameter_queries.get("Resource", {}) if fhir_entity.fhir_name != "Resource" else {}
)
search_parameters_for_current_resource: Dict[str, Dict[str, Any]] = (
search_parameter_queries.get(fhir_entity.fhir_name, {})
)
# write Javascript classes
with open(data_dir.joinpath(serializer_template_file_name), "r") as file:
template_contents = file.read()
from jinja2 import Template
file_path = serializers_resources_folder.joinpath(f"{entity_file_name}.js")
print(f"Writing domain resource: {entity_file_name} to {file_path}...")
template = Template(
template_contents, trim_blocks=True, lstrip_blocks=True
)
result = template.render(
fhir_entity=fhir_entity,
search_parameters_for_all_resources=search_parameters_for_all_resources,
search_parameters_for_current_resource=search_parameters_for_current_resource,
extra_properties=[
{
"name": "_access",
"type": "Object"
},
{
"name": "_sourceAssigningAuthority",
"type": "string"
},
{
"name": "_uuid",
"type": "string"
},
{
"name": "_sourceId",
"type": "string"
}
]
)
if not path.exists(file_path):
with open(file_path, "w") as file2:
file2.write(result)
elif fhir_entity.type_ == "BackboneElement" or fhir_entity.is_back_bone_element:
with open(data_dir.joinpath(serializer_template_file_name), "r") as file:
template_contents = file.read()
from jinja2 import Template
file_path = serializers_backbone_elements_folder.joinpath(f"{entity_file_name}.js")
print(f"Writing back bone class: {entity_file_name} to {file_path}...")
template = Template(
template_contents, trim_blocks=True, lstrip_blocks=True
)
result = template.render(
fhir_entity=fhir_entity,
)
if not path.exists(file_path):
with open(file_path, "w") as file2:
file2.write(result)
elif fhir_entity.is_extension: # valueset
# write Javascript classes
with open(data_dir.joinpath(serializer_template_file_name), "r") as file:
template_contents = file.read()
from jinja2 import Template
file_path = serializers_complex_types_folder.joinpath(f"{entity_file_name}.js")
print(f"Writing extension as complex type: {entity_file_name} to {file_path}...")
template = Template(
template_contents, trim_blocks=True, lstrip_blocks=True
)
result = template.render(
fhir_entity=fhir_entity
)
if not path.exists(file_path):
with open(file_path, "w") as file2:
file2.write(result)
elif fhir_entity.type_ == "Element": # valueset
# write Javascript classes
with open(data_dir.joinpath(serializer_template_file_name), "r") as file:
template_contents = file.read()
from jinja2 import Template
file_path = serializers_complex_types_folder.joinpath(f"{entity_file_name}.js")
print(f"Writing complex type: {entity_file_name} to {file_path}...")
template = Template(
template_contents, trim_blocks=True, lstrip_blocks=True
)
extra_properties = [
{
"name": "_file_id",
"type": "string"
}
] if entity_file_name == "attachment" else []
result = template.render(
fhir_entity=fhir_entity,
extra_properties_for_reference=[
{
"name": "_sourceAssigningAuthority",
"type": "string"
},
{
"name": "_uuid",
"type": "string"
},
{
"name": "_sourceId",
"type": "string"
}
],
extra_properties=extra_properties,
extra_properties_for_json=extra_properties
)
if not path.exists(file_path):
with open(file_path, "w") as file2:
file2.write(result)
elif fhir_entity.type_ in ["Quantity"]: # valueset
with open(data_dir.joinpath(serializer_template_file_name), "r") as file:
template_contents = file.read()
from jinja2 import Template
file_path = serializers_complex_types_folder.joinpath(f"{entity_file_name}.js")
print(f"Writing complex_type: {entity_file_name} to {file_path}...")
template = Template(
template_contents, trim_blocks=True, lstrip_blocks=True
)
result = template.render(
fhir_entity=fhir_entity,
)
if not path.exists(file_path):
with open(file_path, "w") as file2:
file2.write(result)
else:
print(f"{resource_name}: {fhir_entity.type_} is not supported")
# print(result)
return 0
if __name__ == "__main__":
exit(main())