pubid 2.0.0.pre.alpha.3 → 2.0.0.pre.alpha.4
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/lib/pubid/amca/identifier.rb +4 -23
- data/lib/pubid/amca/identifiers/base.rb +67 -30
- data/lib/pubid/amca/identifiers/interpretation.rb +0 -4
- data/lib/pubid/amca/identifiers/publication.rb +0 -4
- data/lib/pubid/amca/identifiers/standard.rb +0 -4
- data/lib/pubid/amca/renderer.rb +1 -1
- data/lib/pubid/amca/urn_generator.rb +2 -1
- data/lib/pubid/api/builder.rb +4 -0
- data/lib/pubid/api/identifier.rb +5 -1
- data/lib/pubid/api/identifiers/base.rb +2 -12
- data/lib/pubid/api/identifiers/mpms.rb +0 -4
- data/lib/pubid/api/identifiers/typeless_standard.rb +0 -3
- data/lib/pubid/api/single_identifier.rb +5 -8
- data/lib/pubid/ashrae/identifier.rb +7 -22
- data/lib/pubid/ashrae/identifiers/base.rb +28 -17
- data/lib/pubid/ashrae/parser.rb +4 -0
- data/lib/pubid/ashrae.rb +4 -0
- data/lib/pubid/asme/single_identifier.rb +3 -1
- data/lib/pubid/astm/single_identifier.rb +3 -1
- data/lib/pubid/bsi/identifier.rb +5 -31
- data/lib/pubid/bsi/identifiers/addendum_document.rb +0 -4
- data/lib/pubid/bsi/identifiers/adopted_european_norm.rb +0 -4
- data/lib/pubid/bsi/identifiers/adopted_international_standard.rb +0 -4
- data/lib/pubid/bsi/identifiers/aerospace_standard.rb +0 -3
- data/lib/pubid/bsi/identifiers/amendment.rb +0 -4
- data/lib/pubid/bsi/identifiers/british_industrial_practice.rb +0 -3
- data/lib/pubid/bsi/identifiers/bundled_identifier.rb +2 -5
- data/lib/pubid/bsi/identifiers/committee_document.rb +0 -3
- data/lib/pubid/bsi/identifiers/consolidated_identifier.rb +2 -5
- data/lib/pubid/bsi/identifiers/corrigendum.rb +0 -4
- data/lib/pubid/bsi/identifiers/detailed_specification.rb +0 -3
- data/lib/pubid/bsi/identifiers/disc.rb +0 -3
- data/lib/pubid/bsi/identifiers/draft_document.rb +0 -3
- data/lib/pubid/bsi/identifiers/electronic_book.rb +0 -3
- data/lib/pubid/bsi/identifiers/expert_commentary.rb +0 -4
- data/lib/pubid/bsi/identifiers/explanatory_supplement.rb +0 -3
- data/lib/pubid/bsi/identifiers/flex.rb +0 -3
- data/lib/pubid/bsi/identifiers/handbook.rb +0 -3
- data/lib/pubid/bsi/identifiers/index.rb +0 -3
- data/lib/pubid/bsi/identifiers/method.rb +0 -3
- data/lib/pubid/bsi/identifiers/national_annex.rb +0 -3
- data/lib/pubid/bsi/identifiers/practice_guide.rb +0 -3
- data/lib/pubid/bsi/identifiers/publicly_available_specification.rb +0 -3
- data/lib/pubid/bsi/identifiers/published_document.rb +0 -3
- data/lib/pubid/bsi/identifiers/section.rb +0 -3
- data/lib/pubid/bsi/identifiers/set.rb +2 -5
- data/lib/pubid/bsi/identifiers/standalone_amendment.rb +0 -3
- data/lib/pubid/bsi/identifiers/supplement_document.rb +0 -4
- data/lib/pubid/bsi/identifiers/supplementary_index.rb +0 -3
- data/lib/pubid/bsi/identifiers/technical_specification.rb +0 -3
- data/lib/pubid/bsi/identifiers/test_method.rb +0 -3
- data/lib/pubid/bsi/identifiers/value_added_publication.rb +0 -4
- data/lib/pubid/bsi/single_identifier.rb +32 -13
- data/lib/pubid/bsi.rb +8 -1
- data/lib/pubid/ccsds/identifier.rb +2 -14
- data/lib/pubid/cen_cenelec/identifier.rb +10 -8
- data/lib/pubid/cen_cenelec/identifiers/adopted_european_norm.rb +0 -4
- data/lib/pubid/cen_cenelec/identifiers/amendment.rb +0 -4
- data/lib/pubid/cen_cenelec/identifiers/base.rb +2 -9
- data/lib/pubid/cen_cenelec/identifiers/consolidated_identifier.rb +0 -4
- data/lib/pubid/cen_cenelec/identifiers/corrigendum.rb +0 -4
- data/lib/pubid/cen_cenelec/identifiers/european_prestandard.rb +0 -3
- data/lib/pubid/cen_cenelec/identifiers/fragment.rb +0 -4
- data/lib/pubid/cen_cenelec/single_identifier.rb +4 -7
- data/lib/pubid/cen_cenelec.rb +4 -0
- data/lib/pubid/cie/identifier.rb +4 -0
- data/lib/pubid/cie/single_identifier.rb +4 -4
- data/lib/pubid/cie.rb +4 -0
- data/lib/pubid/csa/identifier.rb +10 -1
- data/lib/pubid/csa/identifiers/base.rb +0 -3
- data/lib/pubid/csa/identifiers/cec.rb +0 -4
- data/lib/pubid/csa/identifiers/series.rb +0 -4
- data/lib/pubid/csa/single_identifier.rb +1 -1
- data/lib/pubid/csa.rb +4 -0
- data/lib/pubid/etsi/components/code.rb +1 -7
- data/lib/pubid/etsi/components/version.rb +0 -5
- data/lib/pubid/etsi/identifier.rb +4 -12
- data/lib/pubid/etsi/identifiers/base.rb +31 -24
- data/lib/pubid/etsi/identifiers/supplement_identifier.rb +0 -3
- data/lib/pubid/etsi.rb +3 -1
- data/lib/pubid/identifier.rb +90 -1
- data/lib/pubid/idf/identifier.rb +4 -0
- data/lib/pubid/idf.rb +4 -0
- data/lib/pubid/iec/identifier.rb +14 -14
- data/lib/pubid/iec/identifiers/base.rb +0 -4
- data/lib/pubid/iec/identifiers/consolidated_identifier.rb +0 -4
- data/lib/pubid/iec/identifiers/fragment_identifier.rb +1 -5
- data/lib/pubid/iec/identifiers/sheet_identifier.rb +1 -5
- data/lib/pubid/iec/identifiers/test_report_form.rb +0 -3
- data/lib/pubid/iec/identifiers/vap_identifier.rb +1 -5
- data/lib/pubid/iec/identifiers/working_document.rb +0 -4
- data/lib/pubid/iec.rb +4 -0
- data/lib/pubid/ieee/identifier.rb +5 -17
- data/lib/pubid/ieee/identifiers/adopted_standard.rb +0 -4
- data/lib/pubid/ieee/identifiers/base.rb +223 -201
- data/lib/pubid/ieee/identifiers/conformance_identifier.rb +0 -4
- data/lib/pubid/ieee/identifiers/corrigendum.rb +0 -4
- data/lib/pubid/ieee/identifiers/csa_dual_published.rb +0 -4
- data/lib/pubid/ieee/identifiers/dual_identifier.rb +0 -4
- data/lib/pubid/ieee/identifiers/dual_published.rb +0 -4
- data/lib/pubid/ieee/identifiers/iec_ieee_copublished.rb +0 -4
- data/lib/pubid/ieee/identifiers/interpretation_identifier.rb +0 -4
- data/lib/pubid/ieee/identifiers/multi_numbered_identifier.rb +0 -4
- data/lib/pubid/ieee/identifiers/parenthetical_identifier.rb +0 -4
- data/lib/pubid/ieee/identifiers/redlined_standard.rb +0 -4
- data/lib/pubid/ieee/identifiers/si_standard.rb +0 -4
- data/lib/pubid/ieee.rb +4 -0
- data/lib/pubid/iho/identifier.rb +7 -25
- data/lib/pubid/iho/identifiers/base.rb +62 -68
- data/lib/pubid/iho.rb +3 -1
- data/lib/pubid/iso/identifier.rb +15 -14
- data/lib/pubid/iso/single_identifier.rb +0 -4
- data/lib/pubid/iso.rb +4 -0
- data/lib/pubid/itu/components/code.rb +1 -7
- data/lib/pubid/itu/components/sector.rb +15 -4
- data/lib/pubid/itu/components/series.rb +0 -4
- data/lib/pubid/itu/identifier.rb +4 -18
- data/lib/pubid/itu/identifiers/base.rb +124 -122
- data/lib/pubid/itu.rb +3 -1
- data/lib/pubid/jcgm/identifiers/amendment.rb +0 -4
- data/lib/pubid/jcgm/identifiers/gum_guide.rb +0 -4
- data/lib/pubid/jcgm/single_identifier.rb +0 -4
- data/lib/pubid/jis/identifier.rb +2 -14
- data/lib/pubid/nist/identifier.rb +8 -23
- data/lib/pubid/nist/identifiers/base.rb +553 -544
- data/lib/pubid/nist/preprocessor.rb +12 -0
- data/lib/pubid/nist.rb +4 -0
- data/lib/pubid/oiml/builder.rb +21 -3
- data/lib/pubid/oiml/components/code.rb +7 -0
- data/lib/pubid/oiml/identifier.rb +44 -0
- data/lib/pubid/oiml/identifiers/annex.rb +10 -1
- data/lib/pubid/oiml/identifiers/errata.rb +15 -0
- data/lib/pubid/oiml/identifiers.rb +1 -1
- data/lib/pubid/oiml/parser.rb +59 -12
- data/lib/pubid/oiml/renderer.rb +27 -17
- data/lib/pubid/oiml/single_identifier.rb +58 -0
- data/lib/pubid/oiml/supplement_identifier.rb +30 -1
- data/lib/pubid/plateau/identifier.rb +4 -21
- data/lib/pubid/plateau/identifiers/base.rb +45 -36
- data/lib/pubid/plateau/identifiers/handbook.rb +0 -4
- data/lib/pubid/plateau/identifiers/technical_report.rb +0 -4
- data/lib/pubid/plateau/supplement_identifier.rb +0 -4
- data/lib/pubid/sae/identifier.rb +4 -12
- data/lib/pubid/sae/identifiers/base.rb +26 -17
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid.rb +18 -2
- data/lib/tasks/export.rake +6 -5
- metadata +3 -4
- data/lib/pubid/identifier_facade.rb +0 -114
- data/lib/pubid/oiml/identifiers/base.rb +0 -21
|
@@ -19,10 +19,6 @@ module Pubid
|
|
|
19
19
|
raise NotImplementedError, "Subclasses must implement supplement_string"
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def to_s
|
|
23
|
-
render(format: :human)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
22
|
# Override base_hash to extract edition, type, and annex from base_identifier
|
|
27
23
|
def base_hash
|
|
28
24
|
hash = super
|
data/lib/pubid/sae/identifier.rb
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
parsed = Parser.parse(input)
|
|
8
|
-
Builder.build(parsed)
|
|
9
|
-
rescue Parslet::ParseFailed => e
|
|
10
|
-
raise "Failed to parse SAE identifier: #{input}\n#{e.message}"
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
3
|
+
# Pubid::Sae::Identifier is the SAE base class (a real Pubid::Identifier
|
|
4
|
+
# subclass); its body, `.parse`, and the Identifiers::Base back-compat alias
|
|
5
|
+
# live in identifiers/base.rb. This file just ensures it is loaded.
|
|
6
|
+
require_relative "identifiers/base"
|
|
@@ -2,27 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
module Pubid
|
|
4
4
|
module Sae
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
# Base SAE Identifier. Canonical name Pubid::Sae::Identifier (Identifiers::Base
|
|
6
|
+
# is a back-compat alias). SAE has a single identifier class that IS the
|
|
7
|
+
# document type, so this class is both the base and the only concrete type.
|
|
8
|
+
# Handles all SAE document types (AMS, AIR, ARP, AS, MA).
|
|
9
|
+
class Identifier < ::Pubid::Identifier
|
|
10
|
+
def self.parse(input)
|
|
11
|
+
parsed = Parser.parse(input)
|
|
12
|
+
Builder.build(parsed)
|
|
13
|
+
rescue Parslet::ParseFailed => e
|
|
14
|
+
raise "Failed to parse SAE identifier: #{input}\n#{e.message}"
|
|
15
|
+
end
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
attribute :publisher, :string, default: -> { "SAE" }
|
|
18
|
+
attribute :type, Sae::Components::Type
|
|
19
|
+
attribute :number, Sae::Components::Code
|
|
20
|
+
attribute :date, Sae::Components::Date
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
def self.type
|
|
23
|
+
{ key: :base, web: :standard, title: "Standard", short: "SAE" }
|
|
24
|
+
end
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
end
|
|
26
|
+
def year
|
|
27
|
+
date&.year
|
|
25
28
|
end
|
|
26
29
|
end
|
|
30
|
+
|
|
31
|
+
module Identifiers
|
|
32
|
+
# Backward-compatible alias: SAE's base class used to be
|
|
33
|
+
# Pubid::Sae::Identifiers::Base. It is now Pubid::Sae::Identifier.
|
|
34
|
+
Base = Pubid::Sae::Identifier
|
|
35
|
+
end
|
|
27
36
|
end
|
|
28
37
|
end
|
data/lib/pubid/version.rb
CHANGED
data/lib/pubid.rb
CHANGED
|
@@ -10,6 +10,21 @@ require "parslet"
|
|
|
10
10
|
require "pubid/lutaml/no_store_registration"
|
|
11
11
|
|
|
12
12
|
module Pubid
|
|
13
|
+
# Upper bound on the length of an identifier string accepted by any +parse+
|
|
14
|
+
# entry point. Real-world standards identifiers are well under 200 characters;
|
|
15
|
+
# this limit exists purely to keep pathological, attacker-controlled inputs
|
|
16
|
+
# away from the flavors' backtracking-capable normalization regexes
|
|
17
|
+
# (CodeQL rb/polynomial-redos). The inline `.length` checks in every public
|
|
18
|
+
# +parse+ method are recognized by CodeQL as a barrier that bounds the input
|
|
19
|
+
# before it can reach those regexes. Ruby 3.2+ already memoizes the flagged
|
|
20
|
+
# regexes to linear time, so this guard is defense-in-depth, not a fix for a
|
|
21
|
+
# live exploit; it must therefore never reject a legitimate identifier.
|
|
22
|
+
MAX_INPUT_LENGTH = 1000
|
|
23
|
+
|
|
24
|
+
# Raised (as an ArgumentError) when an input string exceeds MAX_INPUT_LENGTH.
|
|
25
|
+
INPUT_TOO_LONG_MESSAGE =
|
|
26
|
+
"identifier string exceeds maximum length of #{MAX_INPUT_LENGTH} characters"
|
|
27
|
+
|
|
13
28
|
# Registry for tracking all loaded flavors
|
|
14
29
|
class Registry
|
|
15
30
|
@flavors = {}
|
|
@@ -50,7 +65,6 @@ module Pubid
|
|
|
50
65
|
autoload :Components, "pubid/components"
|
|
51
66
|
autoload :BundledIdentifier, "pubid/bundled_identifier"
|
|
52
67
|
autoload :Identifier, "pubid/identifier"
|
|
53
|
-
autoload :IdentifierFacade, "pubid/identifier_facade"
|
|
54
68
|
autoload :IdentifierMetadata, "pubid/identifier_metadata"
|
|
55
69
|
autoload :Rendering, "pubid/rendering"
|
|
56
70
|
autoload :Renderers, "pubid/renderers"
|
|
@@ -111,6 +125,8 @@ module Pubid
|
|
|
111
125
|
# @param format [Symbol] :auto, :human, :mr_string, or :urn
|
|
112
126
|
# @return [Identifier] The parsed identifier
|
|
113
127
|
def self.parse(string, format: :auto)
|
|
128
|
+
raise ArgumentError, INPUT_TOO_LONG_MESSAGE if string.length > MAX_INPUT_LENGTH
|
|
129
|
+
|
|
114
130
|
format = FormatDetector.detect(string) if format == :auto
|
|
115
131
|
|
|
116
132
|
case format
|
|
@@ -126,7 +142,7 @@ module Pubid
|
|
|
126
142
|
end
|
|
127
143
|
|
|
128
144
|
urn_parser = flavor_module.const_get(:UrnParser)
|
|
129
|
-
urn_parser.parse(string)
|
|
145
|
+
urn_parser.parse(string) else
|
|
130
146
|
# Default to MR string parser for MR format, human-readable otherwise
|
|
131
147
|
# The MR string parser converts to human-readable and delegates to flavor.parse
|
|
132
148
|
raise ArgumentError,
|
data/lib/tasks/export.rake
CHANGED
|
@@ -19,17 +19,18 @@ namespace :export do
|
|
|
19
19
|
desc "Audit library data against website publishers"
|
|
20
20
|
task :audit do
|
|
21
21
|
require "pubid/export"
|
|
22
|
-
data = Pubid::Export::Exporter.export_all
|
|
23
22
|
|
|
24
|
-
#
|
|
25
|
-
#
|
|
23
|
+
# Auditor compares string-keyed, JSON-shaped data (see Auditor.from_file and
|
|
24
|
+
# auditor_spec.rb), so roundtrip the export through JSON to convert the
|
|
25
|
+
# symbol keys (:identifier_types) into the string keys it expects.
|
|
26
|
+
data = JSON.parse(JSON.generate(Pubid::Export::Exporter.export_all))
|
|
26
27
|
auditor = Pubid::Export::Auditor.new(data)
|
|
27
28
|
|
|
28
29
|
# Build a minimal website representation from the generated data itself
|
|
29
30
|
# (in production, this would parse the website's publishers.ts)
|
|
30
|
-
{}
|
|
31
31
|
summary = data.transform_values do |fd|
|
|
32
|
-
|
|
32
|
+
keys = fd["identifier_types"].map { |t| { "key" => t["key"] } }
|
|
33
|
+
{ "doc_types" => keys }
|
|
33
34
|
end
|
|
34
35
|
|
|
35
36
|
results = auditor.audit(summary)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pubid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.0.pre.alpha.
|
|
4
|
+
version: 2.0.0.pre.alpha.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: lutaml-model
|
|
@@ -336,7 +336,6 @@ files:
|
|
|
336
336
|
- lib/pubid/format_detector.rb
|
|
337
337
|
- lib/pubid/format_registry.rb
|
|
338
338
|
- lib/pubid/identifier.rb
|
|
339
|
-
- lib/pubid/identifier_facade.rb
|
|
340
339
|
- lib/pubid/identifier_metadata.rb
|
|
341
340
|
- lib/pubid/idf.rb
|
|
342
341
|
- lib/pubid/idf/builder.rb
|
|
@@ -609,9 +608,9 @@ files:
|
|
|
609
608
|
- lib/pubid/oiml/identifiers.rb
|
|
610
609
|
- lib/pubid/oiml/identifiers/amendment.rb
|
|
611
610
|
- lib/pubid/oiml/identifiers/annex.rb
|
|
612
|
-
- lib/pubid/oiml/identifiers/base.rb
|
|
613
611
|
- lib/pubid/oiml/identifiers/basic_publication.rb
|
|
614
612
|
- lib/pubid/oiml/identifiers/document.rb
|
|
613
|
+
- lib/pubid/oiml/identifiers/errata.rb
|
|
615
614
|
- lib/pubid/oiml/identifiers/expert_report.rb
|
|
616
615
|
- lib/pubid/oiml/identifiers/guide.rb
|
|
617
616
|
- lib/pubid/oiml/identifiers/recommendation.rb
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Pubid
|
|
4
|
-
# Mixin for the per-flavor `Identifier` *module* facades (NIST, IHO, BSI,
|
|
5
|
-
# CEN/CENELEC, ASHRAE). The class-pattern flavors (ISO, IEC, JIS, …) expose
|
|
6
|
-
# their root identifier as a real class, so `id.is_a?(Pubid::Iso::Identifier)`
|
|
7
|
-
# and `Pubid::Iso::Identifier.from_hash` already work natively. The
|
|
8
|
-
# module-pattern flavors keep `Identifier` as a thin parse/factory module;
|
|
9
|
-
# this mixin gives that module the same two capabilities a consumer relies on
|
|
10
|
-
# when it is handed the module as its identifier class (e.g. relaton-index's
|
|
11
|
-
# `pubid_class`):
|
|
12
|
-
#
|
|
13
|
-
# * `from_hash` — polymorphic deserialization that dispatches on the
|
|
14
|
-
# `_type` discriminator to the correct concrete `Identifiers::*` class,
|
|
15
|
-
# reusing the flavor's own `identifier_types` registry rather than a
|
|
16
|
-
# hand-maintained map.
|
|
17
|
-
# * identity — `extend`ing this mixin into the `Identifier` module is paired
|
|
18
|
-
# with `include`-ing that module into the flavor's `Identifiers::Base`, so
|
|
19
|
-
# every concrete identifier descends from it. That makes
|
|
20
|
-
# `id.is_a?(Pubid::Nist::Identifier)` and `Pubid::Nist::Identifier === id`
|
|
21
|
-
# both true (`Module#===` delegates to `is_a?`) — the test a consumer
|
|
22
|
-
# holding the module needs to ask "is this one of my identifiers?".
|
|
23
|
-
#
|
|
24
|
-
# The flavor namespace, the `Identifiers` namespace, and the fallback `Base`
|
|
25
|
-
# class are all derived from the extending module's own name by convention
|
|
26
|
-
# (`Pubid::<Flavor>::Identifier`), so a flavor opts in with a single
|
|
27
|
-
# `extend Pubid::IdentifierFacade`.
|
|
28
|
-
#
|
|
29
|
-
# Opt-in is deliberately GATED to flavors whose `to_hash`/`from_hash`
|
|
30
|
-
# round-trips cleanly. Some module-pattern flavors (AMCA, ITU, PLATEAU, IEEE)
|
|
31
|
-
# have a broken `to_hash` (publisher stored as a String) or a lossy
|
|
32
|
-
# `from_hash`; for those the facade's identity check would route ids through a
|
|
33
|
-
# consumer's `to_hash` and crash or silently corrupt them, so they
|
|
34
|
-
# intentionally do not opt in (see the NOTE in each of their identifier.rb).
|
|
35
|
-
module IdentifierFacade
|
|
36
|
-
# Reconstruct a concrete identifier from its serialized key_value hash by
|
|
37
|
-
# dispatching on the `_type` discriminator. Falls back to the flavor's
|
|
38
|
-
# `Identifiers::Base` for an absent/unknown type, matching lutaml's own
|
|
39
|
-
# non-polymorphic default.
|
|
40
|
-
#
|
|
41
|
-
# @param data [Hash] the serialized identifier hash (string or symbol keys)
|
|
42
|
-
# @return [Pubid::Identifier] the concrete identifier instance
|
|
43
|
-
def from_hash(data, options = {})
|
|
44
|
-
type = data && (data["_type"] || data[:_type])
|
|
45
|
-
klass = polymorphic_type_map[type] || identifier_base_class
|
|
46
|
-
klass.from_hash(data, options)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Map of polymorphic_name ("pubid:nist:interagency-report") => concrete
|
|
50
|
-
# class, built once from the flavor's identifier-type registry so it tracks
|
|
51
|
-
# newly registered types automatically.
|
|
52
|
-
# @return [Hash{String => Class}]
|
|
53
|
-
def polymorphic_type_map
|
|
54
|
-
@polymorphic_type_map ||=
|
|
55
|
-
(identifier_registry_classes + [identifier_base_class]).uniq
|
|
56
|
-
.each_with_object({}) do |klass, map|
|
|
57
|
-
poly_name = klass.polymorphic_name
|
|
58
|
-
map[poly_name] = klass if poly_name
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
private
|
|
63
|
-
|
|
64
|
-
# The flavor module that namespaces this facade, e.g. Pubid::Nist for
|
|
65
|
-
# Pubid::Nist::Identifier.
|
|
66
|
-
def facade_flavor_module
|
|
67
|
-
@facade_flavor_module ||=
|
|
68
|
-
Object.const_get(name.split("::")[0...-1].join("::"))
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def facade_identifiers_namespace
|
|
72
|
-
@facade_identifiers_namespace ||=
|
|
73
|
-
facade_flavor_module.const_get(:Identifiers)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Fallback class for an absent/unknown `_type`. Most flavors expose a
|
|
77
|
-
# concrete `Identifiers::Base`; flavors without one (e.g. BSI, whose common
|
|
78
|
-
# ancestor is SingleIdentifier) fall back to the shared root, which is only
|
|
79
|
-
# ever reached for an unrecognized `_type`.
|
|
80
|
-
def identifier_base_class
|
|
81
|
-
if facade_identifiers_namespace.const_defined?(:Base, false)
|
|
82
|
-
facade_identifiers_namespace.const_get(:Base)
|
|
83
|
-
else
|
|
84
|
-
::Pubid::Identifier
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# Every concrete identifier class whose `_type` may appear in a serialized
|
|
89
|
-
# hash. Scans the `Identifiers` namespace for descendants of
|
|
90
|
-
# Pubid::Identifier (the complete set, independent of whatever filtering the
|
|
91
|
-
# flavor's `identifier_types` applies) and unions in `identifier_types`,
|
|
92
|
-
# which may register classes living outside that namespace.
|
|
93
|
-
def identifier_registry_classes
|
|
94
|
-
(scanned_identifier_classes + registered_identifier_classes).uniq
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# Concrete identifier classes found directly in the `Identifiers` namespace.
|
|
98
|
-
def scanned_identifier_classes
|
|
99
|
-
facade_identifiers_namespace.constants.filter_map do |const|
|
|
100
|
-
klass = facade_identifiers_namespace.const_get(const)
|
|
101
|
-
klass if klass.is_a?(Class) && klass < ::Pubid::Identifier
|
|
102
|
-
rescue NameError
|
|
103
|
-
nil
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
# Classes the flavor explicitly registers via `identifier_types`, if any.
|
|
108
|
-
def registered_identifier_classes
|
|
109
|
-
return [] unless facade_flavor_module.respond_to?(:identifier_types)
|
|
110
|
-
|
|
111
|
-
Array(facade_flavor_module.identifier_types)
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Pubid
|
|
4
|
-
module Oiml
|
|
5
|
-
module Identifiers
|
|
6
|
-
class Base < Pubid::Identifier
|
|
7
|
-
attribute :publisher, :string
|
|
8
|
-
attribute :type, :string
|
|
9
|
-
attribute :code, Oiml::Components::Code
|
|
10
|
-
attribute :date, Pubid::Components::Date
|
|
11
|
-
attribute :stage, :string
|
|
12
|
-
attribute :iteration, :string
|
|
13
|
-
attribute :language, :string
|
|
14
|
-
|
|
15
|
-
def to_s(**opts)
|
|
16
|
-
render(format: :human, **opts)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|