Skip to content

Commit e43364b

Browse files
committed
refactor(models): ♻️ introduce pre/post internal validation hooks on Validator
1 parent 4f7ec5a commit e43364b

1 file changed

Lines changed: 47 additions & 3 deletions

File tree

rocrate_validator/models.py

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,32 @@ def __get_requirement_loader__(cls, profile: Profile, requirement_path: Path) ->
11431143
setattr(profile, loader_instance_name, loader_instance)
11441144
return loader_instance
11451145

1146+
@staticmethod
1147+
def __get_requirement_classes__() -> list[Type[Requirement]]:
1148+
1149+
# Ensure known requirement modules are imported so subclasses are registered.
1150+
for requirement_type in ("python", "shacl"):
1151+
module_name = f"rocrate_validator.requirements.{requirement_type}"
1152+
try:
1153+
importlib.import_module(module_name)
1154+
except Exception:
1155+
logger.debug(
1156+
"Unable to import requirement module: %s",
1157+
module_name,
1158+
exc_info=True,
1159+
)
1160+
1161+
def all_subclasses(
1162+
base_class: Type[Requirement],
1163+
) -> list[Type[Requirement]]:
1164+
result: list[Type[Requirement]] = []
1165+
for subcls in base_class.__subclasses__():
1166+
result.append(subcls)
1167+
result.extend(all_subclasses(subcls))
1168+
return result
1169+
1170+
return all_subclasses(Requirement)
1171+
11461172
@staticmethod
11471173
def load_requirements(profile: Profile, severity: Severity = None) -> list[Requirement]:
11481174
"""
@@ -2682,7 +2708,8 @@ def __do_validate__(self,
26822708
# register the current context
26832709
self.__current_context__ = context
26842710

2685-
try:
2711+
# initialize the requirement types
2712+
self.__invoke_pre_validation_hooks__(context)
26862713

26872714
# set the profiles to validate against
26882715
profiles = context.profiles
@@ -2720,14 +2747,31 @@ def __do_validate__(self,
27202747
self.notify(ProfileValidationEvent(EventType.PROFILE_VALIDATION_END, profile=profile))
27212748
if terminate:
27222749
break
2723-
self.notify(ValidationEvent(EventType.VALIDATION_END,
2724-
validation_result=context.result))
27252750

2751+
# finalize the requirement types
2752+
self.__invoke_post_validation_hooks__(context)
2753+
# notify the end of the validation
2754+
self.notify(ValidationEvent(EventType.VALIDATION_END, validation_result=context.result))
2755+
# return the validation result
27262756
return context.result
27272757
finally:
27282758
# clear the current context
27292759
self.__current_context__ = None
27302760

2761+
def __invoke_pre_validation_hooks__(self, context: ValidationContext):
2762+
logger.debug("Initializing requirement types: starting...")
2763+
requirements_types = RequirementLoader.__get_requirement_classes__()
2764+
for requirement_type in requirements_types:
2765+
requirement_type.initialize(context)
2766+
logger.debug("Initializing requirement types: completed")
2767+
2768+
def __invoke_post_validation_hooks__(self, context: ValidationContext):
2769+
logger.debug("Finalizing requirement types: starting...")
2770+
requirements_types = RequirementLoader.__get_requirement_classes__()
2771+
for requirement_type in requirements_types:
2772+
requirement_type.finalize(context)
2773+
logger.debug("Finalizing requirement types: completed")
2774+
27312775
def notify(self, event: Union[Event, EventType]):
27322776
""" Override notify to update statistics """
27332777
assert self.__current_context__ is not None, "No current validation context"

0 commit comments

Comments
 (0)