Skip to content

links_validator

Validate catalog by confirming control links match resources in backmatter.

Bases: Validator

Validator to confirm all uuids in links and prose match resources in backmatter.

Source code in trestle/core/links_validator.py
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
class LinksValidator(Validator):
    """Validator to confirm all uuids in links and prose match resources in backmatter."""

    def model_is_valid(
        self, model: TopLevelOscalModel, quiet: bool, trestle_root: Optional[pathlib.Path] = None
    ) -> bool:
        """
        Test if the model is valid.

        args:
            model: A top level OSCAL model.
            quiet: Don't report msgs unless invalid.

        returns:
            Always returns True, but gives warning if links and resources are not one-to-one.
        """
        refs = ModelUtils.find_uuid_refs(model)

        # find uuids in backmatter
        links: List[str] = []
        if model.back_matter and model.back_matter.resources:
            links = [res.uuid for res in model.back_matter.resources]
            seen: Set[str] = set()
            dupes: List[str] = []
            for uuid in links:
                if uuid in seen:
                    dupes.append(uuid)
                else:
                    seen.add(uuid)
            if dupes:
                if not quiet:
                    logger.warning(f'Backmatter has  {len(dupes)} duplicate link uuids.')
                logger.debug(f'Backmatter has {len(dupes)} duplicate link uuids: {dupes}')

        links = set(links)
        in_refs = refs.difference(links)
        if in_refs:
            if not quiet:
                logger.warning(f'Model references {len(refs)} uuids and {len(in_refs)} of them are not in resources.')
            logger.debug(f'Model references {len(in_refs)} uuids not in resources: {in_refs}')

        in_links = links.difference(refs)
        if in_links:
            if not quiet:
                logger.warning(f'Resources have {len(links)} uuids and {len(in_links)} are not referenced by model.')
            logger.debug(f'Resources have {len(in_links)} uuids not referenced by model: {in_links}')

        # This validator is intended just to give warnings, so it always returns True
        return True

Test if the model is valid.

Parameters:

Name Type Description Default
model TopLevelOscalModel

A top level OSCAL model.

required
quiet bool

Don't report msgs unless invalid.

required

Returns:

Type Description
bool

Always returns True, but gives warning if links and resources are not one-to-one.

Source code in trestle/core/links_validator.py
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
def model_is_valid(
    self, model: TopLevelOscalModel, quiet: bool, trestle_root: Optional[pathlib.Path] = None
) -> bool:
    """
    Test if the model is valid.

    args:
        model: A top level OSCAL model.
        quiet: Don't report msgs unless invalid.

    returns:
        Always returns True, but gives warning if links and resources are not one-to-one.
    """
    refs = ModelUtils.find_uuid_refs(model)

    # find uuids in backmatter
    links: List[str] = []
    if model.back_matter and model.back_matter.resources:
        links = [res.uuid for res in model.back_matter.resources]
        seen: Set[str] = set()
        dupes: List[str] = []
        for uuid in links:
            if uuid in seen:
                dupes.append(uuid)
            else:
                seen.add(uuid)
        if dupes:
            if not quiet:
                logger.warning(f'Backmatter has  {len(dupes)} duplicate link uuids.')
            logger.debug(f'Backmatter has {len(dupes)} duplicate link uuids: {dupes}')

    links = set(links)
    in_refs = refs.difference(links)
    if in_refs:
        if not quiet:
            logger.warning(f'Model references {len(refs)} uuids and {len(in_refs)} of them are not in resources.')
        logger.debug(f'Model references {len(in_refs)} uuids not in resources: {in_refs}')

    in_links = links.difference(refs)
    if in_links:
        if not quiet:
            logger.warning(f'Resources have {len(links)} uuids and {len(in_links)} are not referenced by model.')
        logger.debug(f'Resources have {len(in_links)} uuids not referenced by model: {in_links}')

    # This validator is intended just to give warnings, so it always returns True
    return True

handler: python