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.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +19 -0
  3. data/.github/workflows/release.yml +28 -0
  4. data/.gitignore +4 -0
  5. data/.rubocop_todo.yml +560 -10
  6. data/CHANGELOG.adoc +34 -1
  7. data/CONTRIBUTING.adoc +8 -1
  8. data/Gemfile +5 -7
  9. data/README.adoc +162 -7
  10. data/dcc.gemspec +8 -2
  11. data/docs/schema-versions.adoc +20 -7
  12. data/examples/build_minimal_dcc.rb +0 -0
  13. data/examples/convert_all_formats.rb +2 -1
  14. data/examples/parse_and_inspect.rb +0 -0
  15. data/examples/quantity_math_demo.rb +7 -7
  16. data/examples/validate_full.rb +1 -1
  17. data/lib/dcc/base/calibration_laboratory.rb +2 -1
  18. data/lib/dcc/base/condition.rb +5 -2
  19. data/lib/dcc/base/core_data.rb +8 -3
  20. data/lib/dcc/base/formula.rb +3 -3
  21. data/lib/dcc/base/identification.rb +6 -3
  22. data/lib/dcc/base/mathml.rb +33 -0
  23. data/lib/dcc/base/quantity.rb +2 -1
  24. data/lib/dcc/base/resp_person.rb +4 -2
  25. data/lib/dcc/base/text.rb +1 -1
  26. data/lib/dcc/base.rb +2 -1
  27. data/lib/dcc/builder/dsl.rb +1 -1
  28. data/lib/dcc/builder/session.rb +16 -14
  29. data/lib/dcc/builder.rb +3 -3
  30. data/lib/dcc/cli/cli.rb +36 -18
  31. data/lib/dcc/cli/formatters.rb +35 -7
  32. data/lib/dcc/cli.rb +1 -1
  33. data/lib/dcc/context_configuration.rb +2 -1
  34. data/lib/dcc/context_options.rb +4 -2
  35. data/lib/dcc/convert/csv.rb +27 -9
  36. data/lib/dcc/convert/html.rb +26 -110
  37. data/lib/dcc/convert/json.rb +10 -7
  38. data/lib/dcc/convert/liquid_filters.rb +58 -0
  39. data/lib/dcc/convert/result.rb +1 -1
  40. data/lib/dcc/convert/templates/report.liquid +250 -0
  41. data/lib/dcc/convert/yaml.rb +1 -1
  42. data/lib/dcc/convert.rb +1 -0
  43. data/lib/dcc/diff/change.rb +1 -1
  44. data/lib/dcc/diff/result.rb +8 -4
  45. data/lib/dcc/diff.rb +43 -11
  46. data/lib/dcc/error.rb +7 -0
  47. data/lib/dcc/extract/file.rb +3 -4
  48. data/lib/dcc/extract/ring.rb +1 -1
  49. data/lib/dcc/extract.rb +1 -1
  50. data/lib/dcc/i18n/text_lookup.rb +8 -4
  51. data/lib/dcc/i18n.rb +1 -1
  52. data/lib/dcc/inspect/report.rb +51 -14
  53. data/lib/dcc/inspect.rb +1 -1
  54. data/lib/dcc/migrate/route.rb +44 -0
  55. data/lib/dcc/migrate/v2_to_v3.rb +445 -0
  56. data/lib/dcc/migrate.rb +130 -26
  57. data/lib/dcc/plugin/base.rb +64 -0
  58. data/lib/dcc/plugin/registry.rb +7 -2
  59. data/lib/dcc/plugin.rb +6 -2
  60. data/lib/dcc/quantity_format/formatter.rb +16 -10
  61. data/lib/dcc/quantity_format.rb +1 -1
  62. data/lib/dcc/quantity_math/quantity.rb +1 -1
  63. data/lib/dcc/quantity_math/real.rb +6 -6
  64. data/lib/dcc/quantity_math.rb +1 -1
  65. data/lib/dcc/schema/version.rb +2 -2
  66. data/lib/dcc/server/app.html +282 -0
  67. data/lib/dcc/server/app.rb +171 -87
  68. data/lib/dcc/server/demo_cert.xml +244 -0
  69. data/lib/dcc/server/storage/entry.rb +1 -1
  70. data/lib/dcc/server/storage/memory.rb +3 -2
  71. data/lib/dcc/server/storage.rb +1 -1
  72. data/lib/dcc/server.rb +1 -1
  73. data/lib/dcc/si/base/complex.rb +1 -1
  74. data/lib/dcc/si/base/complex_list_xml_list.rb +1 -1
  75. data/lib/dcc/si/base/constant.rb +1 -1
  76. data/lib/dcc/si/base/coverage_interval.rb +36 -0
  77. data/lib/dcc/si/base/coverage_interval_mu.rb +1 -1
  78. data/lib/dcc/si/base/expanded_mu.rb +1 -1
  79. data/lib/dcc/si/base/expanded_unc.rb +34 -0
  80. data/lib/dcc/si/base/expanded_unc_xml_list.rb +3 -2
  81. data/lib/dcc/si/base/hybrid.rb +3 -2
  82. data/lib/dcc/si/base/measurement_uncertainty_univariate.rb +1 -1
  83. data/lib/dcc/si/base/real.rb +13 -3
  84. data/lib/dcc/si/base/real_list_xml_list.rb +5 -3
  85. data/lib/dcc/si/base/si_list.rb +3 -2
  86. data/lib/dcc/si/base/standard_mu.rb +1 -1
  87. data/lib/dcc/si/base.rb +5 -2
  88. data/lib/dcc/si/v1/coverage_interval.rb +8 -0
  89. data/lib/dcc/si/v1/expanded_unc.rb +1 -16
  90. data/lib/dcc/si/v1/measurement_uncertainty_univariate.rb +2 -1
  91. data/lib/dcc/si/v1.rb +5 -2
  92. data/lib/dcc/si/v2/coverage_interval.rb +8 -0
  93. data/lib/dcc/si/v2/coverage_interval_mu_xml_list.rb +4 -2
  94. data/lib/dcc/si/v2/expanded_mu_xml_list.rb +2 -1
  95. data/lib/dcc/si/v2/expanded_unc.rb +8 -0
  96. data/lib/dcc/si/v2/measurement_uncertainty_univariate.rb +2 -1
  97. data/lib/dcc/si/v2.rb +8 -3
  98. data/lib/dcc/signature/result.rb +2 -2
  99. data/lib/dcc/signature/signer.rb +31 -18
  100. data/lib/dcc/signature/verifier.rb +23 -21
  101. data/lib/dcc/signature.rb +1 -1
  102. data/lib/dcc/transform/result.rb +1 -1
  103. data/lib/dcc/transform/xslt.rb +22 -12
  104. data/lib/dcc/transform.rb +5 -4
  105. data/lib/dcc/type/base64_binary.rb +5 -3
  106. data/lib/dcc/type/decimal_xml_list.rb +99 -13
  107. data/lib/dcc/type/iso_country_code.rb +3 -2
  108. data/lib/dcc/type/iso_language_code.rb +3 -2
  109. data/lib/dcc/type/schema_version.rb +3 -2
  110. data/lib/dcc/type/si_unit.rb +3 -2
  111. data/lib/dcc/type_guards.rb +3 -3
  112. data/lib/dcc/v2/calibration_laboratory.rb +2 -1
  113. data/lib/dcc/v2/condition.rb +22 -1
  114. data/lib/dcc/v2/configuration.rb +1 -1
  115. data/lib/dcc/v2/digital_calibration_certificate.rb +2 -1
  116. data/lib/dcc/v2/identification.rb +14 -1
  117. data/lib/dcc/v2/mathml.rb +8 -0
  118. data/lib/dcc/v2/measurement_meta_data_list.rb +2 -1
  119. data/lib/dcc/v2/quantity.rb +4 -2
  120. data/lib/dcc/v2.rb +4 -2
  121. data/lib/dcc/v3/calibration_laboratory.rb +2 -1
  122. data/lib/dcc/v3/configuration.rb +1 -1
  123. data/lib/dcc/v3/digital_calibration_certificate.rb +2 -1
  124. data/lib/dcc/v3/mathml.rb +8 -0
  125. data/lib/dcc/v3/measurement_meta_data_list.rb +2 -1
  126. data/lib/dcc/v3/quantity.rb +4 -2
  127. data/lib/dcc/v3.rb +12 -2
  128. data/lib/dcc/validate/business_rules.rb +23 -9
  129. data/lib/dcc/validate/issue.rb +2 -1
  130. data/lib/dcc/validate/result.rb +6 -4
  131. data/lib/dcc/validate/schematron/profile.rb +73 -18
  132. data/lib/dcc/validate/schematron/rule.rb +13 -3
  133. data/lib/dcc/validate/schematron/rules/administrative_data_completeness.rb +11 -4
  134. data/lib/dcc/validate/schematron/rules/base.rb +1 -2
  135. data/lib/dcc/validate/schematron/rules/date_range_check.rb +11 -5
  136. data/lib/dcc/validate/schematron/rules/id_refid_linking.rb +0 -3
  137. data/lib/dcc/validate/schematron/rules/influence_conditions_placement.rb +22 -12
  138. data/lib/dcc/validate/schematron/rules/iso_code_validation.rb +31 -14
  139. data/lib/dcc/validate/schematron/rules/language_code_dedup.rb +12 -5
  140. data/lib/dcc/validate/schematron/rules/non_si_declaration.rb +7 -4
  141. data/lib/dcc/validate/schematron/rules/release_format_check.rb +7 -4
  142. data/lib/dcc/validate/schematron/rules/schema_version_check.rb +13 -9
  143. data/lib/dcc/validate/schematron/rules/uncertainty_consistency.rb +39 -10
  144. data/lib/dcc/validate/schematron/rules/unit_format_check.rb +2 -3
  145. data/lib/dcc/validate/schematron/rules/used_methods_placement.rb +15 -10
  146. data/lib/dcc/validate/schematron/rules/used_software_placement.rb +15 -10
  147. data/lib/dcc/validate/schematron/rules/xml_list_spacing.rb +4 -3
  148. data/lib/dcc/validate/schematron/rules.rb +28 -14
  149. data/lib/dcc/validate/schematron.rb +1 -1
  150. data/lib/dcc/validate/xsd.rb +9 -3
  151. data/lib/dcc/validate.rb +1 -1
  152. data/lib/dcc/version.rb +1 -1
  153. data/lib/dcc/versioned_parser.rb +1 -1
  154. data/lib/dcc.rb +55 -7
  155. data/sample_dcc.xml +140 -0
  156. data/web/index.html +12 -0
  157. data/web/package-lock.json +1599 -0
  158. data/web/package.json +22 -0
  159. data/web/src/App.vue +349 -0
  160. data/web/src/lib/builder.ts +171 -0
  161. data/web/src/lib/dcc.ts +338 -0
  162. data/web/src/lib/units.json +5581 -0
  163. data/web/src/main.ts +5 -0
  164. data/web/src/style.css +27 -0
  165. data/web/tsconfig.json +15 -0
  166. data/web/vite.config.ts +14 -0
  167. metadata +125 -9
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dcc
4
+ module Si
5
+ module Base
6
+ # `si:expandedUncType` — expanded uncertainty stated directly on a real
7
+ # quantity. The v1 form; v2 keeps it as a deprecated alternative to
8
+ # `measurementUncertaintyUnivariate`.
9
+ module ExpandedUnc
10
+ # rubocop:disable Metrics/MethodLength -- one lutaml mapping
11
+ # block, written the same way as every sibling D-SI module.
12
+ def self.included(klass)
13
+ klass.class_eval do
14
+ attribute :uncertainty, :string
15
+ attribute :coverage_factor, :string
16
+ attribute :coverage_probability, :string
17
+ attribute :distribution, :string
18
+
19
+ xml do
20
+ namespace ::Dcc::Namespace::Si
21
+ element "expandedUnc"
22
+ ordered
23
+ map_element "uncertainty", to: :uncertainty
24
+ map_element "coverageFactor", to: :coverage_factor
25
+ map_element "coverageProbability", to: :coverage_probability
26
+ map_element "distribution", to: :distribution
27
+ end
28
+ end
29
+ end
30
+ # rubocop:enable Metrics/MethodLength
31
+ end
32
+ end
33
+ end
34
+ end
@@ -19,7 +19,8 @@ module Dcc
19
19
  ordered
20
20
  map_element "uncertaintyXMLList", to: :uncertainty_xml_list
21
21
  map_element "coverageFactorXMLList", to: :coverage_factor_xml_list
22
- map_element "coverageProbabilityXMLList", to: :coverage_probability_xml_list
22
+ map_element "coverageProbabilityXMLList",
23
+ to: :coverage_probability_xml_list
23
24
  map_element "distributionXMLList", to: :distribution_xml_list
24
25
  end
25
26
  end
@@ -27,4 +28,4 @@ module Dcc
27
28
  end
28
29
  end
29
30
  end
30
- end
31
+ end
@@ -18,7 +18,8 @@ module Dcc
18
18
  attribute :complex, :complex, collection: true
19
19
  attribute :constant, :constant, collection: true
20
20
  attribute :real_list_xml_list, :realListXMLList, collection: true
21
- attribute :complex_list_xml_list, :complexListXMLList, collection: true
21
+ attribute :complex_list_xml_list, :complexListXMLList,
22
+ collection: true
22
23
 
23
24
  xml do
24
25
  namespace ::Dcc::Namespace::Si
@@ -39,4 +40,4 @@ module Dcc
39
40
  end
40
41
  end
41
42
  end
42
- end
43
+ end
@@ -25,4 +25,4 @@ module Dcc
25
25
  end
26
26
  end
27
27
  end
28
- end
28
+ end
@@ -17,6 +17,8 @@ module Dcc
17
17
  # </si:real>
18
18
  module Real
19
19
  def self.included(klass)
20
+ # rubocop:disable Metrics/BlockLength -- one lutaml mapping block,
21
+ # as in the sibling D-SI modules already listed in the todo file.
20
22
  klass.class_eval do
21
23
  attribute :id, :string
22
24
  attribute :ref_type, :string
@@ -25,7 +27,11 @@ module Dcc
25
27
  attribute :unit, ::Dcc::Type::SiUnit
26
28
  attribute :significant_digit, :integer
27
29
  attribute :date_time, :date_time
28
- attribute :measurement_uncertainty_univariate, :measurementUncertaintyUnivariate
30
+ attribute :measurement_uncertainty_univariate,
31
+ :measurementUncertaintyUnivariate
32
+ # Deprecated in v2, but the only uncertainty form v1 documents use.
33
+ attribute :expanded_unc, :expandedUnc
34
+ attribute :coverage_interval, :coverageInterval
29
35
 
30
36
  xml do
31
37
  namespace ::Dcc::Namespace::Si
@@ -38,11 +44,15 @@ module Dcc
38
44
  map_element "unit", to: :unit
39
45
  map_element "significantDigit", to: :significant_digit
40
46
  map_element "dateTime", to: :date_time
41
- map_element "measurementUncertaintyUnivariate", to: :measurement_uncertainty_univariate
47
+ map_element "measurementUncertaintyUnivariate",
48
+ to: :measurement_uncertainty_univariate
49
+ map_element "expandedUnc", to: :expanded_unc
50
+ map_element "coverageInterval", to: :coverage_interval
42
51
  end
43
52
  end
53
+ # rubocop:enable Metrics/BlockLength
44
54
  end
45
55
  end
46
56
  end
47
57
  end
48
- end
58
+ end
@@ -31,15 +31,17 @@ module Dcc
31
31
  map_element "quantityTypeXMLList", to: :quantity_type_xml_list
32
32
  map_element "valueXMLList", to: :value_xml_list
33
33
  map_element "unitXMLList", to: :unit_xml_list
34
- map_element "significantDigitXMLList", to: :significant_digit_xml_list
34
+ map_element "significantDigitXMLList",
35
+ to: :significant_digit_xml_list
35
36
  map_element "dateTimeXMLList", to: :date_time_xml_list
36
37
  map_element "expandedUncXMLList", to: :expanded_unc_xml_list
37
38
  map_element "standardMUXMLList", to: :standard_mu_xml_list
38
- map_element "coverageIntervalMUXMLList", to: :coverage_interval_mu_xml_list
39
+ map_element "coverageIntervalMUXMLList",
40
+ to: :coverage_interval_mu_xml_list
39
41
  end
40
42
  end
41
43
  end
42
44
  end
43
45
  end
44
46
  end
45
- end
47
+ end
@@ -13,7 +13,8 @@ module Dcc
13
13
  attribute :date_time, :date_time
14
14
  attribute :real_list, :real, collection: true
15
15
  attribute :real_list_xml_list, :realListXMLList, collection: true
16
- attribute :complex_list_xml_list, :complexListXMLList, collection: true
16
+ attribute :complex_list_xml_list, :complexListXMLList,
17
+ collection: true
17
18
  attribute :list, :list, collection: true
18
19
 
19
20
  xml do
@@ -34,4 +35,4 @@ module Dcc
34
35
  end
35
36
  end
36
37
  end
37
- end
38
+ end
@@ -22,4 +22,4 @@ module Dcc
22
22
  end
23
23
  end
24
24
  end
25
- end
25
+ end
data/lib/dcc/si/base.rb CHANGED
@@ -17,8 +17,11 @@ module Dcc
17
17
  autoload :StandardMU, "dcc/si/base/standard_mu"
18
18
  autoload :ExpandedMU, "dcc/si/base/expanded_mu"
19
19
  autoload :CoverageIntervalMU, "dcc/si/base/coverage_interval_mu"
20
+ autoload :ExpandedUnc, "dcc/si/base/expanded_unc"
21
+ autoload :CoverageInterval, "dcc/si/base/coverage_interval"
20
22
  autoload :ExpandedUncXmlList, "dcc/si/base/expanded_unc_xml_list"
21
- autoload :MeasurementUncertaintyUnivariate, "dcc/si/base/measurement_uncertainty_univariate"
23
+ autoload :MeasurementUncertaintyUnivariate,
24
+ "dcc/si/base/measurement_uncertainty_univariate"
22
25
  end
23
26
  end
24
- end
27
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dcc::Si::V1
4
+ class CoverageInterval < CommonElements
5
+ include ::Dcc::Si::Base::CoverageInterval
6
+ end
7
+ Configuration.register_model(CoverageInterval, id: :coverageInterval)
8
+ end
@@ -1,23 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dcc::Si::V1
4
- # Deprecated v1 expandedUnc type — superseded by expandedMU in v2.
5
- # Kept so old fixtures parse without losing data.
6
4
  class ExpandedUnc < CommonElements
7
- attribute :uncertainty, :string
8
- attribute :coverage_factor, :string
9
- attribute :coverage_probability, :string
10
- attribute :distribution, :string
11
-
12
- xml do
13
- namespace ::Dcc::Namespace::Si
14
- element "expandedUnc"
15
- ordered
16
- map_element "uncertainty", to: :uncertainty
17
- map_element "coverageFactor", to: :coverage_factor
18
- map_element "coverageProbability", to: :coverage_probability
19
- map_element "distribution", to: :distribution
20
- end
5
+ include ::Dcc::Si::Base::ExpandedUnc
21
6
  end
22
7
  Configuration.register_model(ExpandedUnc, id: :expandedUnc)
23
8
  end
@@ -4,5 +4,6 @@ module Dcc::Si::V1
4
4
  class MeasurementUncertaintyUnivariate < CommonElements
5
5
  include ::Dcc::Si::Base::MeasurementUncertaintyUnivariate
6
6
  end
7
- Configuration.register_model(MeasurementUncertaintyUnivariate, id: :measurementUncertaintyUnivariate)
7
+ Configuration.register_model(MeasurementUncertaintyUnivariate,
8
+ id: :measurementUncertaintyUnivariate)
8
9
  end
data/lib/dcc/si/v1.rb CHANGED
@@ -22,8 +22,10 @@ module Dcc
22
22
  autoload :ExpandedMU, "dcc/si/v1/expanded_mu"
23
23
  autoload :CoverageIntervalMU, "dcc/si/v1/coverage_interval_mu"
24
24
  autoload :ExpandedUnc, "dcc/si/v1/expanded_unc"
25
+ autoload :CoverageInterval, "dcc/si/v1/coverage_interval"
25
26
  autoload :ExpandedUncXmlList, "dcc/si/v1/expanded_unc_xml_list"
26
- autoload :MeasurementUncertaintyUnivariate, "dcc/si/v1/measurement_uncertainty_univariate"
27
+ autoload :MeasurementUncertaintyUnivariate,
28
+ "dcc/si/v1/measurement_uncertainty_univariate"
27
29
 
28
30
  ROOT_ELEMENT_TAG = "real"
29
31
 
@@ -33,7 +35,8 @@ module Dcc
33
35
  Real Complex Constant
34
36
  RealListXmlList ComplexListXmlList Hybrid SiList
35
37
  StandardMU ExpandedMU CoverageIntervalMU
36
- ExpandedUnc ExpandedUncXmlList MeasurementUncertaintyUnivariate
38
+ ExpandedUnc CoverageInterval
39
+ ExpandedUncXmlList MeasurementUncertaintyUnivariate
37
40
  ].freeze
38
41
 
39
42
  def self.load_all!
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dcc::Si::V2
4
+ class CoverageInterval < CommonElements
5
+ include ::Dcc::Si::Base::CoverageInterval
6
+ end
7
+ Configuration.register_model(CoverageInterval, id: :coverageInterval)
8
+ end
@@ -16,9 +16,11 @@ module Dcc::Si::V2
16
16
  map_element "valueStandardMUXMLList", to: :value_standard_mu_xml_list
17
17
  map_element "intervalMinXMLList", to: :interval_min_xml_list
18
18
  map_element "intervalMaxXMLList", to: :interval_max_xml_list
19
- map_element "coverageProbabilityXMLList", to: :coverage_probability_xml_list
19
+ map_element "coverageProbabilityXMLList",
20
+ to: :coverage_probability_xml_list
20
21
  map_element "distributionXMLList", to: :distribution_xml_list
21
22
  end
22
23
  end
23
- Configuration.register_model(CoverageIntervalMUXMLList, id: :coverageIntervalMUXMLList)
24
+ Configuration.register_model(CoverageIntervalMUXMLList,
25
+ id: :coverageIntervalMUXMLList)
24
26
  end
@@ -14,7 +14,8 @@ module Dcc::Si::V2
14
14
  ordered
15
15
  map_element "valueExpandedMUXMLList", to: :value_expanded_mu_xml_list
16
16
  map_element "coverageFactorXMLList", to: :coverage_factor_xml_list
17
- map_element "coverageProbabilityXMLList", to: :coverage_probability_xml_list
17
+ map_element "coverageProbabilityXMLList",
18
+ to: :coverage_probability_xml_list
18
19
  map_element "distributionXMLList", to: :distribution_xml_list
19
20
  end
20
21
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dcc::Si::V2
4
+ class ExpandedUnc < CommonElements
5
+ include ::Dcc::Si::Base::ExpandedUnc
6
+ end
7
+ Configuration.register_model(ExpandedUnc, id: :expandedUnc)
8
+ end
@@ -4,5 +4,6 @@ module Dcc::Si::V2
4
4
  class MeasurementUncertaintyUnivariate < CommonElements
5
5
  include ::Dcc::Si::Base::MeasurementUncertaintyUnivariate
6
6
  end
7
- Configuration.register_model(MeasurementUncertaintyUnivariate, id: :measurementUncertaintyUnivariate)
7
+ Configuration.register_model(MeasurementUncertaintyUnivariate,
8
+ id: :measurementUncertaintyUnivariate)
8
9
  end
data/lib/dcc/si/v2.rb CHANGED
@@ -22,9 +22,13 @@ module Dcc
22
22
  autoload :ExpandedMU, "dcc/si/v2/expanded_mu"
23
23
  autoload :ExpandedMUXMLList, "dcc/si/v2/expanded_mu_xml_list"
24
24
  autoload :CoverageIntervalMU, "dcc/si/v2/coverage_interval_mu"
25
- autoload :CoverageIntervalMUXMLList, "dcc/si/v2/coverage_interval_mu_xml_list"
25
+ autoload :CoverageIntervalMUXMLList,
26
+ "dcc/si/v2/coverage_interval_mu_xml_list"
27
+ autoload :ExpandedUnc, "dcc/si/v2/expanded_unc"
28
+ autoload :CoverageInterval, "dcc/si/v2/coverage_interval"
26
29
  autoload :ExpandedUncXmlList, "dcc/si/v2/expanded_unc_xml_list"
27
- autoload :MeasurementUncertaintyUnivariate, "dcc/si/v2/measurement_uncertainty_univariate"
30
+ autoload :MeasurementUncertaintyUnivariate,
31
+ "dcc/si/v2/measurement_uncertainty_univariate"
28
32
 
29
33
  ROOT_ELEMENT_TAG = "real"
30
34
 
@@ -36,6 +40,7 @@ module Dcc
36
40
  StandardMU StandardMUXMLList
37
41
  ExpandedMU ExpandedMUXMLList
38
42
  CoverageIntervalMU CoverageIntervalMUXMLList
43
+ ExpandedUnc CoverageInterval
39
44
  ExpandedUncXmlList MeasurementUncertaintyUnivariate
40
45
  ].freeze
41
46
 
@@ -46,4 +51,4 @@ module Dcc
46
51
  end
47
52
  end
48
53
  end
49
- end
54
+ end
@@ -19,7 +19,7 @@ module Dcc
19
19
 
20
20
  def to_s
21
21
  if valid?
22
- "Signature valid#{certificate_pem ? " (cert: #{certificate_pem.lines.first&.strip})" : ''}"
22
+ "Signature valid#{" (cert: #{certificate_pem.lines.first&.strip})" if certificate_pem}"
23
23
  else
24
24
  "Signature INVALID"
25
25
  end
@@ -40,4 +40,4 @@ module Dcc
40
40
  end
41
41
  end
42
42
  end
43
- end
43
+ end
@@ -1,36 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "moxml"
4
+ require "openssl"
5
+
3
6
  module Dcc
4
7
  module Signature
5
- # `Dcc::Signature::Signer` wraps an enveloped XMLDSig signature over a
6
- # DCC document using RSA-SHA-256. Requires the `xmldsig` gem.
8
+ # `Dcc::Signature::Signer` creates an enveloped XMLDSig signature over
9
+ # a DCC document using RSA-SHA-256 with exclusive C14N. Uses moxml's
10
+ # native Signature module.
7
11
  module Signer
12
+ EXC_C14N = "http://www.w3.org/2001/10/xml-exc-c14n#"
13
+ RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
14
+ SHA256 = "http://www.w3.org/2001/04/xmlenc#sha256"
15
+ ENVELOPED = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
16
+
8
17
  class << self
9
18
  # @param xml_or_dcc [String, Lutaml::Model::Serializable] the DCC.
10
19
  # @param cert_pem [String] PEM-encoded signing certificate.
11
20
  # @param key_pem [String] PEM-encoded private key.
12
21
  # @return [String] the signed XML document.
13
22
  def call(xml_or_dcc, cert_pem:, key_pem:)
14
- ensure_xmldsig!
15
23
  xml = xml_or_dcc.is_a?(::String) ? xml_or_dcc : xml_or_dcc.to_xml
16
- document = Xmldsig::XMLDoc.new(xml)
17
- document.sign(
18
- OpenSSL::PKey::RSA.new(key_pem),
19
- cert_pem,
20
- ).to_xml
21
- end
22
-
23
- private
24
+ ctx = ::Moxml.new(::Lutaml::Model::Config.xml_adapter_type)
25
+ doc = ctx.parse(xml)
26
+ key = ::OpenSSL::PKey::RSA.new(key_pem)
27
+ cert = ::OpenSSL::X509::Certificate.new(cert_pem)
24
28
 
25
- def ensure_xmldsig!
26
- return if defined?(::Xmldsig)
29
+ signature = ::Moxml::Signature.sign(
30
+ context: ctx,
31
+ document: doc,
32
+ key: key,
33
+ certificate: cert,
34
+ signature_method: RSA_SHA256,
35
+ canonicalization_method: EXC_C14N,
36
+ digest_method: SHA256,
37
+ reference_uri: "",
38
+ transforms: [ENVELOPED],
39
+ )
27
40
 
28
- require "xmldsig"
29
- rescue ::LoadError
30
- raise ::Dcc::MissingDependencyError.new(gem_name: "xmldsig", feature: "Dcc::Signature"),
31
- "xmldsig is required for XMLDSig signing"
41
+ serialized = ::Moxml::Signature::Serializer
42
+ .new(context: ctx).serialize(signature)
43
+ doc.root.add_child(serialized.root)
44
+ doc.to_xml
32
45
  end
33
46
  end
34
47
  end
35
48
  end
36
- end
49
+ end
@@ -1,41 +1,43 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "moxml"
4
+ require "openssl"
5
+
3
6
  module Dcc
4
7
  module Signature
5
- # `Dcc::Signature::Verifier` validates a signed DCC against a CA
6
- # certificate. The signed XML subtree is extracted so callers can
7
- # extract the trustworthy content.
8
+ # `Dcc::Signature::Verifier` validates a signed DCC using moxml's
9
+ # native Signature module.
8
10
  module Verifier
9
11
  class << self
10
12
  # @param xml [String] signed DCC XML.
11
- # @param ca_cert_pem [String] PEM-encoded CA certificate.
13
+ # @param ca_cert_pem [String] PEM-encoded certificate or public key.
12
14
  # @return [Dcc::Signature::Result]
13
15
  def call(xml, ca_cert_pem:)
14
- ensure_xmldsig!
15
- document = Xmldsig::XMLDoc.new(xml)
16
- signed_xml = nil
17
- is_valid = document.validate(ca_cert_pem) do |signed_node|
18
- signed_xml = signed_node.to_xml
19
- true
20
- end
16
+ ctx = ::Moxml.new(::Lutaml::Model::Config.xml_adapter_type)
17
+ doc = ctx.parse(xml)
18
+
19
+ key = load_key(ca_cert_pem)
20
+ result = ::Moxml::Signature.verify(
21
+ context: ctx,
22
+ document: doc,
23
+ key: key,
24
+ )
25
+
21
26
  ::Dcc::Signature::Result.new(
22
- valid: is_valid,
27
+ valid: result.valid?,
23
28
  certificate_pem: ca_cert_pem,
24
- signed_xml: signed_xml,
29
+ signed_xml: doc.to_xml,
25
30
  )
26
31
  end
27
32
 
28
33
  private
29
34
 
30
- def ensure_xmldsig!
31
- return if defined?(::Xmldsig)
32
-
33
- require "xmldsig"
34
- rescue ::LoadError
35
- raise ::Dcc::MissingDependencyError.new(gem_name: "xmldsig", feature: "Dcc::Signature"),
36
- "xmldsig is required for XMLDSig verification"
35
+ def load_key(pem)
36
+ ::OpenSSL::X509::Certificate.new(pem).public_key
37
+ rescue ::OpenSSL::X509::CertificateError
38
+ ::OpenSSL::PKey::RSA.new(pem)
37
39
  end
38
40
  end
39
41
  end
40
42
  end
41
- end
43
+ end
data/lib/dcc/signature.rb CHANGED
@@ -10,4 +10,4 @@ module Dcc
10
10
  autoload :Verifier, "dcc/signature/verifier"
11
11
  autoload :Result, "dcc/signature/result"
12
12
  end
13
- end
13
+ end
@@ -21,4 +21,4 @@ module Dcc
21
21
  end
22
22
  end
23
23
  end
24
- end
24
+ end
@@ -6,9 +6,9 @@ module Dcc
6
6
  module Transform
7
7
  # `Dcc::Transform::Xslt` applies an XSLT stylesheet to a DCC XML document.
8
8
  #
9
- # Nokogiri is OFFICIALLY banned outside validation, so we shell out to
10
- # the system `xsltproc` (libxslt) for XSLT 1.0 transforms. For XSLT
11
- # 2.0/3.0, set `ENV["SAXON_JAR"]` to point at saxon-he.jar.
9
+ # Nokogiri is banned outside XSD validation and the v2-to-v3 migration,
10
+ # so we shell out to the system `xsltproc` (libxslt) for XSLT 1.0
11
+ # transforms. For XSLT 2.0/3.0, set `ENV["SAXON_JAR"]` to saxon-he.jar.
12
12
  module Xslt
13
13
  class << self
14
14
  # @param xml [String, Lutaml::Model::Serializable]
@@ -21,7 +21,8 @@ module Dcc
21
21
  when :xsltproc then run_xsltproc(xml_string, stylesheet)
22
22
  when :saxon then run_saxon(xml_string, stylesheet)
23
23
  else
24
- raise ::ArgumentError, "unknown XSLT engine: #{engine.inspect}"
24
+ raise ::ArgumentError,
25
+ "unknown XSLT engine: #{engine.inspect}"
25
26
  end
26
27
  ::Dcc::Transform::Result.new(payload: output, engine: engine)
27
28
  end
@@ -31,22 +32,31 @@ module Dcc
31
32
  def run_xsltproc(xml, stylesheet)
32
33
  ensure_tool!("xsltproc")
33
34
  xsl_path = stylesheet_path(stylesheet)
34
- out, status = ::Open3.capture2("xsltproc", xsl_path, "-", stdin_data: xml)
35
- raise ::Dcc::TransformError, "xsltproc failed: #{status}" unless status.success?
35
+ out, status = ::Open3.capture2("xsltproc", xsl_path, "-",
36
+ stdin_data: xml)
37
+ unless status.success?
38
+ raise ::Dcc::TransformError,
39
+ "xsltproc failed: #{status}"
40
+ end
36
41
 
37
42
  out
38
43
  end
39
44
 
40
45
  def run_saxon(xml, stylesheet)
41
- jar = ENV["SAXON_JAR"]
42
- raise ::Dcc::MissingDependencyError.new(gem_name: "saxon-he",
43
- feature: "XSLT 2.0/3.0"),
44
- "SAXON_JAR env var is required for the :saxon engine" unless jar
46
+ jar = ENV.fetch("SAXON_JAR", nil)
47
+ unless jar
48
+ raise ::Dcc::MissingDependencyError.new(gem_name: "saxon-he",
49
+ feature: "XSLT 2.0/3.0"),
50
+ "SAXON_JAR env var is required for the :saxon engine"
51
+ end
45
52
 
46
53
  xsl_path = stylesheet_path(stylesheet)
47
54
  cmd = ["java", "-jar", jar, "-s:-", "-xsl:#{xsl_path}"]
48
55
  out, status = ::Open3.capture2(*cmd, stdin_data: xml)
49
- raise ::Dcc::TransformError, "saxon failed: #{status}" unless status.success?
56
+ unless status.success?
57
+ raise ::Dcc::TransformError,
58
+ "saxon failed: #{status}"
59
+ end
50
60
 
51
61
  out
52
62
  end
@@ -69,4 +79,4 @@ module Dcc
69
79
  end
70
80
  end
71
81
  end
72
- end
82
+ end
data/lib/dcc/transform.rb CHANGED
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # `Dcc::Transform` provides XSLT transformations. We cannot use Nokogiri
4
- # for this per project rule (only validation may touch Nokogiri); instead
5
- # we shell out to the system `xsltproc` CLI for XSLT 1.0, or to
6
- # `java -jar saxon-he.jar` for XSLT 2.0/3.0 when SAXON_JAR is set.
4
+ # for this per project rule (only XSD validation and the v2-to-v3 migration
5
+ # may touch Nokogiri); instead we shell out to the system `xsltproc` CLI for
6
+ # XSLT 1.0, or to `java -jar saxon-he.jar` for XSLT 2.0/3.0 when SAXON_JAR
7
+ # is set.
7
8
  module Dcc
8
9
  module Transform
9
10
  autoload :Xslt, "dcc/transform/xslt"
10
11
  autoload :Result, "dcc/transform/result"
11
12
  end
12
- end
13
+ end
@@ -15,7 +15,8 @@ module Dcc
15
15
  def self.cast(value)
16
16
  return nil if value.nil? || value == ""
17
17
  unless value.is_a?(::String)
18
- raise Lutaml::Model::Type::InvalidValueError.new(value, "expected binary String")
18
+ raise Lutaml::Model::Type::InvalidValueError.new(value,
19
+ "expected binary String")
19
20
  end
20
21
 
21
22
  value
@@ -25,7 +26,8 @@ module Dcc
25
26
  return nil if value.nil?
26
27
 
27
28
  unless value.is_a?(::String)
28
- raise Lutaml::Model::Type::InvalidValueError.new(value, "expected binary String")
29
+ raise Lutaml::Model::Type::InvalidValueError.new(value,
30
+ "expected binary String")
29
31
  end
30
32
 
31
33
  value
@@ -52,4 +54,4 @@ module Dcc
52
54
  end
53
55
  end
54
56
  end
55
- end
57
+ end