| 26 | |
| 27 | |
| 28 | class CodeGenerator: |
| 29 | all_classes: dict[str, AttributeClass] |
| 30 | base_output_path: Path |
| 31 | |
| 32 | def __init__(self, base_output_path: Path) -> None: |
| 33 | self.all_classes = {} |
| 34 | self.base_output_path = base_output_path |
| 35 | |
| 36 | def render_template(self, template_path: Path, output_path: Path, **data): |
| 37 | # jinja expects a string, representing a relative path with forward slashes |
| 38 | template_path_str = str(template_path.relative_to(TEMPLATE_DIR)).replace("\\", "/") |
| 39 | template = JINJA_ENV.get_template(template_path_str) |
| 40 | |
| 41 | output = template.render(**data) |
| 42 | |
| 43 | with output_path.open(mode="w", encoding="utf-8") as output_file: |
| 44 | output_file.write(output) |
| 45 | |
| 46 | def render_attribute_classes(self, template_path: Path, data_path: Path, output_path: Path): |
| 47 | with data_path.open() as data_file: |
| 48 | json_data = data_file.read() |
| 49 | dataset_meta_data: DatasetMetaData = DatasetMetaData.schema().loads(json_data) |
| 50 | # flatten attribute list |
| 51 | # assign full name |
| 52 | for attribute_class in dataset_meta_data.classes: |
| 53 | if attribute_class.is_template: |
| 54 | attribute_class.full_name = f"{attribute_class.name}<sym>" |
| 55 | attribute_class.specification_names = [ |
| 56 | f"{attribute_class.name}<symmetric_t>", |
| 57 | f"{attribute_class.name}<asymmetric_t>", |
| 58 | f"Sym{attribute_class.name}", |
| 59 | f"Asym{attribute_class.name}", |
| 60 | ] |
| 61 | else: |
| 62 | attribute_class.full_name = attribute_class.name |
| 63 | attribute_class.specification_names = [attribute_class.name] |
| 64 | new_attribute_list = [] |
| 65 | for attribute in attribute_class.attributes: |
| 66 | attribute.nan_value = _data_type_nan(attribute.data_type) |
| 67 | if isinstance(attribute.names, str): |
| 68 | new_attribute_list.append(attribute) |
| 69 | else: |
| 70 | # flatten list |
| 71 | for name in attribute.names: |
| 72 | new_attribute = deepcopy(attribute) |
| 73 | new_attribute.names = name |
| 74 | new_attribute_list.append(new_attribute) |
| 75 | attribute_class.attributes = new_attribute_list |
| 76 | # get full attribute |
| 77 | if attribute_class.base is not None: |
| 78 | base_class = next(filter(lambda x: x.name == attribute_class.base, dataset_meta_data.classes)) |
| 79 | attribute_class.full_attributes = base_class.full_attributes + attribute_class.attributes |
| 80 | attribute_class.base_attributes = base_class.base_attributes.copy() |
| 81 | attribute_class.base_attributes[base_class.name] = base_class.full_attributes |
| 82 | else: |
| 83 | attribute_class.full_attributes = attribute_class.attributes |
| 84 | attribute_class.base_attributes = {} |
| 85 | # add to class dict |