Class: Pubid::Iso::Identifier
- Inherits:
-
Pubid::Identifier
- Object
- Lutaml::Model::Serializable
- Pubid::Identifier
- Pubid::Iso::Identifier
- Defined in:
- lib/pubid/iso/identifier.rb
Direct Known Subclasses
Constant Summary collapse
- ISO_TYPE_MAP =
Polymorphic type map for lutaml::Model key_value serialization Maps polymorphic_name → class name for deserialization Validated by spec to stay in sync with Scheme.identifiers
{ "pubid:iso:international-standard" => "Pubid::Iso::Identifiers::InternationalStandard", "pubid:iso:international-standardized-profile" => "Pubid::Iso::Identifiers::InternationalStandardizedProfile", "pubid:iso:international-workshop-agreement" => "Pubid::Iso::Identifiers::InternationalWorkshopAgreement", "pubid:iso:technical-report" => "Pubid::Iso::Identifiers::TechnicalReport", "pubid:iso:technical-specification" => "Pubid::Iso::Identifiers::TechnicalSpecification", "pubid:iso:pas" => "Pubid::Iso::Identifiers::Pas", "pubid:iso:guide" => "Pubid::Iso::Identifiers::Guide", "pubid:iso:recommendation" => "Pubid::Iso::Identifiers::Recommendation", "pubid:iso:amendment" => "Pubid::Iso::Identifiers::Amendment", "pubid:iso:corrigendum" => "Pubid::Iso::Identifiers::Corrigendum", "pubid:iso:supplement" => "Pubid::Iso::Identifiers::Supplement", "pubid:iso:addendum" => "Pubid::Iso::Identifiers::Addendum", "pubid:iso:extract" => "Pubid::Iso::Identifiers::Extract", "pubid:iso:directives" => "Pubid::Iso::Identifiers::Directives", "pubid:iso:directives-supplement" => "Pubid::Iso::Identifiers::DirectivesSupplement", "pubid:iso:data" => "Pubid::Iso::Identifiers::Data", "pubid:iso:tc-document" => "Pubid::Iso::Identifiers::TcDocument", "pubid:iso:technology-trends-assessments" => "Pubid::Iso::Identifiers::TechnologyTrendsAssessments", }.freeze
Class Method Summary collapse
-
.build_base_identifier(base) ⇒ Object
Build the base_identifier for a supplement from either an already constructed identifier or a 1.x-style attribute hash (the nested ‘:base` entry in a structured index).
-
.build_type_map ⇒ Object
Build type map from Scheme.identifiers for validation.
-
.create(type: nil, stage: nil, base: nil, **opts) ⇒ Pubid::Iso::Identifier
Factory mirroring pubid 1.x’s ‘Pubid::Iso::Identifier.create` API.
-
.locate_create_typed_stage(stage) ⇒ Object
Resolve a TypedStage from a create() :stage value.
-
.locate_klass_by_type_or_short(type) ⇒ Object
Try direct key lookup, then a case-insensitive key lookup (indexes store e.g. “DATA” but the registry key is :data), then fall back to matching the class’s :short letter (e.g. type “R” → Recommendation, whose key is :rec and short is “R”).
- .parse(string, format: :auto) ⇒ Object
-
.retype_stage_for_class(klass, ts) ⇒ Object
Indexes store a supplement’s stage as the bare review-stage abbr (“CD”, “WD”, “AWI”) plus a separate type (“AMD”), so the global lookup resolves the stage to the IS-typed variant (cdis) rather than the amendment-typed one (committee_draft_amd).
Methods inherited from Pubid::Identifier
#base_identifier, #eql?, #exclude, #hash, #initialize, #mr_number, #mr_number_with_part, #mr_part, #mr_publisher, #mr_type, #mr_year, #new_edition_of?, polymorphic_name, #render, #resolve_urn_generator, #root, #to_mr_string, #to_s, #to_supplement_s, #to_urn, #urn_supplement_type, #urn_type_code, #year
Constructor Details
This class inherits a constructor from Pubid::Identifier
Class Method Details
.build_base_identifier(base) ⇒ Object
Build the base_identifier for a supplement from either an already constructed identifier or a 1.x-style attribute hash (the nested ‘:base` entry in a structured index). Recurses so supplement-of- supplement chains (e.g. a Corrigendum to an Amendment) build cleanly.
174 175 176 177 178 |
# File 'lib/pubid/iso/identifier.rb', line 174 def self.build_base_identifier(base) return base if base.is_a?(::Pubid::Identifier) create(**base.transform_keys(&:to_sym)) end |
.build_type_map ⇒ Object
Build type map from Scheme.identifiers for validation
39 40 41 42 43 |
# File 'lib/pubid/iso/identifier.rb', line 39 def self.build_type_map Scheme.identifiers.to_h do |klass| [klass.polymorphic_name, klass.name] end end |
.create(type: nil, stage: nil, base: nil, **opts) ⇒ Pubid::Iso::Identifier
Factory mirroring pubid 1.x’s ‘Pubid::Iso::Identifier.create` API.
Accepts 1.x-style primitive kwargs and dispatches to the correct 2.x ‘Identifiers::*` subclass via Scheme. Coerces primitives into ISO-specific Component objects.
Dispatch rules:
* `type:` (e.g. `:tr`, `:amd`) → lookup via Scheme
* else `stage:` (e.g. `"DIS"`, `"AMD"`) → lookup via Scheme
* else → InternationalStandard
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/pubid/iso/identifier.rb', line 85 def self.create(type: nil, stage: nil, base: nil, **opts) # A bundled directive (e.g. "ISO/IEC DIR 1 + IEC SUP") is stored by the # 1.x index as the base document's fields plus a nested joint_document # (or a supplements array). The 2.x model is a separate # BundledIdentifier; build that so .create round-trips parse. if opts[:joint_document] || opts[:supplements] return build_bundled(type: type, stage: stage, base: base, **opts) end klass = resolve_create_class(type: type, stage: stage, base: base) attrs = coerce_create_attrs(opts) ts = resolve_create_typed_stage(klass, stage) if ts # dup the (shared) TYPED_STAGES element before tweaking, and set # original_abbr to the canonical abbr so rendering matches a # parsed identifier (parse records the spelled abbr, e.g. "Amd" # not the upcased short_abbr "AMD"). ts = ts.dup ts.original_abbr ||= Array(ts.abbr).first&.to_s attrs[:typed_stage] = ts # Parse fills `type` and `stage` Components derived from # typed_stage; mirror that here so .create round-trips through # Pubid::Identifier#== with a parsed identifier. attrs[:type] ||= ::Pubid::Components::Type.new( name: ts.name, abbr: Array(ts.abbr).first.to_s, type_code: ts.type_code&.to_s, ) attrs[:stage] ||= ::Pubid::Components::Stage.new( name: ts.name, stage_code: ts.stage_code&.to_s, abbr: Array(ts.abbr).first.to_s, harmonized_stages: Array(ts.harmonized_stages), ) end # Build the base_identifier whenever a `base:` is supplied, regardless # of whether the resolved class is registered as a supplement (e.g. # DirectivesSupplement holds a base but is not in # Scheme#supplement_identifiers). Only classes that *require* a base # and were given none raise. if base attrs[:base_identifier] = build_base_identifier(base) elsif supplement_klass?(klass) raise ArgumentError, "#{klass} requires a base: identifier" end # For a DirectivesSupplement the top-level `publisher:` names the # supplement's own publisher ("… ISO SUP"), not the document's — the # document publisher lives on the base. Mirror parse, which records it # as `supplement_publisher`. if klass <= Identifiers::DirectivesSupplement && attrs.key?(:publisher) attrs[:supplement_publisher] = attrs.delete(:publisher) attrs.delete(:copublishers) end klass.new(**attrs) end |
.locate_create_typed_stage(stage) ⇒ Object
Resolve a TypedStage from a create() :stage value. The index may supply it as an abbreviation (“DIS”), a generic stage_code (:dis), or a unique per-typed-stage code (:dtr, :fdisp). Try each in turn.
219 220 221 222 223 |
# File 'lib/pubid/iso/identifier.rb', line 219 def self.locate_create_typed_stage(stage) Scheme.locate_typed_stage_by_abbr(stage.to_s) || Scheme.locate_typed_stage_by_stage_code(stage) || Scheme.locate_typed_stage_by_code(stage) end |
.locate_klass_by_type_or_short(type) ⇒ Object
Try direct key lookup, then a case-insensitive key lookup (indexes store e.g. “DATA” but the registry key is :data), then fall back to matching the class’s :short letter (e.g. type “R” → Recommendation, whose key is :rec and short is “R”). Indexes and legacy data carry either the key, an upper-cased key, or the short form.
248 249 250 251 252 |
# File 'lib/pubid/iso/identifier.rb', line 248 def self.locate_klass_by_type_or_short(type) Scheme.locate_identifier_klass_by_type_code(type) || Scheme.locate_identifier_klass_by_type_code(type.to_s.downcase) || Scheme.identifiers.detect { |k| k.type&.dig(:short)&.to_s == type.to_s } end |
.parse(string, format: :auto) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/pubid/iso/identifier.rb', line 49 def self.parse(string, format: :auto) format = Pubid::FormatDetector.detect(string) if format == :auto case format when :urn Pubid::Iso::UrnParser.parse(string) when :mr_string Pubid::Parsers::MrString.parse(string) else parsed = Pubid::Iso::Parser.new.parse(string) if parsed.nil? || parsed.empty? raise Pubid::Iso::Parser::ParseError, "Invalid identifier format" end Pubid::Iso::Builder.new(Pubid::Iso::Scheme).build(parsed) end end |
.retype_stage_for_class(klass, ts) ⇒ Object
Indexes store a supplement’s stage as the bare review-stage abbr (“CD”, “WD”, “AWI”) plus a separate type (“AMD”), so the global lookup resolves the stage to the IS-typed variant (cdis) rather than the amendment-typed one (committee_draft_amd). When the resolved stage’s type differs from the class chosen via ‘type:`, re-pick the equivalent stage from the class’s own TYPED_STAGES. harmonized_stages is the stable cross-type key (stage_code/abbr diverge between IS and amd: IS “WD” is :working_draft, the amendment is :wd_amd).
203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/pubid/iso/identifier.rb', line 203 def self.retype_stage_for_class(klass, ts) return ts unless klass.const_defined?(:TYPED_STAGES) return ts unless klass.respond_to?(:type) && klass.type return ts if ts.type_code.to_s == klass.type[:key].to_s harmonized = Array(ts.harmonized_stages) return ts if harmonized.empty? klass.const_get(:TYPED_STAGES).find do |s| (Array(s.harmonized_stages) & harmonized).any? end || ts end |