Class: Relaton::Ccsds::DataParser

Inherits:
Object
  • Object
show all
Includes:
Core::ArrayWrapper
Defined in:
lib/relaton/ccsds/data/parser.rb

Constant Summary collapse

DOCTYPES =
{ B: "standard", M: "practice", G: "report", O: "specification", Y: "record" }.freeze
DOMAIN =
"https://public.ccsds.org".freeze
AREAS =
{
  "SEA" => "Systems Engineering Area",
  "MOIMS" => "Mission Operations and Information Management Services Area",
  "CSS" => "Cross Support Services Area",
  "SOIS" => "Spacecraft Onboard Interface Services Area",
  "SLS" => "Space Link Services Area",
  "SIS" => "Space Internetworking Services Area",
}.freeze
ATTRS =
%i[
  title docidentifier abstract date status source edition relation contributor ext
].freeze
ID_MAPPING =
{
  "CCSDS 320.0-B-1-S Corrigendum 1" => "CCSDS 320.0-B-1-S Cor. 1", # TODO relaton/relaton-data-ccsds#5
  "CCSDS 701.00-R-3" => "CCSDS 701.00-R-3-S", # TODO relaton/relaton-data-ccsds#8
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(doc, docs, successor = nil) ⇒ DataParser

Returns a new instance of DataParser.



31
32
33
34
35
# File 'lib/relaton/ccsds/data/parser.rb', line 31

def initialize(doc, docs, successor = nil)
  @doc = doc
  @docs = docs
  @successor = successor
end

Instance Method Details

#adoptedObject



124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/relaton/ccsds/data/parser.rb', line 124

def adopted
  /(?<href>https?:[^"]+)/ =~ @doc[9]
  array(href).each_with_object([]) do |uri, acc|
    /\/(?<ref_id>\d+)\.html/ =~ uri
    iso_id = IsoReferences.instance[ref_id]
    unless iso_id
      Util.warn "ISO reference not found for #{uri}"
      next
    end
    acc << create_relation("adoptedAs", iso_id, uri, "ISO")
  end
end

#create_relation(type, rel_id, uri = nil, id_type = "CCSDS") ⇒ Object



160
161
162
163
164
165
# File 'lib/relaton/ccsds/data/parser.rb', line 160

def create_relation(type, rel_id, uri = nil, id_type = "CCSDS")
  id = Bib::Docidentifier.new content: rel_id, type: id_type, primary: true
  source = array(uri).map { |u| Bib::Uri.new(type: "src", content: u) }
  bibitem = Bib::ItemData.new docidentifier: [id], source: source, formattedref: Bib::Formattedref.new(content: rel_id)
  Bib::Relation.new type: type, bibitem: bibitem
end

#create_source(link, type) ⇒ Object



97
98
99
100
101
102
# File 'lib/relaton/ccsds/data/parser.rb', line 97

def create_source(link, type)
  href = parse_href(link)
  return unless href

  Bib::Uri.new(type: type, content: href)
end

#docidentifierObject



53
54
55
56
57
58
# File 'lib/relaton/ccsds/data/parser.rb', line 53

def docidentifier
  @docidentifier ||= begin
    docid = parse_identifier(@doc[2])
    @successor ? docid.sub(/(-S|s)(?=\s|$)/, "") : docid
  end
end

#parseObject



37
38
39
40
41
42
# File 'lib/relaton/ccsds/data/parser.rb', line 37

def parse
  args = ATTRS.each_with_object({}) { |a, o| o[a] = send "parse_#{a}" }
  item = ItemData.new(**args)
  item.create_id
  item
end

#parse_abstractObject



65
66
67
68
# File 'lib/relaton/ccsds/data/parser.rb', line 65

def parse_abstract
  a = @doc[7]
  [Bib::Abstract.new(content: a, language: "en", script: "Latn")]
end

#parse_contributorObject

rubocop:disable Metrics/AbcSize,Metrics/MethodLength



167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/relaton/ccsds/data/parser.rb', line 167

def parse_contributor # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
  array(@doc[8]).each_with_object([]) do |wg, acc|
    /^(?<name>[^<]+)/ =~ wg
    next if name.nil? || name.strip.empty?

    sdname = Bib::TypedLocalizedString.new content: name.strip
    subdiv = Bib::Subdivision.new type: "technical-committee", name: [sdname]
    orgname = Bib::TypedLocalizedString.new content: "CCSDS"
    org = Bib::Organization.new name: [orgname], subdivision: [subdiv]
    description = Bib::LocalizedMarkedUpString.new(content: "committee")
    role = Bib::Contributor::Role.new type: "author", description: [description]
    acc << Bib::Contributor.new(role: [role], organization: org)
  end
end

#parse_dateObject



75
76
77
78
# File 'lib/relaton/ccsds/data/parser.rb', line 75

def parse_date
  at = @doc[6]
  [Bib::Date.new(type: "published", at: at)]
end

#parse_docidentifierObject



49
50
51
# File 'lib/relaton/ccsds/data/parser.rb', line 49

def parse_docidentifier
  [Bib::Docidentifier.new(content: docidentifier, type: "CCSDS", primary: true)]
end

#parse_doctypeObject



70
71
72
73
# File 'lib/relaton/ccsds/data/parser.rb', line 70

def parse_doctype
  />CCSDS\s[\d.]+-(?<type>\w+)/ =~ @doc[2]
  Doctype.new content: DOCTYPES[type&.to_sym]
end

#parse_editionObject



108
109
110
111
112
# File 'lib/relaton/ccsds/data/parser.rb', line 108

def parse_edition
  return unless @doc[5]

  Bib::Edition.new content: @doc[5]
end

#parse_extObject



182
183
184
# File 'lib/relaton/ccsds/data/parser.rb', line 182

def parse_ext
  Ext.new flavor: "ccsds", doctype: parse_doctype, technology_area: parse_technology_area
end

#parse_href(link) ⇒ Object



104
105
106
# File 'lib/relaton/ccsds/data/parser.rb', line 104

def parse_href(link)
  /(?<href>https?:[^"]+)/.match(link)&.[](:href)
end

#parse_identifier(link) ⇒ Object



60
61
62
63
# File 'lib/relaton/ccsds/data/parser.rb', line 60

def parse_identifier(link)
  id = link.strip.match(/(?<=>).+(?=<\/a>)/).to_s
  ID_MAPPING[id] || id
end

#parse_relationObject



114
115
116
117
118
119
120
121
122
# File 'lib/relaton/ccsds/data/parser.rb', line 114

def parse_relation
  @docs.each_with_object(successors + adopted) do |d, a|
    id = parse_identifier d[2]
    type = relation_type id
    next unless type

    a << create_relation(type, id)
  end
end

#parse_sourceObject



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/relaton/ccsds/data/parser.rb', line 85

def parse_source
  sources = []
  src = create_source(@doc[2], "src")
  sources << src if src

  type = @doc[1].match(/https?:[^"]+(pdf|doc)"/)
  return sources unless type

  download = create_source(@doc[1], type[1])
  sources.tap { |s| s << download if download }
end

#parse_statusObject



80
81
82
83
# File 'lib/relaton/ccsds/data/parser.rb', line 80

def parse_status
  stage = Bib::Status::Stage.new content: @successor ? "withdrawn" : "published"
  Bib::Status.new stage: stage
end

#parse_technology_areaObject



186
187
188
189
190
191
# File 'lib/relaton/ccsds/data/parser.rb', line 186

def parse_technology_area
  return unless @doc[8]

  desc = @doc[8].split("-").first
  AREAS[desc]
end

#parse_titleObject



44
45
46
47
# File 'lib/relaton/ccsds/data/parser.rb', line 44

def parse_title
  t = @doc[3]
  [Bib::Title.new(content: t, language: "en", script: "Latn")]
end

#relation_type(rel_id) ⇒ Object

TODO: cover this



149
150
151
152
153
154
155
156
157
158
# File 'lib/relaton/ccsds/data/parser.rb', line 149

def relation_type(rel_id)
  return if rel_id == docidentifier ||
    rel_id.match(DataFetcher::TRRGX).to_s != docidentifier.match(DataFetcher::TRRGX).to_s

  if rel_id.include?(docidentifier.sub(DataFetcher::TRRGX, ""))
    "updatedBy"
  elsif docidentifier.include?(rel_id.sub(DataFetcher::TRRGX, ""))
    "updates"
  end
end

#successorsObject



137
138
139
140
141
142
143
144
145
146
# File 'lib/relaton/ccsds/data/parser.rb', line 137

def successors
  return [] unless @successor

  @successors ||= begin
    if @successor.relation.none? { |r| r.type == "successorOf" }
      @successor.relation << create_relation("successorOf", docidentifier)
    end
    [create_relation("hasSuccessor", @successor.docidentifier[0].content)]
  end
end