dcc 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +19 -0
- data/.github/workflows/release.yml +28 -0
- data/.gitignore +4 -0
- data/.rubocop_todo.yml +560 -10
- data/CHANGELOG.adoc +34 -1
- data/CONTRIBUTING.adoc +8 -1
- data/Gemfile +5 -7
- data/README.adoc +162 -7
- data/dcc.gemspec +8 -2
- data/docs/schema-versions.adoc +20 -7
- data/examples/build_minimal_dcc.rb +0 -0
- data/examples/convert_all_formats.rb +2 -1
- data/examples/parse_and_inspect.rb +0 -0
- data/examples/quantity_math_demo.rb +7 -7
- data/examples/validate_full.rb +1 -1
- data/lib/dcc/base/calibration_laboratory.rb +2 -1
- data/lib/dcc/base/condition.rb +5 -2
- data/lib/dcc/base/core_data.rb +8 -3
- data/lib/dcc/base/formula.rb +3 -3
- data/lib/dcc/base/identification.rb +6 -3
- data/lib/dcc/base/mathml.rb +33 -0
- data/lib/dcc/base/quantity.rb +2 -1
- data/lib/dcc/base/resp_person.rb +4 -2
- data/lib/dcc/base/text.rb +1 -1
- data/lib/dcc/base.rb +2 -1
- data/lib/dcc/builder/dsl.rb +1 -1
- data/lib/dcc/builder/session.rb +16 -14
- data/lib/dcc/builder.rb +3 -3
- data/lib/dcc/cli/cli.rb +36 -18
- data/lib/dcc/cli/formatters.rb +35 -7
- data/lib/dcc/cli.rb +1 -1
- data/lib/dcc/context_configuration.rb +2 -1
- data/lib/dcc/context_options.rb +4 -2
- data/lib/dcc/convert/csv.rb +27 -9
- data/lib/dcc/convert/html.rb +26 -110
- data/lib/dcc/convert/json.rb +10 -7
- data/lib/dcc/convert/liquid_filters.rb +58 -0
- data/lib/dcc/convert/result.rb +1 -1
- data/lib/dcc/convert/templates/report.liquid +250 -0
- data/lib/dcc/convert/yaml.rb +1 -1
- data/lib/dcc/convert.rb +1 -0
- data/lib/dcc/diff/change.rb +1 -1
- data/lib/dcc/diff/result.rb +8 -4
- data/lib/dcc/diff.rb +43 -11
- data/lib/dcc/error.rb +7 -0
- data/lib/dcc/extract/file.rb +3 -4
- data/lib/dcc/extract/ring.rb +1 -1
- data/lib/dcc/extract.rb +1 -1
- data/lib/dcc/i18n/text_lookup.rb +8 -4
- data/lib/dcc/i18n.rb +1 -1
- data/lib/dcc/inspect/report.rb +51 -14
- data/lib/dcc/inspect.rb +1 -1
- data/lib/dcc/migrate/route.rb +44 -0
- data/lib/dcc/migrate/v2_to_v3.rb +445 -0
- data/lib/dcc/migrate.rb +130 -26
- data/lib/dcc/plugin/base.rb +64 -0
- data/lib/dcc/plugin/registry.rb +7 -2
- data/lib/dcc/plugin.rb +6 -2
- data/lib/dcc/quantity_format/formatter.rb +16 -10
- data/lib/dcc/quantity_format.rb +1 -1
- data/lib/dcc/quantity_math/quantity.rb +1 -1
- data/lib/dcc/quantity_math/real.rb +6 -6
- data/lib/dcc/quantity_math.rb +1 -1
- data/lib/dcc/schema/version.rb +2 -2
- data/lib/dcc/server/app.html +282 -0
- data/lib/dcc/server/app.rb +171 -87
- data/lib/dcc/server/demo_cert.xml +244 -0
- data/lib/dcc/server/storage/entry.rb +1 -1
- data/lib/dcc/server/storage/memory.rb +3 -2
- data/lib/dcc/server/storage.rb +1 -1
- data/lib/dcc/server.rb +1 -1
- data/lib/dcc/si/base/complex.rb +1 -1
- data/lib/dcc/si/base/complex_list_xml_list.rb +1 -1
- data/lib/dcc/si/base/constant.rb +1 -1
- data/lib/dcc/si/base/coverage_interval.rb +36 -0
- data/lib/dcc/si/base/coverage_interval_mu.rb +1 -1
- data/lib/dcc/si/base/expanded_mu.rb +1 -1
- data/lib/dcc/si/base/expanded_unc.rb +34 -0
- data/lib/dcc/si/base/expanded_unc_xml_list.rb +3 -2
- data/lib/dcc/si/base/hybrid.rb +3 -2
- data/lib/dcc/si/base/measurement_uncertainty_univariate.rb +1 -1
- data/lib/dcc/si/base/real.rb +13 -3
- data/lib/dcc/si/base/real_list_xml_list.rb +5 -3
- data/lib/dcc/si/base/si_list.rb +3 -2
- data/lib/dcc/si/base/standard_mu.rb +1 -1
- data/lib/dcc/si/base.rb +5 -2
- data/lib/dcc/si/v1/coverage_interval.rb +8 -0
- data/lib/dcc/si/v1/expanded_unc.rb +1 -16
- data/lib/dcc/si/v1/measurement_uncertainty_univariate.rb +2 -1
- data/lib/dcc/si/v1.rb +5 -2
- data/lib/dcc/si/v2/coverage_interval.rb +8 -0
- data/lib/dcc/si/v2/coverage_interval_mu_xml_list.rb +4 -2
- data/lib/dcc/si/v2/expanded_mu_xml_list.rb +2 -1
- data/lib/dcc/si/v2/expanded_unc.rb +8 -0
- data/lib/dcc/si/v2/measurement_uncertainty_univariate.rb +2 -1
- data/lib/dcc/si/v2.rb +8 -3
- data/lib/dcc/signature/result.rb +2 -2
- data/lib/dcc/signature/signer.rb +31 -18
- data/lib/dcc/signature/verifier.rb +23 -21
- data/lib/dcc/signature.rb +1 -1
- data/lib/dcc/transform/result.rb +1 -1
- data/lib/dcc/transform/xslt.rb +22 -12
- data/lib/dcc/transform.rb +5 -4
- data/lib/dcc/type/base64_binary.rb +5 -3
- data/lib/dcc/type/decimal_xml_list.rb +99 -13
- data/lib/dcc/type/iso_country_code.rb +3 -2
- data/lib/dcc/type/iso_language_code.rb +3 -2
- data/lib/dcc/type/schema_version.rb +3 -2
- data/lib/dcc/type/si_unit.rb +3 -2
- data/lib/dcc/type_guards.rb +3 -3
- data/lib/dcc/v2/calibration_laboratory.rb +2 -1
- data/lib/dcc/v2/condition.rb +22 -1
- data/lib/dcc/v2/configuration.rb +1 -1
- data/lib/dcc/v2/digital_calibration_certificate.rb +2 -1
- data/lib/dcc/v2/identification.rb +14 -1
- data/lib/dcc/v2/mathml.rb +8 -0
- data/lib/dcc/v2/measurement_meta_data_list.rb +2 -1
- data/lib/dcc/v2/quantity.rb +4 -2
- data/lib/dcc/v2.rb +4 -2
- data/lib/dcc/v3/calibration_laboratory.rb +2 -1
- data/lib/dcc/v3/configuration.rb +1 -1
- data/lib/dcc/v3/digital_calibration_certificate.rb +2 -1
- data/lib/dcc/v3/mathml.rb +8 -0
- data/lib/dcc/v3/measurement_meta_data_list.rb +2 -1
- data/lib/dcc/v3/quantity.rb +4 -2
- data/lib/dcc/v3.rb +12 -2
- data/lib/dcc/validate/business_rules.rb +23 -9
- data/lib/dcc/validate/issue.rb +2 -1
- data/lib/dcc/validate/result.rb +6 -4
- data/lib/dcc/validate/schematron/profile.rb +73 -18
- data/lib/dcc/validate/schematron/rule.rb +13 -3
- data/lib/dcc/validate/schematron/rules/administrative_data_completeness.rb +11 -4
- data/lib/dcc/validate/schematron/rules/base.rb +1 -2
- data/lib/dcc/validate/schematron/rules/date_range_check.rb +11 -5
- data/lib/dcc/validate/schematron/rules/id_refid_linking.rb +0 -3
- data/lib/dcc/validate/schematron/rules/influence_conditions_placement.rb +22 -12
- data/lib/dcc/validate/schematron/rules/iso_code_validation.rb +31 -14
- data/lib/dcc/validate/schematron/rules/language_code_dedup.rb +12 -5
- data/lib/dcc/validate/schematron/rules/non_si_declaration.rb +7 -4
- data/lib/dcc/validate/schematron/rules/release_format_check.rb +7 -4
- data/lib/dcc/validate/schematron/rules/schema_version_check.rb +13 -9
- data/lib/dcc/validate/schematron/rules/uncertainty_consistency.rb +39 -10
- data/lib/dcc/validate/schematron/rules/unit_format_check.rb +2 -3
- data/lib/dcc/validate/schematron/rules/used_methods_placement.rb +15 -10
- data/lib/dcc/validate/schematron/rules/used_software_placement.rb +15 -10
- data/lib/dcc/validate/schematron/rules/xml_list_spacing.rb +4 -3
- data/lib/dcc/validate/schematron/rules.rb +28 -14
- data/lib/dcc/validate/schematron.rb +1 -1
- data/lib/dcc/validate/xsd.rb +9 -3
- data/lib/dcc/validate.rb +1 -1
- data/lib/dcc/version.rb +1 -1
- data/lib/dcc/versioned_parser.rb +1 -1
- data/lib/dcc.rb +55 -7
- data/sample_dcc.xml +140 -0
- data/web/index.html +12 -0
- data/web/package-lock.json +1599 -0
- data/web/package.json +22 -0
- data/web/src/App.vue +349 -0
- data/web/src/lib/builder.ts +171 -0
- data/web/src/lib/dcc.ts +338 -0
- data/web/src/lib/units.json +5581 -0
- data/web/src/main.ts +5 -0
- data/web/src/style.css +27 -0
- data/web/tsconfig.json +15 -0
- data/web/vite.config.ts +14 -0
- metadata +125 -9
|
@@ -1,19 +1,86 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bigdecimal"
|
|
4
|
+
require "forwardable"
|
|
4
5
|
require "lutaml/model"
|
|
5
6
|
|
|
6
7
|
module Dcc
|
|
7
8
|
module Type
|
|
8
9
|
# Space-separated list of decimals, as used by D-SI `*XMLList` elements
|
|
9
10
|
# (e.g. `<si:valueXMLList>306 373 448</si:valueXMLList>`). Parses to/from
|
|
10
|
-
#
|
|
11
|
+
# a `Values` list of BigDecimal.
|
|
12
|
+
#
|
|
13
|
+
# `cast` deliberately does not return a plain Array: lutaml-model treats an
|
|
14
|
+
# Array-valued attribute as a collection and would emit one element per
|
|
15
|
+
# decimal instead of a single space-separated list.
|
|
11
16
|
class DecimalXmlList < Lutaml::Model::Type::Value
|
|
17
|
+
# An ordered list of BigDecimals that renders as space-separated text and
|
|
18
|
+
# compares equal to the equivalent Array.
|
|
19
|
+
class Values
|
|
20
|
+
include Enumerable
|
|
21
|
+
extend Forwardable
|
|
22
|
+
|
|
23
|
+
def_delegators :@decimals, :size, :length, :empty?, :last, :[]
|
|
24
|
+
|
|
25
|
+
def initialize(decimals)
|
|
26
|
+
@decimals = decimals
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def each(&)
|
|
30
|
+
return to_enum(:each) unless block_given?
|
|
31
|
+
|
|
32
|
+
@decimals.each(&)
|
|
33
|
+
self
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Implicit conversion, so `Array#==` delegates back here instead of
|
|
37
|
+
# returning false and making equality asymmetric.
|
|
38
|
+
def to_ary
|
|
39
|
+
@decimals.dup
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Joined over the serialized decimals, not the raw BigDecimals, so it
|
|
43
|
+
# cannot disagree with `to_s` by emitting "0.72e-1" for "0.072".
|
|
44
|
+
def join(separator = " ")
|
|
45
|
+
map { |decimal| DecimalXmlList.serialize_one(decimal) }.join(separator)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def to_s
|
|
49
|
+
DecimalXmlList.serialize(self)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Dumped as its wire form, so YAML matches JSON rather than leaking a
|
|
53
|
+
# `!ruby/object:` tag that `safe_load` refuses to read back.
|
|
54
|
+
def encode_with(coder)
|
|
55
|
+
coder.represent_scalar(nil, to_s)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def ==(other)
|
|
59
|
+
case other
|
|
60
|
+
when Values then to_a == other.to_a
|
|
61
|
+
when ::Array then to_a == other
|
|
62
|
+
else false
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Stricter than `==`, which accepts a plain Array. Hash lookup pairs
|
|
67
|
+
# `eql?` with `hash`, and an Array keyed alongside us would hash the
|
|
68
|
+
# same while comparing equal in only one direction.
|
|
69
|
+
def eql?(other)
|
|
70
|
+
other.is_a?(Values) && to_a == other.to_a
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def hash
|
|
74
|
+
to_a.hash
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
12
78
|
def self.cast(value)
|
|
13
|
-
return
|
|
14
|
-
return
|
|
79
|
+
return value if value.is_a?(Values)
|
|
80
|
+
return Values.new([]) if value.nil?
|
|
15
81
|
|
|
16
|
-
value.
|
|
82
|
+
tokens = value.is_a?(::Array) ? value : value.to_s.split
|
|
83
|
+
Values.new(tokens.map { |token| cast_one(token) })
|
|
17
84
|
end
|
|
18
85
|
|
|
19
86
|
def self.serialize(value)
|
|
@@ -22,24 +89,43 @@ module Dcc
|
|
|
22
89
|
Array(value).map { |v| serialize_one(v) }.join(" ")
|
|
23
90
|
end
|
|
24
91
|
|
|
92
|
+
# One decimal in the notation D-SI writes, e.g. 0.072 rather than
|
|
93
|
+
# BigDecimal's own "0.72e-1". `to_s("F")` renders every BigDecimal,
|
|
94
|
+
# finite or not, and `sub` only trims a trailing ".0". That is what
|
|
95
|
+
# lets `NaN` through, which D-SI admits in every decimal type
|
|
96
|
+
# (SI_Format.xsd:1195).
|
|
97
|
+
def self.serialize_one(value)
|
|
98
|
+
reject_infinite!(value)
|
|
99
|
+
|
|
100
|
+
case value
|
|
101
|
+
when ::BigDecimal then value.to_s("F").sub(/\.0\z/, "")
|
|
102
|
+
when ::Float then format("%.15g", value)
|
|
103
|
+
else value.to_s
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
25
107
|
class << self
|
|
26
108
|
private
|
|
27
109
|
|
|
28
110
|
def cast_one(token)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
111
|
+
decimal = token.is_a?(::BigDecimal) ? token : BigDecimal(token.to_s)
|
|
112
|
+
reject_infinite!(decimal)
|
|
113
|
+
decimal
|
|
32
114
|
rescue ::ArgumentError => e
|
|
33
115
|
raise Lutaml::Model::Type::InvalidValueError.new(token,
|
|
34
116
|
"invalid decimal in XML list: #{e.message}")
|
|
35
117
|
end
|
|
36
118
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
119
|
+
# Called from `cast_one` and from the public `serialize_one`, since
|
|
120
|
+
# `serialize` takes a raw BigDecimal and casting is not the only way in.
|
|
121
|
+
def reject_infinite!(value)
|
|
122
|
+
return unless value.is_a?(::BigDecimal) && value.infinite?
|
|
123
|
+
|
|
124
|
+
raise Lutaml::Model::Type::InvalidValueError.new(
|
|
125
|
+
value,
|
|
126
|
+
"infinity is not a D-SI decimal: SI_Format.xsd:1195 admits " \
|
|
127
|
+
"numbers and NaN only",
|
|
128
|
+
)
|
|
43
129
|
end
|
|
44
130
|
end
|
|
45
131
|
end
|
|
@@ -7,13 +7,14 @@ module Dcc
|
|
|
7
7
|
# ISO 3166-1 alpha-2 country code (two uppercase letters, e.g. `"DE"`).
|
|
8
8
|
# Used by `dcc:countryCodeISO3166_1`.
|
|
9
9
|
class IsoCountryCode < Lutaml::Model::Type::String
|
|
10
|
-
PATTERN = /\A[A-Z]{2}\z
|
|
10
|
+
PATTERN = /\A[A-Z]{2}\z/
|
|
11
11
|
|
|
12
12
|
def self.cast(value)
|
|
13
13
|
return nil unless value.is_a?(::String) && value != ""
|
|
14
14
|
|
|
15
15
|
unless PATTERN.match?(value)
|
|
16
|
-
raise Lutaml::Model::Type::InvalidValueError.new(value,
|
|
16
|
+
raise Lutaml::Model::Type::InvalidValueError.new(value,
|
|
17
|
+
"invalid ISO 3166-1 alpha-2 country code: #{value.inspect}")
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
value
|
|
@@ -7,13 +7,14 @@ module Dcc
|
|
|
7
7
|
# ISO 639-1 language code (two lowercase letters, e.g. `"en"`).
|
|
8
8
|
# Used by `dcc:usedLangCodeISO639_1` and `dcc:mandatoryLangCodeISO639_1`.
|
|
9
9
|
class IsoLanguageCode < Lutaml::Model::Type::String
|
|
10
|
-
PATTERN = /\A[a-z]{2}\z
|
|
10
|
+
PATTERN = /\A[a-z]{2}\z/
|
|
11
11
|
|
|
12
12
|
def self.cast(value)
|
|
13
13
|
return nil unless value.is_a?(::String) && value != ""
|
|
14
14
|
|
|
15
15
|
unless PATTERN.match?(value)
|
|
16
|
-
raise Lutaml::Model::Type::InvalidValueError.new(value,
|
|
16
|
+
raise Lutaml::Model::Type::InvalidValueError.new(value,
|
|
17
|
+
"invalid ISO 639-1 language code: #{value.inspect}")
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
value
|
|
@@ -12,13 +12,14 @@ module Dcc
|
|
|
12
12
|
(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)
|
|
13
13
|
(?:-(?<pre>[0-9A-Za-z.-]+))?
|
|
14
14
|
(?:\+(?<build>[0-9A-Za-z.-]+))?
|
|
15
|
-
\z/x
|
|
15
|
+
\z/x
|
|
16
16
|
|
|
17
17
|
def self.cast(value)
|
|
18
18
|
return nil unless value.is_a?(::String) && value != ""
|
|
19
19
|
|
|
20
20
|
unless PATTERN.match?(value)
|
|
21
|
-
raise Lutaml::Model::Type::InvalidValueError.new(value,
|
|
21
|
+
raise Lutaml::Model::Type::InvalidValueError.new(value,
|
|
22
|
+
"invalid schemaVersion")
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
value
|
data/lib/dcc/type/si_unit.rb
CHANGED
|
@@ -10,13 +10,14 @@ module Dcc
|
|
|
10
10
|
# check: the string must not contain whitespace (Schematron rule), and the
|
|
11
11
|
# non-SI declaration prefix (`|unit`) is allowed.
|
|
12
12
|
class SiUnit < Lutaml::Model::Type::String
|
|
13
|
-
NO_WHITESPACE_PATTERN = /\A\S+\z
|
|
13
|
+
NO_WHITESPACE_PATTERN = /\A\S+\z/
|
|
14
14
|
|
|
15
15
|
def self.cast(value)
|
|
16
16
|
return nil unless value.is_a?(::String) && value != ""
|
|
17
17
|
|
|
18
18
|
unless NO_WHITESPACE_PATTERN.match?(value)
|
|
19
|
-
raise Lutaml::Model::Type::InvalidValueError.new(value,
|
|
19
|
+
raise Lutaml::Model::Type::InvalidValueError.new(value,
|
|
20
|
+
"invalid SI unit expression (whitespace not allowed): #{value.inspect}")
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
value
|
data/lib/dcc/type_guards.rb
CHANGED
|
@@ -130,11 +130,11 @@ module Dcc
|
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
# Safe method call: invokes the method if the node's class declares it.
|
|
133
|
-
def call_if_present(node, method_name, *
|
|
133
|
+
def call_if_present(node, method_name, *)
|
|
134
134
|
return nil unless node.is_a?(::Lutaml::Model::Serializable)
|
|
135
135
|
return nil unless node.class.attributes.key?(method_name)
|
|
136
136
|
|
|
137
|
-
node.public_send(method_name, *
|
|
137
|
+
node.public_send(method_name, *)
|
|
138
138
|
end
|
|
139
139
|
end
|
|
140
|
-
end
|
|
140
|
+
end
|
|
@@ -4,5 +4,6 @@ module Dcc::V2
|
|
|
4
4
|
class CalibrationLaboratory < CommonElements
|
|
5
5
|
include ::Dcc::Base::CalibrationLaboratory
|
|
6
6
|
end
|
|
7
|
-
Configuration.register_model(CalibrationLaboratory,
|
|
7
|
+
Configuration.register_model(CalibrationLaboratory,
|
|
8
|
+
id: :calibrationLaboratory)
|
|
8
9
|
end
|
data/lib/dcc/v2/condition.rb
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Dcc::V2
|
|
4
|
+
# v2 calls the influence condition's state element `state`; v3 renamed it to
|
|
5
|
+
# `status`, which the shared base module carries.
|
|
4
6
|
class Condition < CommonElements
|
|
5
|
-
|
|
7
|
+
attribute :id, :string
|
|
8
|
+
attribute :ref_id, :string
|
|
9
|
+
attribute :ref_type, :string
|
|
10
|
+
attribute :name, :text
|
|
11
|
+
attribute :description, :text
|
|
12
|
+
attribute :status, :string
|
|
13
|
+
attribute :data, :data, collection: true
|
|
14
|
+
|
|
15
|
+
xml do
|
|
16
|
+
namespace ::Dcc::Namespace::Dcc
|
|
17
|
+
element "influenceCondition"
|
|
18
|
+
ordered
|
|
19
|
+
map_attribute "id", to: :id
|
|
20
|
+
map_attribute "refId", to: :ref_id
|
|
21
|
+
map_attribute "refType", to: :ref_type
|
|
22
|
+
map_element "name", to: :name
|
|
23
|
+
map_element "description", to: :description
|
|
24
|
+
map_element "state", to: :status
|
|
25
|
+
map_element "data", to: :data
|
|
26
|
+
end
|
|
6
27
|
end
|
|
7
28
|
Configuration.register_model(Condition, id: :influenceCondition)
|
|
8
29
|
end
|
data/lib/dcc/v2/configuration.rb
CHANGED
|
@@ -4,5 +4,6 @@ module Dcc::V2
|
|
|
4
4
|
class DigitalCalibrationCertificate < CommonElements
|
|
5
5
|
include ::Dcc::Base::DigitalCalibrationCertificate
|
|
6
6
|
end
|
|
7
|
-
Configuration.register_model(DigitalCalibrationCertificate,
|
|
7
|
+
Configuration.register_model(DigitalCalibrationCertificate,
|
|
8
|
+
id: :digitalCalibrationCertificate)
|
|
8
9
|
end
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Dcc::V2
|
|
4
|
+
# v2 calls the identification's third child `description`; v3 renamed it to
|
|
5
|
+
# `name`, which the shared base module carries.
|
|
4
6
|
class Identification < CommonElements
|
|
5
|
-
|
|
7
|
+
attribute :issuer, :string
|
|
8
|
+
attribute :value, :string
|
|
9
|
+
attribute :description, :text
|
|
10
|
+
|
|
11
|
+
xml do
|
|
12
|
+
namespace ::Dcc::Namespace::Dcc
|
|
13
|
+
element "identification"
|
|
14
|
+
ordered
|
|
15
|
+
map_element "issuer", to: :issuer
|
|
16
|
+
map_element "value", to: :value
|
|
17
|
+
map_element "description", to: :description
|
|
18
|
+
end
|
|
6
19
|
end
|
|
7
20
|
Configuration.register_model(Identification, id: :identification)
|
|
8
21
|
end
|
|
@@ -4,5 +4,6 @@ module Dcc::V2
|
|
|
4
4
|
class MeasurementMetaDataList < CommonElements
|
|
5
5
|
include ::Dcc::Base::MeasurementMetaDataList
|
|
6
6
|
end
|
|
7
|
-
Configuration.register_model(MeasurementMetaDataList,
|
|
7
|
+
Configuration.register_model(MeasurementMetaDataList,
|
|
8
|
+
id: :measurementMetaData)
|
|
8
9
|
end
|
data/lib/dcc/v2/quantity.rb
CHANGED
|
@@ -19,8 +19,10 @@ module Dcc::V2
|
|
|
19
19
|
attribute :complex, ::Dcc::Si::V1::Complex, collection: true
|
|
20
20
|
attribute :constant, ::Dcc::Si::V1::Constant, collection: true
|
|
21
21
|
attribute :hybrid, ::Dcc::Si::V1::Hybrid, collection: true
|
|
22
|
-
attribute :real_list_xml_list, ::Dcc::Si::V1::RealListXmlList,
|
|
23
|
-
|
|
22
|
+
attribute :real_list_xml_list, ::Dcc::Si::V1::RealListXmlList,
|
|
23
|
+
collection: true
|
|
24
|
+
attribute :complex_list_xml_list, ::Dcc::Si::V1::ComplexListXmlList,
|
|
25
|
+
collection: true
|
|
24
26
|
attribute :list, ::Dcc::Si::V1::SiList, collection: true
|
|
25
27
|
|
|
26
28
|
xml do
|
data/lib/dcc/v2.rb
CHANGED
|
@@ -14,6 +14,7 @@ module Dcc
|
|
|
14
14
|
autoload :Text, "dcc/v2/text"
|
|
15
15
|
autoload :ByteData, "dcc/v2/byte_data"
|
|
16
16
|
autoload :Formula, "dcc/v2/formula"
|
|
17
|
+
autoload :Mathml, "dcc/v2/mathml"
|
|
17
18
|
autoload :RichContent, "dcc/v2/rich_content"
|
|
18
19
|
autoload :XmlBlob, "dcc/v2/xml_blob"
|
|
19
20
|
autoload :Comment, "dcc/v2/comment"
|
|
@@ -53,14 +54,15 @@ module Dcc
|
|
|
53
54
|
autoload :MeasurementResult, "dcc/v2/measurement_result"
|
|
54
55
|
autoload :MeasurementResultList, "dcc/v2/measurement_result_list"
|
|
55
56
|
autoload :AdministrativeData, "dcc/v2/administrative_data"
|
|
56
|
-
autoload :DigitalCalibrationCertificate,
|
|
57
|
+
autoload :DigitalCalibrationCertificate,
|
|
58
|
+
"dcc/v2/digital_calibration_certificate"
|
|
57
59
|
|
|
58
60
|
ROOT_ELEMENT_TAG = "digitalCalibrationCertificate"
|
|
59
61
|
|
|
60
62
|
extend ::Dcc::VersionedParser
|
|
61
63
|
|
|
62
64
|
ELEMENT_CLASSES = %i[
|
|
63
|
-
StringWithLang Text ByteData Formula RichContent XmlBlob Comment
|
|
65
|
+
StringWithLang Text ByteData Mathml Formula RichContent XmlBlob Comment
|
|
64
66
|
EquipmentClass Location Contact ContactNotStrict HashType
|
|
65
67
|
Identification Identifications Software SoftwareList
|
|
66
68
|
RefTypeDefinition RefTypeDefinitionList
|
|
@@ -4,5 +4,6 @@ module Dcc::V3
|
|
|
4
4
|
class CalibrationLaboratory < CommonElements
|
|
5
5
|
include ::Dcc::Base::CalibrationLaboratory
|
|
6
6
|
end
|
|
7
|
-
Configuration.register_model(CalibrationLaboratory,
|
|
7
|
+
Configuration.register_model(CalibrationLaboratory,
|
|
8
|
+
id: :calibrationLaboratory)
|
|
8
9
|
end
|
data/lib/dcc/v3/configuration.rb
CHANGED
|
@@ -4,5 +4,6 @@ module Dcc::V3
|
|
|
4
4
|
class DigitalCalibrationCertificate < CommonElements
|
|
5
5
|
include ::Dcc::Base::DigitalCalibrationCertificate
|
|
6
6
|
end
|
|
7
|
-
Configuration.register_model(DigitalCalibrationCertificate,
|
|
7
|
+
Configuration.register_model(DigitalCalibrationCertificate,
|
|
8
|
+
id: :digitalCalibrationCertificate)
|
|
8
9
|
end
|
|
@@ -4,5 +4,6 @@ module Dcc::V3
|
|
|
4
4
|
class MeasurementMetaDataList < CommonElements
|
|
5
5
|
include ::Dcc::Base::MeasurementMetaDataList
|
|
6
6
|
end
|
|
7
|
-
Configuration.register_model(MeasurementMetaDataList,
|
|
7
|
+
Configuration.register_model(MeasurementMetaDataList,
|
|
8
|
+
id: :measurementMetaData)
|
|
8
9
|
end
|
data/lib/dcc/v3/quantity.rb
CHANGED
|
@@ -19,8 +19,10 @@ module Dcc::V3
|
|
|
19
19
|
attribute :complex, ::Dcc::Si::V2::Complex, collection: true
|
|
20
20
|
attribute :constant, ::Dcc::Si::V2::Constant, collection: true
|
|
21
21
|
attribute :hybrid, ::Dcc::Si::V2::Hybrid, collection: true
|
|
22
|
-
attribute :real_list_xml_list, ::Dcc::Si::V2::RealListXmlList,
|
|
23
|
-
|
|
22
|
+
attribute :real_list_xml_list, ::Dcc::Si::V2::RealListXmlList,
|
|
23
|
+
collection: true
|
|
24
|
+
attribute :complex_list_xml_list, ::Dcc::Si::V2::ComplexListXmlList,
|
|
25
|
+
collection: true
|
|
24
26
|
attribute :list, ::Dcc::Si::V2::SiList, collection: true
|
|
25
27
|
|
|
26
28
|
xml do
|
data/lib/dcc/v3.rb
CHANGED
|
@@ -14,6 +14,7 @@ module Dcc
|
|
|
14
14
|
autoload :Text, "dcc/v3/text"
|
|
15
15
|
autoload :ByteData, "dcc/v3/byte_data"
|
|
16
16
|
autoload :Formula, "dcc/v3/formula"
|
|
17
|
+
autoload :Mathml, "dcc/v3/mathml"
|
|
17
18
|
autoload :RichContent, "dcc/v3/rich_content"
|
|
18
19
|
autoload :XmlBlob, "dcc/v3/xml_blob"
|
|
19
20
|
autoload :Comment, "dcc/v3/comment"
|
|
@@ -53,7 +54,8 @@ module Dcc
|
|
|
53
54
|
autoload :MeasurementResult, "dcc/v3/measurement_result"
|
|
54
55
|
autoload :MeasurementResultList, "dcc/v3/measurement_result_list"
|
|
55
56
|
autoload :AdministrativeData, "dcc/v3/administrative_data"
|
|
56
|
-
autoload :DigitalCalibrationCertificate,
|
|
57
|
+
autoload :DigitalCalibrationCertificate,
|
|
58
|
+
"dcc/v3/digital_calibration_certificate"
|
|
57
59
|
|
|
58
60
|
ROOT_ELEMENT_TAG = "digitalCalibrationCertificate"
|
|
59
61
|
|
|
@@ -63,7 +65,7 @@ module Dcc
|
|
|
63
65
|
# `Configuration.populate_context!` can register them. Iterating
|
|
64
66
|
# `constants` triggers each autoload lazily.
|
|
65
67
|
ELEMENT_CLASSES = %i[
|
|
66
|
-
StringWithLang Text ByteData Formula RichContent XmlBlob Comment
|
|
68
|
+
StringWithLang Text ByteData Mathml Formula RichContent XmlBlob Comment
|
|
67
69
|
EquipmentClass Location Contact ContactNotStrict HashType
|
|
68
70
|
Identification Identifications Software SoftwareList
|
|
69
71
|
RefTypeDefinition RefTypeDefinitionList
|
|
@@ -90,9 +92,17 @@ module Dcc
|
|
|
90
92
|
|
|
91
93
|
# Re-export D-SI v2 type registrations into the DCC v3 context. Uses
|
|
92
94
|
# only the public `register_model` API (no instance_variable access).
|
|
95
|
+
#
|
|
96
|
+
# Ids DCC already owns are skipped: `register_model` overwrites on
|
|
97
|
+
# duplicate, and both DCC and D-SI define a `list` element, so without this
|
|
98
|
+
# the D-SI one would displace `Dcc::V3::List` and every `dcc:list` would
|
|
99
|
+
# parse as an empty `si:list`.
|
|
93
100
|
def self.register_dsi_types!
|
|
94
101
|
::Dcc::Si::V2.load_all!
|
|
102
|
+
own_ids = Configuration.registered_model_ids
|
|
95
103
|
::Dcc::Si::V2::Configuration.registered_model_ids.each do |id|
|
|
104
|
+
next if own_ids.include?(id)
|
|
105
|
+
|
|
96
106
|
klass = ::Dcc::Si::V2::Configuration.registered_model_class(id)
|
|
97
107
|
Configuration.register_model(klass, id: id)
|
|
98
108
|
end
|
|
@@ -43,7 +43,9 @@ module Dcc
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def code
|
|
46
|
-
"dcc.business_rule.#{self.class.name.split('::').last.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(
|
|
46
|
+
"dcc.business_rule.#{self.class.name.split('::').last.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(
|
|
47
|
+
/([a-z\d])([A-Z])/, '\1_\2'
|
|
48
|
+
).downcase}"
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
# @param _dcc [Lutaml::Model::Serializable]
|
|
@@ -68,10 +70,12 @@ module Dcc
|
|
|
68
70
|
# Require exactly one respPerson with mainSigner = true.
|
|
69
71
|
class MainSignerSingle < Rule
|
|
70
72
|
def check_on(dcc)
|
|
71
|
-
return [] unless Dcc::TypeGuards.has_attribute?(dcc,
|
|
73
|
+
return [] unless Dcc::TypeGuards.has_attribute?(dcc,
|
|
74
|
+
:administrative_data)
|
|
72
75
|
|
|
73
76
|
admin = dcc.administrative_data
|
|
74
|
-
return [] unless admin && Dcc::TypeGuards.has_attribute?(admin,
|
|
77
|
+
return [] unless admin && Dcc::TypeGuards.has_attribute?(admin,
|
|
78
|
+
:resp_persons) && admin.resp_persons
|
|
75
79
|
|
|
76
80
|
resp_persons = Array(admin.resp_persons.resp_person)
|
|
77
81
|
main_signers = resp_persons.select { |p| Dcc::TypeGuards.has_attribute?(p, :main_signer) && p.main_signer }
|
|
@@ -89,15 +93,20 @@ module Dcc
|
|
|
89
93
|
# Require non-empty uniqueIdentifier.
|
|
90
94
|
class UniqueIdentifierPresent < Rule
|
|
91
95
|
def check_on(dcc)
|
|
92
|
-
return [] unless Dcc::TypeGuards.has_attribute?(dcc,
|
|
96
|
+
return [] unless Dcc::TypeGuards.has_attribute?(dcc,
|
|
97
|
+
:administrative_data)
|
|
93
98
|
|
|
94
99
|
core = dcc.administrative_data&.core_data
|
|
95
|
-
|
|
100
|
+
unless core
|
|
101
|
+
return [issue(severity: :error,
|
|
102
|
+
message: "coreData is missing")]
|
|
103
|
+
end
|
|
96
104
|
|
|
97
105
|
id = core.unique_identifier
|
|
98
106
|
return [] if id && !id.to_s.empty?
|
|
99
107
|
|
|
100
|
-
[issue(severity: :error,
|
|
108
|
+
[issue(severity: :error,
|
|
109
|
+
message: "uniqueIdentifier is missing or empty")]
|
|
101
110
|
end
|
|
102
111
|
end
|
|
103
112
|
|
|
@@ -108,14 +117,19 @@ module Dcc
|
|
|
108
117
|
# @param dcc [Lutaml::Model::Serializable]
|
|
109
118
|
# @return [Dcc::Validate::BusinessRules::Result]
|
|
110
119
|
def call(dcc)
|
|
111
|
-
issues = Registry.all.flat_map
|
|
120
|
+
issues = Registry.all.flat_map do |rule_class|
|
|
121
|
+
rule_class.new.check_on(dcc)
|
|
122
|
+
end
|
|
112
123
|
Result.new(
|
|
113
124
|
issues: issues,
|
|
114
|
-
schema_version: Dcc::TypeGuards.has_attribute?(dcc,
|
|
125
|
+
schema_version: if Dcc::TypeGuards.has_attribute?(dcc,
|
|
126
|
+
:schema_version)
|
|
127
|
+
dcc.schema_version.to_s
|
|
128
|
+
end,
|
|
115
129
|
source: "business_rule",
|
|
116
130
|
)
|
|
117
131
|
end
|
|
118
132
|
end
|
|
119
133
|
end
|
|
120
134
|
end
|
|
121
|
-
end
|
|
135
|
+
end
|
data/lib/dcc/validate/issue.rb
CHANGED
|
@@ -24,7 +24,8 @@ module Dcc
|
|
|
24
24
|
# @param column [Integer, nil] XML column number if known.
|
|
25
25
|
# @param path [String, nil] XPath / element path if known.
|
|
26
26
|
# @param source [String, nil] validator name (e.g. "xsd", "schematron").
|
|
27
|
-
def self.build(severity:, message:, code: nil, line: nil, column: nil,
|
|
27
|
+
def self.build(severity:, message:, code: nil, line: nil, column: nil,
|
|
28
|
+
path: nil, source: nil)
|
|
28
29
|
new(
|
|
29
30
|
severity: ::Dcc::Validate::Severity.normalize(severity),
|
|
30
31
|
message: message,
|
data/lib/dcc/validate/result.rb
CHANGED
|
@@ -58,12 +58,12 @@ module Dcc
|
|
|
58
58
|
|
|
59
59
|
def to_s
|
|
60
60
|
if ok?
|
|
61
|
-
"OK: no errors found#{
|
|
61
|
+
"OK: no errors found#{" (schemaVersion #{schema_version})" if schema_version}"
|
|
62
62
|
else
|
|
63
63
|
header = "#{errors.size} error(s), #{warnings.size} warning(s)"
|
|
64
64
|
header += " (schemaVersion #{schema_version})" if schema_version
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
errors.map(&:to_s).unshift(header).join("\n")
|
|
66
|
+
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
|
|
@@ -97,7 +97,9 @@ module Dcc
|
|
|
97
97
|
ok: ok?,
|
|
98
98
|
source: source,
|
|
99
99
|
schema_version: schema_version,
|
|
100
|
-
issues: issues.map
|
|
100
|
+
issues: issues.map do |i|
|
|
101
|
+
[i.severity.to_s, i.message, i.line, i.path]
|
|
102
|
+
end,
|
|
101
103
|
}.to_yaml
|
|
102
104
|
end
|
|
103
105
|
end
|