| 508 | |
| 509 | @classmethod |
| 510 | def serialize(cls, id_=None): |
| 511 | # The order matters |
| 512 | serialized = OrderedDict() |
| 513 | if id_ is not None: |
| 514 | # This is meant as a configuration section, sub json schema |
| 515 | serialized["id"] = f"{BASE_SCHEMA_URL}/{id_}.json#" |
| 516 | else: |
| 517 | # Main configuration block, json schema |
| 518 | serialized["$schema"] = "http://json-schema.org/draft-04/schema#" |
| 519 | if cls.title is not None: |
| 520 | serialized["title"] = cls.title |
| 521 | if cls.description is not None: |
| 522 | if cls.description == cls.__doc__: |
| 523 | serialized["description"] = textwrap.dedent(cls.description).strip() |
| 524 | else: |
| 525 | serialized["description"] = cls.description |
| 526 | |
| 527 | required = [] |
| 528 | ordering = [] |
| 529 | serialized["type"] = "object" |
| 530 | properties = OrderedDict() |
| 531 | cls.after_items_update = [] |
| 532 | for name in cls._order: # pylint: disable=E1133 |
| 533 | skip_order = False |
| 534 | item_name = None |
| 535 | if name in cls._sections: # pylint: disable=E1135 |
| 536 | section = cls._sections[name] |
| 537 | serialized_section = section.serialize( |
| 538 | None if section.__flatten__ is True else name |
| 539 | ) |
| 540 | if section.__flatten__ is True: |
| 541 | # Flatten the configuration section into the parent |
| 542 | # configuration |
| 543 | properties.update(serialized_section["properties"]) |
| 544 | if "x-ordering" in serialized_section: |
| 545 | ordering.extend(serialized_section["x-ordering"]) |
| 546 | if "required" in serialized_section: |
| 547 | required.extend(serialized_section["required"]) |
| 548 | if hasattr(section, "after_items_update"): |
| 549 | cls.after_items_update.extend(section.after_items_update) |
| 550 | skip_order = True |
| 551 | else: |
| 552 | # Store it as a configuration section |
| 553 | properties[name] = serialized_section |
| 554 | |
| 555 | if name in cls._items: # pylint: disable=E1135 |
| 556 | config = cls._items[name] |
| 557 | item_name = config.__item_name__ or name |
| 558 | # Handle the configuration items defined in the class instance |
| 559 | if config.__flatten__ is True: |
| 560 | serialized_config = config.serialize() |
| 561 | cls.after_items_update.append(serialized_config) |
| 562 | skip_order = True |
| 563 | else: |
| 564 | properties[item_name] = config.serialize() |
| 565 | |
| 566 | if config.required: |
| 567 | # If it's a required item, add it to the required list |