cocina-models 0.74.1 → 0.77.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +40 -11
- data/.rubocop_todo.yml +71 -2
- data/README.md +19 -3
- data/cocina-models.gemspec +2 -0
- data/description_types.yml +168 -39
- data/docs/description_types.md +471 -216
- data/lib/cocina/generator/generator.rb +7 -15
- data/lib/cocina/generator/schema.rb +1 -3
- data/lib/cocina/generator/schema_base.rb +0 -8
- data/lib/cocina/generator/schema_ref.rb +1 -1
- data/lib/cocina/generator/schema_value.rb +14 -4
- data/lib/cocina/models/access.rb +4 -4
- data/lib/cocina/models/admin_policy.rb +1 -1
- data/lib/cocina/models/admin_policy_access_template.rb +7 -7
- data/lib/cocina/models/admin_policy_administrative.rb +1 -1
- data/lib/cocina/models/admin_policy_with_metadata.rb +3 -3
- data/lib/cocina/models/builders/dro_rights_description_builder.rb +69 -0
- data/lib/cocina/models/builders/name_title_group_builder.rb +130 -0
- data/lib/cocina/models/builders/rights_description_builder.rb +83 -0
- data/lib/cocina/models/builders/title_builder.rb +211 -0
- data/lib/cocina/models/citation_only_access.rb +2 -2
- data/lib/cocina/models/collection_access.rb +4 -4
- data/lib/cocina/models/collection_identification.rb +1 -1
- data/lib/cocina/models/collection_with_metadata.rb +2 -2
- data/lib/cocina/models/contributor.rb +4 -4
- data/lib/cocina/models/controlled_digital_lending_access.rb +2 -2
- data/lib/cocina/models/dark_access.rb +4 -4
- data/lib/cocina/models/description.rb +3 -3
- data/lib/cocina/models/descriptive_basic_value.rb +13 -13
- data/lib/cocina/models/descriptive_parallel_contributor.rb +5 -5
- data/lib/cocina/models/descriptive_parallel_event.rb +3 -3
- data/lib/cocina/models/descriptive_value.rb +13 -13
- data/lib/cocina/models/descriptive_value_language.rb +6 -6
- data/lib/cocina/models/dro.rb +1 -1
- data/lib/cocina/models/dro_access.rb +8 -8
- data/lib/cocina/models/dro_with_metadata.rb +3 -3
- data/lib/cocina/models/embargo.rb +5 -5
- data/lib/cocina/models/event.rb +3 -3
- data/lib/cocina/models/file.rb +4 -4
- data/lib/cocina/models/file_access.rb +4 -4
- data/lib/cocina/models/identification.rb +2 -2
- data/lib/cocina/models/language.rb +12 -12
- data/lib/cocina/models/location_based_access.rb +1 -1
- data/lib/cocina/models/location_based_download_access.rb +1 -1
- data/lib/cocina/models/mapping/error_notifier.rb +36 -0
- data/lib/cocina/models/mapping/from_mods/access.rb +177 -0
- data/lib/cocina/models/mapping/from_mods/admin_metadata.rb +217 -0
- data/lib/cocina/models/mapping/from_mods/alt_rep_group.rb +26 -0
- data/lib/cocina/models/mapping/from_mods/authority.rb +51 -0
- data/lib/cocina/models/mapping/from_mods/contributor.rb +161 -0
- data/lib/cocina/models/mapping/from_mods/description.rb +98 -0
- data/lib/cocina/models/mapping/from_mods/description_builder.rb +61 -0
- data/lib/cocina/models/mapping/from_mods/event.rb +543 -0
- data/lib/cocina/models/mapping/from_mods/form.rb +381 -0
- data/lib/cocina/models/mapping/from_mods/geographic.rb +219 -0
- data/lib/cocina/models/mapping/from_mods/hydrus_default_title_builder.rb +28 -0
- data/lib/cocina/models/mapping/from_mods/identifier.rb +51 -0
- data/lib/cocina/models/mapping/from_mods/identifier_builder.rb +71 -0
- data/lib/cocina/models/mapping/from_mods/identifier_type.rb +292 -0
- data/lib/cocina/models/mapping/from_mods/language.rb +36 -0
- data/lib/cocina/models/mapping/from_mods/language_script.rb +30 -0
- data/lib/cocina/models/mapping/from_mods/language_term.rb +106 -0
- data/lib/cocina/models/mapping/from_mods/name_builder.rb +307 -0
- data/lib/cocina/models/mapping/from_mods/note.rb +162 -0
- data/lib/cocina/models/mapping/from_mods/part_builder.rb +147 -0
- data/lib/cocina/models/mapping/from_mods/primary.rb +27 -0
- data/lib/cocina/models/mapping/from_mods/purl.rb +53 -0
- data/lib/cocina/models/mapping/from_mods/related_resource.rb +105 -0
- data/lib/cocina/models/mapping/from_mods/subject.rb +413 -0
- data/lib/cocina/models/mapping/from_mods/subject_authority_codes.rb +794 -0
- data/lib/cocina/models/mapping/from_mods/title.rb +160 -0
- data/lib/cocina/models/mapping/from_mods/title_builder.rb +106 -0
- data/lib/cocina/models/mapping/from_mods/title_builder_strategy.rb +19 -0
- data/lib/cocina/models/mapping/from_mods/value_uri.rb +25 -0
- data/lib/cocina/models/mapping/normalizers/base.rb +16 -0
- data/lib/cocina/models/mapping/normalizers/mods/geo_extension_normalizer.rb +69 -0
- data/lib/cocina/models/mapping/normalizers/mods/name_normalizer.rb +191 -0
- data/lib/cocina/models/mapping/normalizers/mods/origin_info_normalizer.rb +157 -0
- data/lib/cocina/models/mapping/normalizers/mods/subject_normalizer.rb +296 -0
- data/lib/cocina/models/mapping/normalizers/mods/title_normalizer.rb +91 -0
- data/lib/cocina/models/mapping/normalizers/mods_normalizer.rb +409 -0
- data/lib/cocina/models/mapping/purl.rb +27 -0
- data/lib/cocina/models/mapping/to_mods/access.rb +155 -0
- data/lib/cocina/models/mapping/to_mods/admin_metadata.rb +129 -0
- data/lib/cocina/models/mapping/to_mods/contributor.rb +49 -0
- data/lib/cocina/models/mapping/to_mods/description.rb +63 -0
- data/lib/cocina/models/mapping/to_mods/event.rb +200 -0
- data/lib/cocina/models/mapping/to_mods/form.rb +292 -0
- data/lib/cocina/models/mapping/to_mods/geographic.rb +151 -0
- data/lib/cocina/models/mapping/to_mods/id_generator.rb +25 -0
- data/lib/cocina/models/mapping/to_mods/identifier.rb +57 -0
- data/lib/cocina/models/mapping/to_mods/language.rb +82 -0
- data/lib/cocina/models/mapping/to_mods/mods_writer.rb +38 -0
- data/lib/cocina/models/mapping/to_mods/name_title_group.rb +29 -0
- data/lib/cocina/models/mapping/to_mods/name_writer.rb +228 -0
- data/lib/cocina/models/mapping/to_mods/note.rb +105 -0
- data/lib/cocina/models/mapping/to_mods/part_writer.rb +115 -0
- data/lib/cocina/models/mapping/to_mods/related_resource.rb +108 -0
- data/lib/cocina/models/mapping/to_mods/role_writer.rb +50 -0
- data/lib/cocina/models/mapping/to_mods/subject.rb +486 -0
- data/lib/cocina/models/mapping/to_mods/title.rb +260 -0
- data/lib/cocina/models/object_metadata.rb +2 -2
- data/lib/cocina/models/presentation.rb +2 -2
- data/lib/cocina/models/related_resource.rb +9 -9
- data/lib/cocina/models/release_tag.rb +4 -4
- data/lib/cocina/models/request_admin_policy.rb +1 -1
- data/lib/cocina/models/request_administrative.rb +1 -1
- data/lib/cocina/models/request_collection.rb +2 -2
- data/lib/cocina/models/request_description.rb +3 -3
- data/lib/cocina/models/request_dro.rb +4 -4
- data/lib/cocina/models/request_file.rb +5 -5
- data/lib/cocina/models/request_identification.rb +1 -1
- data/lib/cocina/models/sequence.rb +1 -1
- data/lib/cocina/models/source.rb +4 -4
- data/lib/cocina/models/standard.rb +5 -5
- data/lib/cocina/models/stanford_access.rb +2 -2
- data/lib/cocina/models/title.rb +13 -13
- data/lib/cocina/models/validators/associated_name_validator.rb +77 -0
- data/lib/cocina/models/validators/dark_validator.rb +4 -2
- data/lib/cocina/models/validators/open_api_validator.rb +0 -4
- data/lib/cocina/models/validators/validator.rb +1 -0
- data/lib/cocina/models/version.rb +1 -1
- data/lib/cocina/models/world_access.rb +2 -2
- data/lib/cocina/models.rb +4 -0
- data/lib/cocina/rspec/factories.rb +205 -0
- data/lib/cocina/rspec.rb +2 -0
- data/openapi.yml +4 -4
- metadata +97 -24
- data/docs/_config.yml +0 -1
- data/docs/maps/Agent.json +0 -18
- data/docs/maps/Collection.json +0 -240
- data/docs/maps/DRO.json +0 -316
- data/docs/maps/Description.json +0 -17
- data/docs/maps/File.json +0 -196
- data/docs/maps/Fileset.json +0 -143
- data/docs/maps/README.md +0 -7
- data/docs/maps/ReleaseTag.json +0 -39
- data/docs/maps/Sequence.json +0 -46
- data/docs/maps/Title.json +0 -18
- data/docs/sampleETD/foxml-export.xml +0 -935
- data/docs/sampleETD/foxml.xml +0 -3475
- data/docs/sampleETD/xn109qc9773_bibframe.ttl +0 -95
- data/docs/sampleETD/xn109qc9773_taco.json +0 -158
- data/lib/cocina/models/dro_rights_description_builder.rb +0 -67
- data/lib/cocina/models/rights_description_builder.rb +0 -81
- data/lib/cocina/models/title_builder.rb +0 -208
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cocina
|
4
|
+
module Models
|
5
|
+
module Mapping
|
6
|
+
module ToMods
|
7
|
+
# Maps adminMetadata from cocina to MODS XML recordInfo
|
8
|
+
class AdminMetadata
|
9
|
+
# @params [Nokogiri::XML::Builder] xml
|
10
|
+
# @params [Cocina::Models::DescriptiveAdminMetadata] admin_metadata
|
11
|
+
def self.write(xml:, admin_metadata:)
|
12
|
+
new(xml: xml, admin_metadata: admin_metadata).write
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(xml:, admin_metadata:)
|
16
|
+
@xml = xml
|
17
|
+
@admin_metadata = admin_metadata
|
18
|
+
end
|
19
|
+
|
20
|
+
def write
|
21
|
+
return unless admin_metadata
|
22
|
+
|
23
|
+
xml.recordInfo do
|
24
|
+
build_language
|
25
|
+
build_content_source
|
26
|
+
build_description_standard
|
27
|
+
build_record_origin
|
28
|
+
build_record_info_notes
|
29
|
+
build_event
|
30
|
+
build_identifier
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_reader :xml, :admin_metadata
|
37
|
+
|
38
|
+
def build_record_origin
|
39
|
+
Array(admin_metadata.note).select { |note| note.type == 'record origin' }.each do |note|
|
40
|
+
xml.recordOrigin note.value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_record_info_notes
|
45
|
+
record_info_notes = Array(admin_metadata.note)
|
46
|
+
# return unless record_info_notes
|
47
|
+
return if record_info_notes.empty?
|
48
|
+
|
49
|
+
record_info_notes.each do |info_note|
|
50
|
+
if info_note.valueAt.present?
|
51
|
+
xml.recordInfoNote nil, { 'xlink:href' => info_note.valueAt }
|
52
|
+
elsif info_note.type == 'record information'
|
53
|
+
xml.recordInfoNote info_note.value
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def build_content_source
|
59
|
+
Array(admin_metadata.contributor).each do |contributor|
|
60
|
+
source = contributor.name.first
|
61
|
+
xml.recordContentSource source.code || source.value, with_uri_info(source)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def build_description_standard
|
66
|
+
return if admin_metadata.metadataStandard.blank?
|
67
|
+
|
68
|
+
admin_metadata.metadataStandard.each do |standard|
|
69
|
+
xml.descriptionStandard standard.code || standard.value, with_uri_info(standard)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def build_event
|
74
|
+
build_event_for('creation', 'recordCreationDate')
|
75
|
+
build_event_for('modification', 'recordChangeDate')
|
76
|
+
end
|
77
|
+
|
78
|
+
def build_event_for(type, tag)
|
79
|
+
Array(admin_metadata.event).select { |note| note.type == type }.each do |event|
|
80
|
+
event.date.each do |date|
|
81
|
+
attributes = {}.tap do |attrs|
|
82
|
+
attrs[:encoding] = date.encoding&.code
|
83
|
+
end.compact
|
84
|
+
|
85
|
+
xml.public_send(tag, date.value, attributes)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def build_identifier
|
91
|
+
Array(admin_metadata.identifier).each do |identifier|
|
92
|
+
id_attributes = {
|
93
|
+
displayLabel: identifier.displayLabel,
|
94
|
+
source: identifier.uri ? 'uri' : Cocina::Models::Mapping::FromMods::IdentifierType.mods_type_for_cocina_type(identifier.type)
|
95
|
+
}.tap do |attrs|
|
96
|
+
attrs[:invalid] = 'yes' if identifier.status == 'invalid'
|
97
|
+
end.compact
|
98
|
+
xml.recordIdentifier identifier.value || identifier.uri, id_attributes
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def build_language
|
103
|
+
Array(admin_metadata.language).each do |language|
|
104
|
+
language_of_cataloging_attrs = {}
|
105
|
+
language_of_cataloging_attrs[:usage] = language.status if language.status
|
106
|
+
xml.languageOfCataloging language_of_cataloging_attrs do
|
107
|
+
language_attrs = with_uri_info(language, {})
|
108
|
+
xml.languageTerm language.value, language_attrs.merge(type: 'text') if language.value
|
109
|
+
xml.languageTerm language.code, language_attrs.merge(type: 'code') if language.code
|
110
|
+
if language.script
|
111
|
+
script_attrs = with_uri_info(language.script, {})
|
112
|
+
xml.scriptTerm language.script.value, script_attrs.merge(type: 'text')
|
113
|
+
xml.scriptTerm language.script.code, script_attrs.merge(type: 'code')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def with_uri_info(cocina, xml_attrs = {})
|
120
|
+
xml_attrs[:valueURI] = cocina.uri
|
121
|
+
xml_attrs[:authorityURI] = cocina.source&.uri
|
122
|
+
xml_attrs[:authority] = cocina.source&.code
|
123
|
+
xml_attrs.compact
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cocina
|
4
|
+
module Models
|
5
|
+
module Mapping
|
6
|
+
module ToMods
|
7
|
+
# Maps contributors from cocina to MODS XML
|
8
|
+
class Contributor
|
9
|
+
# one way mapping: MODS 'corporate' already maps to Cocina 'organization'
|
10
|
+
NAME_TYPE = Cocina::Models::Mapping::FromMods::Contributor::ROLES.invert.merge('event' => 'corporate').freeze
|
11
|
+
NAME_PART = Cocina::Models::Mapping::FromMods::Contributor::NAME_PART.invert.freeze
|
12
|
+
|
13
|
+
# NOTE: contributors in nameTitleGroups are output as part of Title.
|
14
|
+
# @params [Nokogiri::XML::Builder] xml
|
15
|
+
# @params [Array<Cocina::Models::Contributor>] contributors
|
16
|
+
# @params [Array<Cocina::Models::Title>] titles
|
17
|
+
# @params [IdGenerator] id_generator
|
18
|
+
def self.write(xml:, contributors:, titles:, id_generator:)
|
19
|
+
new(xml: xml, contributors: contributors, titles: titles, id_generator: id_generator).write
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(xml:, contributors:, titles:, id_generator:)
|
23
|
+
@xml = xml
|
24
|
+
@contributors = contributors
|
25
|
+
@titles = titles
|
26
|
+
@id_generator = id_generator
|
27
|
+
end
|
28
|
+
|
29
|
+
# NOTE: contributors in nameTitleGroups are output as part of Title.
|
30
|
+
def write
|
31
|
+
Array(contributors)
|
32
|
+
.reject do |contributor|
|
33
|
+
NameTitleGroup.in_name_title_group?(contributor: contributor,
|
34
|
+
titles: titles)
|
35
|
+
end
|
36
|
+
.each do |contributor|
|
37
|
+
NameWriter.write(xml: xml, contributor: contributor,
|
38
|
+
id_generator: id_generator)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_reader :xml, :contributors, :titles, :id_generator
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
module Cocina
|
6
|
+
module Models
|
7
|
+
module Mapping
|
8
|
+
module ToMods
|
9
|
+
# This transforms the DRO.description schema to MODS xml
|
10
|
+
class Description
|
11
|
+
# @param [Cocina::Models::Description] description
|
12
|
+
# @param [string] druid
|
13
|
+
# @return [Nokogiri::XML::Document]
|
14
|
+
def self.transform(description, druid)
|
15
|
+
new(description, druid).transform
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(description, druid)
|
19
|
+
@description = description
|
20
|
+
@druid = druid
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [Nokogiri::XML::Document]
|
24
|
+
def transform
|
25
|
+
Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
26
|
+
xml.mods(mods_attributes) do
|
27
|
+
ModsWriter.write(xml: xml, description: description, druid: druid)
|
28
|
+
end
|
29
|
+
end.doc
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :description, :druid
|
35
|
+
|
36
|
+
def mods_version
|
37
|
+
@mods_version ||= begin
|
38
|
+
notes = description.adminMetadata&.note || []
|
39
|
+
notes.select { |note| note.type == 'record origin' }.each do |note|
|
40
|
+
match = /MODS version (\d\.\d)/.match(note.value)
|
41
|
+
return match[1] if match
|
42
|
+
end
|
43
|
+
'3.7'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def mods_attributes
|
48
|
+
{
|
49
|
+
'xmlns' => 'http://www.loc.gov/mods/v3',
|
50
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
51
|
+
'xmlns:rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
|
52
|
+
'xmlns:xlink' => 'http://www.w3.org/1999/xlink',
|
53
|
+
'version' => mods_version,
|
54
|
+
'xsi:schemaLocation' => "http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-#{mods_version.sub(
|
55
|
+
'.', '-'
|
56
|
+
)}.xsd"
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cocina
|
4
|
+
module Models
|
5
|
+
module Mapping
|
6
|
+
module ToMods
|
7
|
+
# Maps events from cocina to MODS XML
|
8
|
+
class Event # rubocop:disable Metrics/ClassLength
|
9
|
+
# @params [Nokogiri::XML::Builder] xml
|
10
|
+
# @params [Array<Cocina::Models::Event>] events
|
11
|
+
# @params [IdGenerator] id_generator
|
12
|
+
def self.write(xml:, events:, id_generator:)
|
13
|
+
new(xml: xml, events: events, id_generator: id_generator).write
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(xml:, events:, id_generator:)
|
17
|
+
@xml = xml
|
18
|
+
@events = events
|
19
|
+
@id_generator = id_generator
|
20
|
+
end
|
21
|
+
|
22
|
+
def write
|
23
|
+
Array(events).each do |event|
|
24
|
+
if event.parallelEvent.present?
|
25
|
+
write_parallel(event, id_generator.next_altrepgroup)
|
26
|
+
else
|
27
|
+
write_basic(event, event.type)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :xml, :events, :id_generator
|
35
|
+
|
36
|
+
def write_basic(event, event_type)
|
37
|
+
names = Array(event.contributor).map { |contributor| contributor.name.first }
|
38
|
+
attributes = {
|
39
|
+
displayLabel: event.displayLabel,
|
40
|
+
eventType: event_type,
|
41
|
+
script: event.valueLanguage&.valueScript&.code,
|
42
|
+
lang: event.valueLanguage&.code
|
43
|
+
}.compact
|
44
|
+
|
45
|
+
write_event(event.type, event.date, event.location, names, event.note, attributes)
|
46
|
+
end
|
47
|
+
|
48
|
+
def write_parallel(event, alt_rep_group)
|
49
|
+
event.parallelEvent.each do |parallel_event|
|
50
|
+
attributes = {}.tap do |attrs|
|
51
|
+
attrs[:script] = parallel_event.valueLanguage&.valueScript&.code
|
52
|
+
attrs[:lang] = parallel_event.valueLanguage&.code
|
53
|
+
attrs[:altRepGroup] = alt_rep_group
|
54
|
+
attrs[:eventType] = event.type || parallel_event.type
|
55
|
+
attrs[:displayLabel] = event.displayLabel || parallel_event.displayLabel
|
56
|
+
end.compact
|
57
|
+
|
58
|
+
names = Array(parallel_event.contributor).map(&:name).flatten
|
59
|
+
write_event(parallel_event.type,
|
60
|
+
parallel_event.date,
|
61
|
+
parallel_event.location,
|
62
|
+
names,
|
63
|
+
parallel_event.note,
|
64
|
+
attributes)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# rubocop:disable Metrics/ParameterLists
|
69
|
+
def write_event(cocina_event_type, dates, locations, names, notes, attributes, is_parallel: false)
|
70
|
+
return if dates.blank? && locations.blank? && names.blank? && notes.blank?
|
71
|
+
|
72
|
+
xml.originInfo attributes do
|
73
|
+
Array(dates).each do |date|
|
74
|
+
write_basic_date(date, cocina_event_type)
|
75
|
+
end
|
76
|
+
Array(locations).each do |loc|
|
77
|
+
write_location(loc)
|
78
|
+
end
|
79
|
+
Array(names).each do |name|
|
80
|
+
xml.publisher name.value, name_attributes(name)
|
81
|
+
end
|
82
|
+
Array(notes).each do |note|
|
83
|
+
write_note(note)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
# rubocop:enable Metrics/ParameterLists
|
88
|
+
|
89
|
+
def write_note(note)
|
90
|
+
attributes = {}
|
91
|
+
attributes[:authority] = note.source.code if note&.source&.code
|
92
|
+
xml.send(note_tag_for(note), note.value, attributes)
|
93
|
+
end
|
94
|
+
|
95
|
+
def note_tag_for(note)
|
96
|
+
return 'copyrightDate' if note.type == 'copyright statement'
|
97
|
+
return note.type if note.type
|
98
|
+
|
99
|
+
'edition'
|
100
|
+
end
|
101
|
+
|
102
|
+
def write_location(location)
|
103
|
+
place_attrs = {}.tap do |attrs|
|
104
|
+
attrs[:supplied] = 'yes' if location.type == 'supplied'
|
105
|
+
end
|
106
|
+
xml.place place_attrs do
|
107
|
+
placeterm_attrs = {}
|
108
|
+
placeterm_attrs[:authority] = location.source.code if location.source&.code
|
109
|
+
placeterm_attrs[:authorityURI] = location.source.uri if location.source&.uri
|
110
|
+
placeterm_attrs[:valueURI] = location.uri if location.uri
|
111
|
+
|
112
|
+
placeterm_text_attrs = placeterm_attrs.merge({ type: 'text' })
|
113
|
+
xml.placeTerm location.value, placeterm_text_attrs if location.value
|
114
|
+
|
115
|
+
placeterm_code_attrs = placeterm_attrs.merge({ type: 'code' })
|
116
|
+
xml.placeTerm location.code, placeterm_code_attrs if location.code
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def write_basic_date(date, cocina_event_type)
|
121
|
+
if date.structuredValue.present?
|
122
|
+
structured_val_attribs = {
|
123
|
+
encoding: date.encoding,
|
124
|
+
qualifier: date.qualifier,
|
125
|
+
type: date.type
|
126
|
+
}
|
127
|
+
date_type = cocina_event_type
|
128
|
+
date_type = date.type if date.type.present?
|
129
|
+
date_range(date.structuredValue, date_type, structured_val_attribs)
|
130
|
+
else
|
131
|
+
write_date_element(date, cocina_event_type)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# @param [Hash] structured_val_attribs - populated when structuredValue parent has attributes for individual date elements
|
136
|
+
def write_date_element(date, cocina_event_type, structured_val_attribs = {})
|
137
|
+
value = date.value
|
138
|
+
element_name = date_element_name(date, cocina_event_type, structured_val_attribs[:type])
|
139
|
+
attributes = {}.tap do |attrs|
|
140
|
+
attrs[:encoding] = date.encoding&.code || structured_val_attribs[:encoding]&.code
|
141
|
+
attrs[:qualifier] = date.qualifier || structured_val_attribs[:qualifier]
|
142
|
+
attrs[:keyDate] = 'yes' if date.status == 'primary'
|
143
|
+
attrs[:type] = date_type_attr(date, element_name)
|
144
|
+
attrs[:calendar] = calendar_attr(date)
|
145
|
+
attrs[:point] = date.type if %w[start end].include?(date.type)
|
146
|
+
end.compact
|
147
|
+
xml.public_send(element_name, value, attributes)
|
148
|
+
end
|
149
|
+
|
150
|
+
def date_element_name(date, cocina_event_type, structured_val_type)
|
151
|
+
el_name = Cocina::Models::Mapping::FromMods::Event::DATE_ELEMENTS_2_TYPE.key(structured_val_type)
|
152
|
+
return el_name if el_name.present?
|
153
|
+
|
154
|
+
el_name = Cocina::Models::Mapping::FromMods::Event::DATE_ELEMENTS_2_TYPE.key(date.type)
|
155
|
+
return el_name if el_name.present?
|
156
|
+
|
157
|
+
# the date type overrides the eventType for choosing date flavor, even if it ends up with dateOther
|
158
|
+
return 'dateOther' if date.type.present?
|
159
|
+
|
160
|
+
if cocina_event_type.present?
|
161
|
+
el_name = Cocina::Models::Mapping::FromMods::Event::DATE_ELEMENTS_2_TYPE.key(cocina_event_type)
|
162
|
+
return el_name if el_name.present?
|
163
|
+
end
|
164
|
+
|
165
|
+
'dateOther'
|
166
|
+
end
|
167
|
+
|
168
|
+
# MODS only allows a type attr on dateOther; no other date flavors
|
169
|
+
def date_type_attr(cocina_date, date_element_name)
|
170
|
+
return unless date_element_name == 'dateOther'
|
171
|
+
|
172
|
+
cocina_date.type if cocina_date.type.present? && %w[start end].exclude?(cocina_date.type)
|
173
|
+
end
|
174
|
+
|
175
|
+
def calendar_attr(cocina_date)
|
176
|
+
return if cocina_date.note.blank?
|
177
|
+
|
178
|
+
cocina_date.note.each do |note|
|
179
|
+
return note.value if note.type == 'calendar'
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def date_range(dates, cocina_event_type, structured_val_attribs)
|
184
|
+
dates.each do |date|
|
185
|
+
write_date_element(date, cocina_event_type, structured_val_attribs)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def name_attributes(cocina_name)
|
190
|
+
{
|
191
|
+
lang: cocina_name&.valueLanguage&.code,
|
192
|
+
script: cocina_name&.valueLanguage&.valueScript&.code,
|
193
|
+
transliteration: cocina_name&.standard&.value
|
194
|
+
}.compact
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|