File Coverage

blib/lib/SBOM/CycloneDX/Schema.pm
Criterion Covered Total %
statement 37 49 75.5
branch 0 2 0.0
condition 1 2 50.0
subroutine 14 16 87.5
pod 4 4 100.0
total 56 73 76.7


line stmt bran cond sub pod time code
1             package SBOM::CycloneDX::Schema;
2              
3 16     16   235 use 5.010001;
  16         40  
4 16     16   59 use strict;
  16         21  
  16         332  
5 16     16   53 use warnings;
  16         19  
  16         621  
6 16     16   66 use utf8;
  16         41  
  16         111  
7              
8 16     16   527 use Exporter qw(import);
  16         22  
  16         733  
9              
10             our @EXPORT = qw(
11             schema_dir
12             schema_file
13             );
14              
15 16     16   6079 use SBOM::CycloneDX;
  16         52  
  16         667  
16              
17 16     16   111 use File::Basename qw(dirname);
  16         24  
  16         1068  
18 16     16   1348 use File::Spec::Functions qw(catfile);
  16         1890  
  16         720  
19 16     16   8610 use JSON::Validator;
  16         8272547  
  16         125  
20              
21 16     16   784 use Types::Standard qw(HashRef InstanceOf);
  16         26  
  16         341  
22              
23 16     16   38775 use Moo;
  16         35  
  16         130  
24              
25 16   50 16   5533 use constant DEBUG => $ENV{SBOM_DEBUG} || 0;
  16         31  
  16         5574  
26              
27             our @JSON_SCHEMA_REGISTRY = (
28             'bom-1.2-strict.schema.json', 'bom-1.2.schema.json', 'bom-1.3-strict.schema.json', 'bom-1.3.schema.json',
29             'bom-1.4.schema.json', 'bom-1.5.schema.json', 'bom-1.6.schema.json', 'bom-1.7.schema.json',
30             'jsf-0.82.schema.json', 'spdx.schema.json', 'cryptography-defs.schema.json'
31             );
32              
33             has bom => (is => 'ro', isa => InstanceOf ['SBOM::CycloneDX'] | HashRef, required => 1);
34              
35 16     16 1 1047 sub schema_dir { catfile(dirname(__FILE__), 'schema') }
36 16     16 1 46 sub schema_file { catfile(schema_dir, shift) }
37              
38             sub validator {
39              
40 0     0 1   my ($self) = @_;
41              
42 0           my $jv = JSON::Validator->new;
43              
44 0           foreach my $json_schema_file (@JSON_SCHEMA_REGISTRY) {
45 0           DEBUG and say sprintf('-- Preload JSON Schema file %s', $json_schema_file);
46 0           $jv->store->load(schema_file($json_schema_file));
47             }
48              
49 0 0         my $spec_version = (ref $self->bom eq 'HASH') ? $self->bom->{specVersion} : $self->bom->spec_version;
50 0           my $cyclonedx_json_schema = $SBOM::CycloneDX::JSON_SCHEMA{$spec_version};
51              
52 0           DEBUG and say sprintf('-- Use %s JSON schema for validation', $cyclonedx_json_schema);
53              
54 0           $jv->schema($cyclonedx_json_schema)->schema->coerce('bool,num');
55              
56 0           return $jv;
57              
58             }
59              
60             sub validate {
61 0     0 1   my ($self) = @_;
62 0           return $self->validator->validate($self->bom);
63             }
64              
65              
66             1;
67              
68             =encoding utf-8
69              
70             =head1 NAME
71              
72             SBOM::CycloneDX::Schema - JSON Schema Validator
73              
74             =head1 SYNOPSIS
75              
76             use SBOM::CycloneDX::Schema;
77              
78             my $validator = SBOM::CycloneDX::Schema->new(bom => sbom);
79              
80             my @errors = $validator->validate;
81              
82             say $_ for @errors;
83              
84              
85             =head1 DESCRIPTION
86              
87             Validate CycloneDX objects using JSON Schema.
88              
89             =head2 METHODS
90              
91             =over
92              
93             =item SBOM::CycloneDX::Schema->new(object => $object)
94              
95             =item $schema->bom
96              
97             L instance or HASH.
98              
99             =item $schema->validator
100              
101             Return L object.
102              
103             =item $schema->validate
104              
105             Validate and return the L errors.
106              
107             =back
108              
109             =head2 FUNCTIONS
110              
111             =over
112              
113             =item schema_dir
114              
115             Return the CycloneDX schema path.
116              
117             =item schema_file ($json_schema_file)
118              
119             Return the CycloneDX schema file path.
120              
121             schema_file('bom-1.6.schema.json'); # ../SBOM/CycloneDX/schema/bom-1.6.schema.json
122              
123             =back
124              
125             =head1 SUPPORT
126              
127             =head2 Bugs / Feature Requests
128              
129             Please report any bugs or feature requests through the issue tracker
130             at L.
131             You will be notified automatically of any progress on your issue.
132              
133             =head2 Source Code
134              
135             This is open source software. The code repository is available for
136             public review and contribution under the terms of the license.
137              
138             L
139              
140             git clone https://github.com/giterlizzi/perl-SBOM-CycloneDX.git
141              
142              
143             =head1 AUTHOR
144              
145             =over 4
146              
147             =item * Giuseppe Di Terlizzi
148              
149             =back
150              
151              
152             =head1 LICENSE AND COPYRIGHT
153              
154             This software is copyright (c) 2025-2026 by Giuseppe Di Terlizzi.
155              
156             This is free software; you can redistribute it and/or modify it under
157             the same terms as the Perl 5 programming language system itself.
158              
159             =cut