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,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cocina
|
4
|
+
module Models
|
5
|
+
module Mapping
|
6
|
+
module FromMods
|
7
|
+
# Builds cocina identifier
|
8
|
+
class IdentifierBuilder
|
9
|
+
# @param [Nokogiri::XML::Element] identifier_element identifier element
|
10
|
+
# @return [Hash] a hash that can be mapped to a cocina model
|
11
|
+
def self.build_from_identifier(identifier_element:)
|
12
|
+
new(identifier_element: identifier_element, type: identifier_element[:type]).build
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [Nokogiri::XML::Element] identifier_element recordIdentifier element
|
16
|
+
# @return [Hash] a hash that can be mapped to a cocina model
|
17
|
+
def self.build_from_record_identifier(identifier_element:)
|
18
|
+
new(identifier_element: identifier_element, type: identifier_element[:source]).build
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param [Nokogiri::XML::Element] identifier_element nameIdentifier element
|
22
|
+
# @return [Hash] a hash that can be mapped to a cocina model
|
23
|
+
def self.build_from_name_identifier(identifier_element:)
|
24
|
+
new(identifier_element: identifier_element, type: identifier_element[:type]).build
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(identifier_element:, type:)
|
28
|
+
@identifier_element = identifier_element
|
29
|
+
@with_note = with_note
|
30
|
+
@cocina_type, @mods_type, = types_for(type)
|
31
|
+
end
|
32
|
+
|
33
|
+
def build
|
34
|
+
return if identifier_element.text.blank? && identifier_element.attributes.size.zero?
|
35
|
+
|
36
|
+
{
|
37
|
+
displayLabel: identifier_element['displayLabel']
|
38
|
+
}.tap do |attrs|
|
39
|
+
if cocina_type == 'uri'
|
40
|
+
attrs[:uri] = identifier_element.text
|
41
|
+
else
|
42
|
+
attrs[:type] = cocina_type
|
43
|
+
attrs[:value] = identifier_element.text
|
44
|
+
attrs[:source] = build_source
|
45
|
+
end
|
46
|
+
attrs[:status] = 'invalid' if identifier_element['invalid'] == 'yes'
|
47
|
+
end.compact
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
attr_reader :identifier_element, :with_note, :cocina_type, :mods_type
|
53
|
+
|
54
|
+
def types_for(type)
|
55
|
+
return ['uri', 'uri', IdentifierType::STANDARD_IDENTIFIER_SCHEMES] if type == 'uri'
|
56
|
+
|
57
|
+
IdentifierType.cocina_type_for_mods_type(type)
|
58
|
+
end
|
59
|
+
|
60
|
+
def build_source
|
61
|
+
{
|
62
|
+
uri: identifier_element['typeURI']
|
63
|
+
}.tap do |props|
|
64
|
+
props[:code] = mods_type unless props[:uri]
|
65
|
+
end.compact.presence
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,292 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cocina
|
4
|
+
module Models
|
5
|
+
module Mapping
|
6
|
+
module FromMods
|
7
|
+
# Maps identifier types
|
8
|
+
class IdentifierType # rubocop:disable Metrics/ClassLength
|
9
|
+
COCINA_TO_STANDARD_IDENTIFIER_SCHEMES = {
|
10
|
+
'AGROVOC ID' => 'agrovoc',
|
11
|
+
'AllMovie ID' => 'allmovie',
|
12
|
+
'AllMusic ID' => 'allmusic',
|
13
|
+
'AlloCiné ID' => 'allocine',
|
14
|
+
'American National Biography Online ID' => 'amnbo',
|
15
|
+
'ANSI' => 'ansi',
|
16
|
+
'Apis ID' => 'apis',
|
17
|
+
'Artsy ID' => 'artsy',
|
18
|
+
'BFI ID' => 'bfi',
|
19
|
+
'Biblioteca Nacional de España ID' => 'datoses',
|
20
|
+
'Biographical Directory of the United States Congress ID' => 'bdusc',
|
21
|
+
'BnF catalogue général ID' => 'bnfcg',
|
22
|
+
'CANTIC ID' => 'cantic',
|
23
|
+
'CGNDB ID' => 'cgndb',
|
24
|
+
'Danacode ID' => 'danacode',
|
25
|
+
'Det Danske Filminstitut Filmdatabasen ID' => 'dkfilm',
|
26
|
+
'Discogs ID' => 'discogs',
|
27
|
+
'DOI' => 'doi',
|
28
|
+
'EAN' => 'ean',
|
29
|
+
'EIDR ID' => 'eidr',
|
30
|
+
'FAST' => 'fast',
|
31
|
+
'Filmportal ID' => 'filmport',
|
32
|
+
'Find a Grave ID' => 'findagr',
|
33
|
+
'Freebase ID' => 'freebase',
|
34
|
+
'Geographic Names Database ID' => 'geogndb',
|
35
|
+
'GeoNames ID' => 'geonames',
|
36
|
+
'GND ID' => 'gnd',
|
37
|
+
'GNIS ID' => 'gnis',
|
38
|
+
'Gran enciclopèdia catalana ID' => 'gec',
|
39
|
+
'GTIN-14 ID' => 'gtin-14',
|
40
|
+
'Handle' => 'hdl',
|
41
|
+
'IBDB ID' => 'ibdb',
|
42
|
+
'IdRef' => 'idref',
|
43
|
+
'IMDb ID' => 'imdb',
|
44
|
+
'ISAN' => 'isan',
|
45
|
+
'ISBN' => 'isbn',
|
46
|
+
'ISBN registrant element ID' => 'isbnre',
|
47
|
+
'ISIL' => 'isil',
|
48
|
+
'ISMN' => 'ismn',
|
49
|
+
'ISNI' => 'isni',
|
50
|
+
'ISO' => 'iso',
|
51
|
+
'ISRC' => 'isrc',
|
52
|
+
'ISSN' => 'issn',
|
53
|
+
'ISSN-L' => 'issn-l',
|
54
|
+
'ISTC' => 'istc',
|
55
|
+
'ISWC' => 'iswc',
|
56
|
+
'ITAR' => 'itar',
|
57
|
+
'KinoPoisk ID' => 'kinipo',
|
58
|
+
'LC Manuscript Division ID' => 'lcmd',
|
59
|
+
'LCCN' => 'lccn',
|
60
|
+
'Libraries Australia ID' => 'libaus',
|
61
|
+
'local' => 'local',
|
62
|
+
'matrix number' => 'matrix-number',
|
63
|
+
'MOMA ID' => 'moma',
|
64
|
+
'Munzinger ID' => 'munzing',
|
65
|
+
'music plate' => 'music-plate',
|
66
|
+
'music publisher' => 'music-publisher',
|
67
|
+
'MusicBrainz ID' => 'musicb',
|
68
|
+
'Número de Identificación de las Publicaciones Oficiales ID' => 'nipo',
|
69
|
+
'National Gallery of Art ID' => 'nga',
|
70
|
+
'National Portrait Gallery ID' => 'npg',
|
71
|
+
'NNDB ID' => 'nndb',
|
72
|
+
'ODNB ID' => 'odnb',
|
73
|
+
'OpenStreetMap ID' => 'opensm',
|
74
|
+
'ORCID' => 'orcid',
|
75
|
+
'Oxford DNB Index ID' => 'oxforddnb',
|
76
|
+
'PORT.hu ID' => 'porthu',
|
77
|
+
'RBMS Binding Term' => 'rbmsbt',
|
78
|
+
'RBMS Genre Terms ID' => 'rbmsgt',
|
79
|
+
'RBMS Paper Term' => 'rbmspt',
|
80
|
+
'RBMS Printing and Publishing Term' => 'rbmsppe',
|
81
|
+
'RBMS Provenance Evidence' => 'rbmspe',
|
82
|
+
'RBMS Relationship Designator' => 'rbmsrd',
|
83
|
+
'RBMS Type Evidence' => 'rbmste',
|
84
|
+
'ResearcherID' => 'rid',
|
85
|
+
'RKDartists ID' => 'rkda',
|
86
|
+
'Scholar Universe ID' => 'scholaru',
|
87
|
+
'Scope ID' => 'scope',
|
88
|
+
'Scopus Author ID' => 'scopus',
|
89
|
+
'SICI' => 'sici',
|
90
|
+
'Smithsonian American Art Museum ID' => 'saam',
|
91
|
+
'sound recording issue number' => 'issue-number',
|
92
|
+
'Sports Reference: Baseball ID' => 'sprfbsb',
|
93
|
+
'Sports Reference: Basketball ID' => 'sprfbsk',
|
94
|
+
'Sports Reference: College Basketball ID' => 'sprfcbb',
|
95
|
+
'Sports Reference: College Football ID' => 'sprfcfb',
|
96
|
+
'Sports Reference: Hockey ID' => 'sprfhoc',
|
97
|
+
'Sports Reference: Olympic Sports ID' => 'sprfoly',
|
98
|
+
'Sports Reference: Pro Football ID' => 'sprfpfb',
|
99
|
+
'Spotify ID' => 'spotify',
|
100
|
+
'Standard Technical Report Number' => 'strn',
|
101
|
+
'stock number' => 'stock-number',
|
102
|
+
'Svensk Filmdatabas ID' => 'svfilm',
|
103
|
+
'Swets (Netherlands) ID' => 'swets',
|
104
|
+
'Tate Artist ID' => 'tatearid',
|
105
|
+
'TGN' => 'gettytgn',
|
106
|
+
'Theatricalia ID' => 'theatr',
|
107
|
+
'Trove ID' => 'trove',
|
108
|
+
'U.S. National Gazetteer Feature Name ID' => 'natgazfid',
|
109
|
+
'ULAN' => 'gettyulan',
|
110
|
+
'UPC' => 'upc',
|
111
|
+
'URI' => 'uri',
|
112
|
+
'URN' => 'urn',
|
113
|
+
'VIAF' => 'viaf',
|
114
|
+
'video recording number' => 'videorecording-identifier',
|
115
|
+
'Web NDL Authority' => 'wndla',
|
116
|
+
'Wikidata' => 'wikidata'
|
117
|
+
}.freeze
|
118
|
+
|
119
|
+
COCINA_TO_STANDARD_IDENTIFIER_SOURCE_CODES = {
|
120
|
+
'AAT' => 'gettyaat',
|
121
|
+
'actionable ISBN' => 'isbn-a',
|
122
|
+
'AGORHA ID' => 'agorha',
|
123
|
+
'Agricultural Thesaurus and Glossary' => 'atg',
|
124
|
+
'archINFORM location ID' => 'archinl',
|
125
|
+
'archINFORM person ID' => 'archinpe',
|
126
|
+
'archINFORM project ID' => 'archinpr',
|
127
|
+
'Archnet authority' => 'archna',
|
128
|
+
'Archnet site ID' => 'archns',
|
129
|
+
'ARK' => 'ark',
|
130
|
+
'ARK ID' => 'arkid',
|
131
|
+
'Art UK Artists ID' => 'artukart',
|
132
|
+
'Art UK Artworks ID' => 'artukaw',
|
133
|
+
'BALaT People & Institutions ID' => 'balat',
|
134
|
+
'BBC Things ID' => 'bbcth',
|
135
|
+
'Belvedere Artist ID' => 'belvku',
|
136
|
+
'Belvedere Work ID' => 'belvwrk',
|
137
|
+
'Benezit Dictionary of Artists ID' => 'benezit',
|
138
|
+
'BIBBI authority' => 'bibbi',
|
139
|
+
'Biographies of the Entomologists of the World ID' => 'bew',
|
140
|
+
'Biography portal of the Netherlands ID' => 'bpn',
|
141
|
+
'British Standards Institution ID' => 'bsi',
|
142
|
+
'CABI Thesaurus ID' => 'cabt',
|
143
|
+
'Canadiana Authority' => 'cana',
|
144
|
+
'CERL Thesaurus term' => 'cerl',
|
145
|
+
'Cesko-Slovenská filmová databáze ID' => 'csfdcz',
|
146
|
+
'Clara: Database of Women Artists ID' => 'clara',
|
147
|
+
'Collective Biographies of Women Persons ID' => 'cbwpid',
|
148
|
+
'Currículo Lattes ID' => 'lattes',
|
149
|
+
'Dictionnaire des peintres belges ID' => 'dpb',
|
150
|
+
'Digital atlas of the Roman Empire ID' => 'darome',
|
151
|
+
'Early Modern Letters Online ID' => 'emlo',
|
152
|
+
'European Case Law Identifier ID' => 'ecli',
|
153
|
+
'Fide Chess Profile ID' => 'fidecp',
|
154
|
+
'Film Affinity ID' => 'filmaff',
|
155
|
+
'FIS Athlete ID' => 'fisa',
|
156
|
+
'Gemeenschappelijke Thesaurus Audiovisuele Archieven ID' => 'gtaa',
|
157
|
+
'Global Agricultural Concept Scheme ID' => 'gacsch',
|
158
|
+
'Goodreads Author ID' => 'goodra',
|
159
|
+
'Great Britain National Archives ID' => 'nagb',
|
160
|
+
'Great Russian Encyclopedia ID' => 'bigenc',
|
161
|
+
'IAAF Athletes ID' => 'iaafa',
|
162
|
+
'Iconography Authority' => 'iconauth',
|
163
|
+
'Identificativo SBN (Servizio bibliotecario nazionale)' => 'isbnsbn',
|
164
|
+
'ISFDB author directory ID' => 'isfdbau',
|
165
|
+
'ISFDB award directory ID' => 'isfdbaw',
|
166
|
+
'ISFDB magazine directory ID' => 'isfdbma',
|
167
|
+
'ISFDB publisher directory ID' => 'isfdbpu',
|
168
|
+
'J. Paul Getty Museum Artist ID' => 'gettyart',
|
169
|
+
'J. Paul Getty Museum Object ID' => 'gettyobj',
|
170
|
+
'Kunstindeks Danmark Artist ID' => 'kda',
|
171
|
+
'Kunstindeks Danmark Work ID' => 'kdw',
|
172
|
+
'Legal entity identifier' => 'lei',
|
173
|
+
'Marine Gazetteer ID' => 'margaz',
|
174
|
+
'MESH' => 'mesh',
|
175
|
+
'MovieMeter Film ID' => 'moviemetf',
|
176
|
+
'MovieMeter Regisseur ID' => 'moviemetr',
|
177
|
+
"Musée d'Orsay Catalogue des oeuvres fiche oeuvre" => 'mocofo',
|
178
|
+
"Musée d'Orsay Répertoire des artistes notice artiste" => 'morana',
|
179
|
+
'Music Sales Classical ID' => 'muscl',
|
180
|
+
'National Gallery of Victoria Artist ID' => 'ngva',
|
181
|
+
'National Gallery of Victoria Work ID' => 'ngvw',
|
182
|
+
'OFDb ID' => 'ofdb',
|
183
|
+
'ONIX ID' => 'onix',
|
184
|
+
'Pacific Coast Architecture Database building ID' => 'pcadbu',
|
185
|
+
'Pacific Coast Architecture Database firm ID' => 'pcadpf',
|
186
|
+
'Pacific Coast Architecture Database person ID' => 'pcadpe',
|
187
|
+
'PermID' => 'permid',
|
188
|
+
'Personen uit de Nederlandse Thesaurus van Auteursnamen ID' => 'pnta',
|
189
|
+
'PIC ID' => 'picnypl',
|
190
|
+
'Pleiades ID' => 'pleiades',
|
191
|
+
'Prabook ID' => 'prabook',
|
192
|
+
'Quan Guo Bao Kan Suo Yin ID' => 'cnbksy',
|
193
|
+
'ROR' => 'ror',
|
194
|
+
'Russian National Heritage Registry for Books ID' => 'knpam',
|
195
|
+
'S2A3 Biographical Database of Southern African Science ID' => 's2a3bd',
|
196
|
+
'Science Museum Group People ID' => 'smgp',
|
197
|
+
'Semantic Scholar author ID' => 'ssaut',
|
198
|
+
'SNAC' => 'snac',
|
199
|
+
'STW thesaurus ID' => 'stw',
|
200
|
+
'U.S. National Archives Catalog ID' => 'nacat',
|
201
|
+
'UNESCO thesaurus ID' => 'unescot',
|
202
|
+
'Verzeichnis der Drucke des 16. Jahrhunderts ID' => 'vd16',
|
203
|
+
'Verzeichnis der Drucke des 17. Jahrhunderts ID' => 'vd17',
|
204
|
+
'Verzeichnis der Drucke des 18. Jahrhunderts ID' => 'vd18',
|
205
|
+
'VGMdb artist ID' => 'vgmdb',
|
206
|
+
'X Games Athlete ID' => 'xgamea',
|
207
|
+
'ZooBank author ID' => 'zbaut'
|
208
|
+
}.freeze
|
209
|
+
|
210
|
+
OTHER_COCINA_TYPES = [
|
211
|
+
'arXiv',
|
212
|
+
'audio issue number',
|
213
|
+
'audio take',
|
214
|
+
'award number',
|
215
|
+
'barcode',
|
216
|
+
'BIBCODE',
|
217
|
+
'CODEN',
|
218
|
+
'copyright number',
|
219
|
+
'CrossRef Funder ID',
|
220
|
+
'EAN13',
|
221
|
+
'EISSN',
|
222
|
+
'ETD ID',
|
223
|
+
'fingerprint',
|
224
|
+
'GRID',
|
225
|
+
'IGSN',
|
226
|
+
'LC Overseas Acquisition ID',
|
227
|
+
'LISID',
|
228
|
+
'LISSN',
|
229
|
+
'music distributor number',
|
230
|
+
'music opus number',
|
231
|
+
'music serial number',
|
232
|
+
'music thematic number',
|
233
|
+
'NBN',
|
234
|
+
'OCLC',
|
235
|
+
'other system control number',
|
236
|
+
'PMID',
|
237
|
+
'postal registration',
|
238
|
+
'publisher number',
|
239
|
+
'PURL',
|
240
|
+
'report number',
|
241
|
+
'SIRSI',
|
242
|
+
'STM',
|
243
|
+
'study number',
|
244
|
+
'Symphony authority file identifier',
|
245
|
+
'Symphony catkey',
|
246
|
+
'URL',
|
247
|
+
'W3 ID'
|
248
|
+
].freeze
|
249
|
+
|
250
|
+
ALL_COCINA_TYPES = OTHER_COCINA_TYPES + COCINA_TO_STANDARD_IDENTIFIER_SOURCE_CODES.keys + COCINA_TO_STANDARD_IDENTIFIER_SCHEMES.keys
|
251
|
+
|
252
|
+
STANDARD_IDENTIFIER_SOURCE_CODES = 'standard identifier source codes'
|
253
|
+
STANDARD_IDENTIFIER_SCHEMES = 'standard identifier schemes'
|
254
|
+
COCINA = 'cocina'
|
255
|
+
|
256
|
+
# @param [String] mods_type
|
257
|
+
# @return [String, String, String] cocina type or nil, matched mods type (with correct case) or nil, identifier source or nil
|
258
|
+
def self.cocina_type_for_mods_type(mods_type)
|
259
|
+
return [nil, nil, nil] if mods_type.blank?
|
260
|
+
|
261
|
+
# Try to find a standard identifier scheme type (case insensitive)
|
262
|
+
COCINA_TO_STANDARD_IDENTIFIER_SCHEMES.each_pair do |cocina_type, check_mods_type|
|
263
|
+
if check_mods_type&.downcase == mods_type.downcase
|
264
|
+
return [cocina_type, check_mods_type,
|
265
|
+
STANDARD_IDENTIFIER_SCHEMES]
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Try to find a standard identifier scheme type (case insensitive)
|
270
|
+
COCINA_TO_STANDARD_IDENTIFIER_SOURCE_CODES.each_pair do |cocina_type, check_mods_type|
|
271
|
+
if check_mods_type&.downcase == mods_type.downcase
|
272
|
+
return [cocina_type, check_mods_type,
|
273
|
+
STANDARD_IDENTIFIER_SOURCE_CODES]
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
# Try to find a Cocina type (case insensitive)
|
278
|
+
ALL_COCINA_TYPES.each do |cocina_type|
|
279
|
+
return [cocina_type, nil, COCINA] if cocina_type.casecmp(mods_type).zero?
|
280
|
+
end
|
281
|
+
|
282
|
+
[mods_type, nil, nil]
|
283
|
+
end
|
284
|
+
|
285
|
+
def self.mods_type_for_cocina_type(cocina_type)
|
286
|
+
COCINA_TO_STANDARD_IDENTIFIER_SCHEMES[cocina_type] || COCINA_TO_STANDARD_IDENTIFIER_SOURCE_CODES[cocina_type] || cocina_type
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cocina
|
4
|
+
module Models
|
5
|
+
module Mapping
|
6
|
+
module FromMods
|
7
|
+
# Maps languages
|
8
|
+
class Language
|
9
|
+
# @param [Nokogiri::XML::Element] resource_element mods or relatedItem element
|
10
|
+
# @param [Cocina::Models::Mapping::FromMods::DescriptionBuilder] description_builder
|
11
|
+
# @param [String] purl
|
12
|
+
# @return [Hash] a hash that can be mapped to a cocina model
|
13
|
+
def self.build(resource_element:, description_builder:, purl: nil)
|
14
|
+
new(resource_element: resource_element, description_builder: description_builder).build
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(resource_element:, description_builder:)
|
18
|
+
@resource_element = resource_element
|
19
|
+
@notifier = description_builder.notifier
|
20
|
+
end
|
21
|
+
|
22
|
+
def build
|
23
|
+
languages = resource_element.xpath('mods:language', mods: Description::DESC_METADATA_NS).map do |lang_node|
|
24
|
+
Cocina::Models::Mapping::FromMods::LanguageTerm.build(language_element: lang_node, notifier: notifier)
|
25
|
+
end
|
26
|
+
Primary.adjust(languages, 'language', notifier)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :resource_element, :notifier
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cocina
|
4
|
+
module Models
|
5
|
+
module Mapping
|
6
|
+
module FromMods
|
7
|
+
# Maps lang and script attributes
|
8
|
+
class LanguageScript
|
9
|
+
# @param [Nokogiri::XML::Element] element that may have lang or script attributes
|
10
|
+
# @param [Cocina::Models::Mapping::FromMods::DescriptionBuilder] description_builder
|
11
|
+
# @return [Hash] a hash that can be mapped to a cocina model for a valueLanguage
|
12
|
+
def self.build(node:)
|
13
|
+
return nil unless node['lang'].present? || node['script'].present?
|
14
|
+
|
15
|
+
{}.tap do |value_language|
|
16
|
+
if node['lang'].present?
|
17
|
+
value_language[:code] = node['lang']
|
18
|
+
value_language[:source] = { code: 'iso639-2b' }
|
19
|
+
end
|
20
|
+
if node['script'].present?
|
21
|
+
value_language[:valueScript] =
|
22
|
+
{ code: node['script'], source: { code: 'iso15924' } }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cocina
|
4
|
+
module Models
|
5
|
+
module Mapping
|
6
|
+
module FromMods
|
7
|
+
# Maps language term attributes
|
8
|
+
class LanguageTerm
|
9
|
+
# @param [Nokogiri::XML::Element] language_element language or languageOfCataloging element
|
10
|
+
# @param [Cocina::Models::Mapping::ErrorNotifier] notifier
|
11
|
+
# @return [Hash] a hash that can be mapped to a cocina model
|
12
|
+
def self.build(language_element:, notifier:)
|
13
|
+
new(language_element: language_element, notifier: notifier).build
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(language_element:, notifier:)
|
17
|
+
@language_element = language_element
|
18
|
+
@notifier = notifier
|
19
|
+
end
|
20
|
+
|
21
|
+
def build
|
22
|
+
attribs = lang_term_attributes
|
23
|
+
attribs[:status] = status
|
24
|
+
attribs[:script] = script_term_attributes
|
25
|
+
attribs.compact
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :language_element, :notifier
|
31
|
+
|
32
|
+
def lang_term_attributes
|
33
|
+
code_language_term = language_element.xpath('./mods:languageTerm[@type="code"]',
|
34
|
+
mods: Description::DESC_METADATA_NS).first
|
35
|
+
text_language_term = language_element.xpath('./mods:languageTerm[@type="text"]',
|
36
|
+
mods: Description::DESC_METADATA_NS).first
|
37
|
+
if code_language_term.nil? && text_language_term.nil?
|
38
|
+
notifier.warn('languageTerm missing type')
|
39
|
+
code_language_term = language_element.xpath('./mods:languageTerm', mods: Description::DESC_METADATA_NS).first
|
40
|
+
end
|
41
|
+
|
42
|
+
{
|
43
|
+
code: code_language_term&.text,
|
44
|
+
value: text_language_term&.text,
|
45
|
+
uri: ValueURI.sniff(language_value_uri_for(code_language_term, text_language_term), notifier),
|
46
|
+
appliesTo: language_applies_to,
|
47
|
+
displayLabel: language_element['displayLabel']
|
48
|
+
}.tap do |attrs|
|
49
|
+
source = language_source_for(code_language_term, text_language_term)
|
50
|
+
attrs[:source] = source if source.present?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def script_term_attributes
|
55
|
+
script_term_nodes = language_element.xpath('mods:scriptTerm', mods: Description::DESC_METADATA_NS)
|
56
|
+
|
57
|
+
return if script_term_nodes.blank?
|
58
|
+
|
59
|
+
code, value, authority = nil
|
60
|
+
script_term_nodes.each do |script_term_node|
|
61
|
+
code ||= script_term_node.content if script_term_node['type'] == 'code'
|
62
|
+
value ||= script_term_node.content if script_term_node['type'] == 'text'
|
63
|
+
authority ||= script_term_node['authority']
|
64
|
+
end
|
65
|
+
source = { code: authority } if authority
|
66
|
+
{
|
67
|
+
code: code,
|
68
|
+
value: value,
|
69
|
+
source: source
|
70
|
+
}.compact
|
71
|
+
end
|
72
|
+
|
73
|
+
# this can be present for type text and/or code, but we only want one.
|
74
|
+
def language_value_uri_for(code_language_term, text_language_term)
|
75
|
+
code_language_term&.attribute('valueURI')&.to_s || text_language_term&.attribute('valueURI')&.to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
def language_applies_to
|
79
|
+
value = language_element['objectPart']
|
80
|
+
[value: value] if value.present?
|
81
|
+
end
|
82
|
+
|
83
|
+
def language_source_for(code_language_term, text_language_term)
|
84
|
+
{
|
85
|
+
code: code_language_term&.attribute('authority')&.to_s || text_language_term&.attribute('authority')&.to_s,
|
86
|
+
uri: code_language_term&.attribute('authorityURI')&.to_s || text_language_term&.attribute('authorityURI')&.to_s
|
87
|
+
|
88
|
+
}.compact
|
89
|
+
end
|
90
|
+
|
91
|
+
def status
|
92
|
+
status_value = language_element[:usage] || language_element[:status]
|
93
|
+
return unless status_value
|
94
|
+
|
95
|
+
status_value.downcase.tap do |value|
|
96
|
+
if status_value != value
|
97
|
+
notifier.warn("#{language_element.name} usage attribute not downcased",
|
98
|
+
{ value: language_element[:usage] })
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|