from typing import Any from core.Expando import Expando from workflow.engine import DataPresenter class DefaultDataPresenter(DataPresenter): """Default data presenter that returns the input data unchanged.""" def __init__(self, component_id: str, mappings_definition: str): super().__init__(component_id) self._mappings_definition = mappings_definition self._split_definitions = [definition.strip() for definition in mappings_definition.split(",")] if "*" not in mappings_definition: self._static_mappings = self._get_static_mappings() else: self._static_mappings = None def present(self, data: Any) -> Any: self._validate_mappings_definition() if self._static_mappings: return Expando(data.to_dict(self._static_mappings)) dynamic_mappings = self._get_dynamic_mappings(data) return Expando(data.to_dict(dynamic_mappings)) def _get_dynamic_mappings(self, data): manage_conflicts = {} mappings = {} for mapping in self._split_definitions: if "=" in mapping: key, value = [s.strip() for s in mapping.split('=', 1)] if key == "*": # all fields if value != "*": raise ValueError("Only '*' is accepted when renaming wildcard.") for key in data.as_dict().keys(): if key in manage_conflicts: raise ValueError(f"Collision detected for field '{key}'. It is mapped from both '{manage_conflicts[key]}' and '{mapping}'.") manage_conflicts[key] = mapping mappings[key] = key elif key.endswith(".*"): # all fields in a sub-object if value != "*" and value != "": raise ValueError("Only '*' is accepted when renaming wildcard.") obj_path = key[:-2] sub_obj = data.get(obj_path) if isinstance(sub_obj, dict): for sub_field in sub_obj: if sub_field in manage_conflicts: raise ValueError( f"Collision detected for field '{sub_field}'. It is mapped from both '{manage_conflicts[sub_field]}' and '{mapping}'.") manage_conflicts[sub_field] = mapping mappings[f"{obj_path}.{sub_field}"] = sub_field else: raise ValueError(f"Field '{obj_path}' is not an object.") else: mappings[key.strip()] = value.strip() else: if mapping == "*": # all fields for key in data.as_dict().keys(): mappings[key] = key elif mapping.endswith(".*"): # all fields in a sub-object obj_path = mapping[:-2] sub_obj = data.get(obj_path) if isinstance(sub_obj, dict): for sub_field in sub_obj: mappings[f"{obj_path}.{sub_field}"] = f"{obj_path}.{sub_field}" else: raise ValueError(f"Field '{obj_path}' is not an object.") else: mappings[mapping] = mapping return mappings def _get_static_mappings(self): mappings = {} for mapping in self._split_definitions: if "=" in mapping: key, value = [s.strip() for s in mapping.split('=', 1)] if not value: value = key.split(".")[-1] mappings[key] = value else: mappings[mapping] = mapping return mappings def _validate_mappings_definition(self): last_char_was_comma = False for i, char in enumerate(self._mappings_definition): if char == ',': if last_char_was_comma: raise ValueError(f"Invalid mappings definition: Error found at index {i}") last_char_was_comma = True elif not char.isspace(): last_char_was_comma = False