cocina-models 0.74.0 → 0.76.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +40 -11
  3. data/.rubocop_todo.yml +71 -2
  4. data/README.md +19 -3
  5. data/cocina-models.gemspec +2 -0
  6. data/description_types.yml +167 -39
  7. data/docs/description_types.md +470 -216
  8. data/lib/cocina/generator/generator.rb +7 -15
  9. data/lib/cocina/generator/schema.rb +1 -3
  10. data/lib/cocina/generator/schema_base.rb +0 -8
  11. data/lib/cocina/generator/schema_ref.rb +1 -1
  12. data/lib/cocina/generator/schema_value.rb +14 -4
  13. data/lib/cocina/models/access.rb +4 -4
  14. data/lib/cocina/models/admin_policy.rb +1 -1
  15. data/lib/cocina/models/admin_policy_access_template.rb +7 -7
  16. data/lib/cocina/models/admin_policy_administrative.rb +1 -1
  17. data/lib/cocina/models/admin_policy_with_metadata.rb +3 -3
  18. data/lib/cocina/models/builders/dro_rights_description_builder.rb +69 -0
  19. data/lib/cocina/models/builders/name_title_group_builder.rb +130 -0
  20. data/lib/cocina/models/builders/rights_description_builder.rb +83 -0
  21. data/lib/cocina/models/builders/title_builder.rb +211 -0
  22. data/lib/cocina/models/citation_only_access.rb +2 -2
  23. data/lib/cocina/models/collection_access.rb +4 -4
  24. data/lib/cocina/models/collection_identification.rb +1 -1
  25. data/lib/cocina/models/collection_with_metadata.rb +2 -2
  26. data/lib/cocina/models/contributor.rb +4 -4
  27. data/lib/cocina/models/controlled_digital_lending_access.rb +2 -2
  28. data/lib/cocina/models/dark_access.rb +4 -4
  29. data/lib/cocina/models/description.rb +3 -3
  30. data/lib/cocina/models/descriptive_basic_value.rb +13 -13
  31. data/lib/cocina/models/descriptive_parallel_contributor.rb +5 -5
  32. data/lib/cocina/models/descriptive_parallel_event.rb +3 -3
  33. data/lib/cocina/models/descriptive_value.rb +13 -13
  34. data/lib/cocina/models/descriptive_value_language.rb +6 -6
  35. data/lib/cocina/models/dro.rb +1 -1
  36. data/lib/cocina/models/dro_access.rb +8 -8
  37. data/lib/cocina/models/dro_with_metadata.rb +3 -3
  38. data/lib/cocina/models/embargo.rb +5 -5
  39. data/lib/cocina/models/event.rb +3 -3
  40. data/lib/cocina/models/file.rb +4 -4
  41. data/lib/cocina/models/file_access.rb +4 -4
  42. data/lib/cocina/models/identification.rb +2 -2
  43. data/lib/cocina/models/language.rb +12 -12
  44. data/lib/cocina/models/location_based_access.rb +1 -1
  45. data/lib/cocina/models/location_based_download_access.rb +1 -1
  46. data/lib/cocina/models/mapping/error_notifier.rb +36 -0
  47. data/lib/cocina/models/mapping/from_mods/access.rb +177 -0
  48. data/lib/cocina/models/mapping/from_mods/admin_metadata.rb +217 -0
  49. data/lib/cocina/models/mapping/from_mods/alt_rep_group.rb +26 -0
  50. data/lib/cocina/models/mapping/from_mods/authority.rb +51 -0
  51. data/lib/cocina/models/mapping/from_mods/contributor.rb +161 -0
  52. data/lib/cocina/models/mapping/from_mods/description.rb +99 -0
  53. data/lib/cocina/models/mapping/from_mods/description_builder.rb +61 -0
  54. data/lib/cocina/models/mapping/from_mods/event.rb +543 -0
  55. data/lib/cocina/models/mapping/from_mods/form.rb +381 -0
  56. data/lib/cocina/models/mapping/from_mods/geographic.rb +219 -0
  57. data/lib/cocina/models/mapping/from_mods/hydrus_default_title_builder.rb +28 -0
  58. data/lib/cocina/models/mapping/from_mods/identifier.rb +51 -0
  59. data/lib/cocina/models/mapping/from_mods/identifier_builder.rb +71 -0
  60. data/lib/cocina/models/mapping/from_mods/identifier_type.rb +292 -0
  61. data/lib/cocina/models/mapping/from_mods/language.rb +36 -0
  62. data/lib/cocina/models/mapping/from_mods/language_script.rb +30 -0
  63. data/lib/cocina/models/mapping/from_mods/language_term.rb +106 -0
  64. data/lib/cocina/models/mapping/from_mods/name_builder.rb +307 -0
  65. data/lib/cocina/models/mapping/from_mods/note.rb +162 -0
  66. data/lib/cocina/models/mapping/from_mods/part_builder.rb +147 -0
  67. data/lib/cocina/models/mapping/from_mods/primary.rb +27 -0
  68. data/lib/cocina/models/mapping/from_mods/purl.rb +53 -0
  69. data/lib/cocina/models/mapping/from_mods/related_resource.rb +105 -0
  70. data/lib/cocina/models/mapping/from_mods/subject.rb +413 -0
  71. data/lib/cocina/models/mapping/from_mods/subject_authority_codes.rb +794 -0
  72. data/lib/cocina/models/mapping/from_mods/title.rb +160 -0
  73. data/lib/cocina/models/mapping/from_mods/title_builder.rb +106 -0
  74. data/lib/cocina/models/mapping/from_mods/title_builder_strategy.rb +19 -0
  75. data/lib/cocina/models/mapping/from_mods/value_uri.rb +25 -0
  76. data/lib/cocina/models/mapping/normalizers/base.rb +16 -0
  77. data/lib/cocina/models/mapping/normalizers/mods/geo_extension_normalizer.rb +69 -0
  78. data/lib/cocina/models/mapping/normalizers/mods/name_normalizer.rb +191 -0
  79. data/lib/cocina/models/mapping/normalizers/mods/origin_info_normalizer.rb +157 -0
  80. data/lib/cocina/models/mapping/normalizers/mods/subject_normalizer.rb +296 -0
  81. data/lib/cocina/models/mapping/normalizers/mods/title_normalizer.rb +91 -0
  82. data/lib/cocina/models/mapping/normalizers/mods_normalizer.rb +409 -0
  83. data/lib/cocina/models/mapping/purl.rb +28 -0
  84. data/lib/cocina/models/mapping/to_mods/access.rb +155 -0
  85. data/lib/cocina/models/mapping/to_mods/admin_metadata.rb +129 -0
  86. data/lib/cocina/models/mapping/to_mods/contributor.rb +49 -0
  87. data/lib/cocina/models/mapping/to_mods/description.rb +63 -0
  88. data/lib/cocina/models/mapping/to_mods/event.rb +200 -0
  89. data/lib/cocina/models/mapping/to_mods/form.rb +292 -0
  90. data/lib/cocina/models/mapping/to_mods/geographic.rb +151 -0
  91. data/lib/cocina/models/mapping/to_mods/id_generator.rb +25 -0
  92. data/lib/cocina/models/mapping/to_mods/identifier.rb +57 -0
  93. data/lib/cocina/models/mapping/to_mods/language.rb +82 -0
  94. data/lib/cocina/models/mapping/to_mods/mods_writer.rb +38 -0
  95. data/lib/cocina/models/mapping/to_mods/name_title_group.rb +29 -0
  96. data/lib/cocina/models/mapping/to_mods/name_writer.rb +228 -0
  97. data/lib/cocina/models/mapping/to_mods/note.rb +105 -0
  98. data/lib/cocina/models/mapping/to_mods/part_writer.rb +115 -0
  99. data/lib/cocina/models/mapping/to_mods/related_resource.rb +108 -0
  100. data/lib/cocina/models/mapping/to_mods/role_writer.rb +50 -0
  101. data/lib/cocina/models/mapping/to_mods/subject.rb +486 -0
  102. data/lib/cocina/models/mapping/to_mods/title.rb +260 -0
  103. data/lib/cocina/models/object_metadata.rb +2 -2
  104. data/lib/cocina/models/presentation.rb +2 -2
  105. data/lib/cocina/models/related_resource.rb +9 -9
  106. data/lib/cocina/models/release_tag.rb +4 -4
  107. data/lib/cocina/models/request_admin_policy.rb +1 -1
  108. data/lib/cocina/models/request_administrative.rb +1 -1
  109. data/lib/cocina/models/request_collection.rb +2 -2
  110. data/lib/cocina/models/request_description.rb +3 -3
  111. data/lib/cocina/models/request_dro.rb +4 -4
  112. data/lib/cocina/models/request_file.rb +5 -5
  113. data/lib/cocina/models/request_identification.rb +1 -1
  114. data/lib/cocina/models/sequence.rb +1 -1
  115. data/lib/cocina/models/source.rb +4 -4
  116. data/lib/cocina/models/standard.rb +5 -5
  117. data/lib/cocina/models/stanford_access.rb +2 -2
  118. data/lib/cocina/models/title.rb +13 -13
  119. data/lib/cocina/models/validators/associated_name_validator.rb +77 -0
  120. data/lib/cocina/models/validators/dark_validator.rb +4 -2
  121. data/lib/cocina/models/validators/open_api_validator.rb +0 -4
  122. data/lib/cocina/models/validators/validator.rb +1 -0
  123. data/lib/cocina/models/version.rb +1 -1
  124. data/lib/cocina/models/world_access.rb +2 -2
  125. data/lib/cocina/models.rb +4 -0
  126. data/lib/cocina/rspec/factories.rb +157 -0
  127. data/lib/cocina/rspec.rb +2 -0
  128. data/openapi.yml +4 -4
  129. metadata +93 -6
  130. data/docs/_config.yml +0 -1
  131. data/lib/cocina/models/dro_rights_description_builder.rb +0 -67
  132. data/lib/cocina/models/rights_description_builder.rb +0 -81
  133. data/lib/cocina/models/title_builder.rb +0 -208
@@ -1,208 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'deprecation'
4
-
5
- module Cocina
6
- module Models
7
- # TitleBuilder selects the prefered title from the cocina object for solr indexing
8
- # rubocop:disable Metrics/ClassLength
9
- class TitleBuilder
10
- extend Deprecation
11
- # @param [[Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
12
- # @param [Symbol] strategy ":first" is the strategy for selection when primary or display title are missing
13
- # @param [Boolean] add_punctuation determines if the title should be formmated with punctuation
14
- # @return [String] the title value for Solr
15
- def self.build(titles, strategy: :first, add_punctuation: true)
16
- if titles.respond_to?(:description)
17
- Deprecation.warn(self, "Calling TitleBuilder.build with a #{titles.class} is deprecated. It must be called with an array of titles")
18
- titles = titles.description.title
19
- end
20
- new(strategy: strategy, add_punctuation: add_punctuation).build(titles)
21
- end
22
-
23
- def initialize(strategy:, add_punctuation:)
24
- @strategy = strategy
25
- @add_punctuation = add_punctuation
26
- end
27
-
28
- # @param [[Array<Cocina::Models::Title>] titles the titles to consider
29
- # @return [String] the title value for Solr
30
- def build(titles)
31
- cocina_title = primary_title(titles) || untyped_title(titles)
32
- cocina_title = other_title(titles) if cocina_title.blank?
33
-
34
- if strategy == :first
35
- extract_title(cocina_title)
36
- else
37
- cocina_title.map { |one| extract_title(one) }
38
- end
39
- end
40
-
41
- private
42
-
43
- attr_reader :strategy
44
-
45
- def extract_title(cocina_title)
46
- result = if cocina_title.value
47
- cocina_title.value
48
- elsif cocina_title.structuredValue.present?
49
- title_from_structured_values(cocina_title)
50
- elsif cocina_title.parallelValue.present?
51
- return build(cocina_title.parallelValue)
52
- end
53
- remove_trailing_punctuation(result.strip) if result.present?
54
- end
55
-
56
- def add_punctuation?
57
- @add_punctuation
58
- end
59
-
60
- # @return [Cocina::Models::Title, nil] title that has status=primary
61
- def primary_title(titles)
62
- primary_title = titles.find do |title|
63
- title.status == 'primary'
64
- end
65
- return primary_title if primary_title.present?
66
-
67
- # NOTE: structuredValues would only have status primary assigned as a sibling, not as an attribute
68
-
69
- titles.find do |title|
70
- title.parallelValue&.find do |parallel_title|
71
- parallel_title.status == 'primary'
72
- end
73
- end
74
- end
75
-
76
- def untyped_title(titles)
77
- method = strategy == :first ? :find : :select
78
- untyped_title_for(titles.public_send(method))
79
- end
80
-
81
- # @return [Array[Cocina::Models::Title]] first title that has no type attribute
82
- def untyped_title_for(titles)
83
- titles.each do |title|
84
- if title.parallelValue.present?
85
- untyped_title_for(title.parallelValue)
86
- else
87
- title.type.nil? || title.type == 'title'
88
- end
89
- end
90
- end
91
-
92
- # This handles 'main title', 'uniform' or 'translated'
93
- def other_title(titles)
94
- if strategy == :first
95
- titles.first
96
- else
97
- titles
98
- end
99
- end
100
-
101
- # rubocop:disable Metrics/BlockLength
102
- # rubocop:disable Metrics/CyclomaticComplexity
103
- # rubocop:disable Metrics/PerceivedComplexity
104
- # rubocop:disable Metrics/MethodLength
105
- # rubocop:disable Metrics/AbcSize
106
- # @param [Cocina::Models::Title] title with structured values
107
- # @return [String] the title value from combining the pieces of the structured_values by type and order
108
- # with desired punctuation per specs
109
- def title_from_structured_values(title)
110
- structured_title = ''
111
- part_name_number = ''
112
- # combine pieces of the cocina structuredValue into a single title
113
- title.structuredValue.each do |structured_value|
114
- # There can be a structuredValue inside a structuredValue. For example,
115
- # a uniform title where both the name and the title have internal StructuredValue
116
- return title_from_structured_values(structured_value) if structured_value.structuredValue.present?
117
-
118
- value = structured_value.value&.strip
119
- next unless value
120
-
121
- # additional types: name, uniform ...
122
- case structured_value.type&.downcase
123
- when 'nonsorting characters'
124
- non_sort_value = "#{value}#{non_sorting_padding(title, value)}"
125
- structured_title = if structured_title.present?
126
- "#{structured_title}#{non_sort_value}"
127
- else
128
- non_sort_value
129
- end
130
- when 'part name', 'part number'
131
- if part_name_number.blank?
132
- part_name_number = part_name_number(title.structuredValue)
133
- structured_title = if !add_punctuation?
134
- [structured_title, part_name_number].join(' ')
135
- elsif structured_title.present?
136
- "#{structured_title.sub(/[ .,]*$/, '')}. #{part_name_number}. "
137
- else
138
- "#{part_name_number}. "
139
- end
140
- end
141
- when 'main title', 'title'
142
- structured_title = "#{structured_title}#{value}"
143
- when 'subtitle'
144
- # subtitle is preceded by space colon space, unless it is at the beginning of the title string
145
- structured_title = if !add_punctuation?
146
- [structured_title, value].join(' ')
147
- elsif structured_title.present?
148
- "#{structured_title.sub(/[. :]+$/, '')} : #{value.sub(/^:/, '').strip}"
149
- else
150
- structured_title = value.sub(/^:/, '').strip
151
- end
152
- end
153
- end
154
- structured_title
155
- end
156
- # rubocop:enable Metrics/AbcSize
157
- # rubocop:enable Metrics/MethodLength
158
- # rubocop:enable Metrics/BlockLength
159
- # rubocop:enable Metrics/CyclomaticComplexity
160
- # rubocop:enable Metrics/PerceivedComplexity
161
-
162
- def remove_trailing_punctuation(title)
163
- title.sub(%r{[ .,;:/\\]+$}, '')
164
- end
165
-
166
- def non_sorting_padding(title, non_sorting_value)
167
- non_sort_note = title.note&.find { |note| note.type&.downcase == 'nonsorting character count' }
168
- if non_sort_note
169
- padding_count = [non_sort_note.value.to_i - non_sorting_value.length, 0].max
170
- ' ' * padding_count
171
- elsif ['\'', '-'].include?(non_sorting_value.last)
172
- ''
173
- else
174
- ' '
175
- end
176
- end
177
-
178
- # combine part name and part number:
179
- # respect order of occurrence
180
- # separated from each other by comma space
181
- def part_name_number(structured_values)
182
- title_from_part = ''
183
- structured_values.each do |structured_value|
184
- case structured_value.type&.downcase
185
- when 'part name', 'part number'
186
- value = structured_value.value&.strip
187
- next unless value
188
-
189
- title_from_part = append_part_to_title(title_from_part, value)
190
-
191
- end
192
- end
193
- title_from_part
194
- end
195
-
196
- def append_part_to_title(title_from_part, value)
197
- if !add_punctuation?
198
- [title_from_part, value].select(&:presence).join(' ')
199
- elsif title_from_part.strip.present?
200
- "#{title_from_part.sub(/[ .,]*$/, '')}, #{value}"
201
- else
202
- value
203
- end
204
- end
205
- end
206
- # rubocop:enable Metrics/ClassLength
207
- end
208
- end