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.
Files changed (147) 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 +168 -39
  7. data/docs/description_types.md +471 -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 +98 -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 +27 -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 +205 -0
  127. data/lib/cocina/rspec.rb +2 -0
  128. data/openapi.yml +4 -4
  129. metadata +97 -24
  130. data/docs/_config.yml +0 -1
  131. data/docs/maps/Agent.json +0 -18
  132. data/docs/maps/Collection.json +0 -240
  133. data/docs/maps/DRO.json +0 -316
  134. data/docs/maps/Description.json +0 -17
  135. data/docs/maps/File.json +0 -196
  136. data/docs/maps/Fileset.json +0 -143
  137. data/docs/maps/README.md +0 -7
  138. data/docs/maps/ReleaseTag.json +0 -39
  139. data/docs/maps/Sequence.json +0 -46
  140. data/docs/maps/Title.json +0 -18
  141. data/docs/sampleETD/foxml-export.xml +0 -935
  142. data/docs/sampleETD/foxml.xml +0 -3475
  143. data/docs/sampleETD/xn109qc9773_bibframe.ttl +0 -95
  144. data/docs/sampleETD/xn109qc9773_taco.json +0 -158
  145. data/lib/cocina/models/dro_rights_description_builder.rb +0 -67
  146. data/lib/cocina/models/rights_description_builder.rb +0 -81
  147. data/lib/cocina/models/title_builder.rb +0 -208
@@ -1,95 +0,0 @@
1
- :xn109qc9773_work a bf:Work , bf:Text ;
2
- rdfs:label "From superteacher to 'bad teacher': goals 2000, comic book films, and changing depictions of educators in the movies" ;
3
- bf:title [ a bf:Title ;
4
- bf:mainTitle "From superteacher to 'bad teacher'" ;
5
- bf:subTitle "goals 2000, comic book films, and changing depictions of educators in the movies"
6
- ] ;
7
- bf:contribution [ a bf:Contribution ;
8
- bf:agent [ a bf:Agent , bf:Person ;
9
- rdfs:label "Grant, Derisa"
10
- ] ;
11
- ] ;
12
- bf:contribution [ a bf:Contribution ;
13
- bf:agent [ a bf:Agent , bf:Person ;
14
- rdfs:label "Labaree, David F., 1947-"
15
- ] ;
16
- bf:role [ a bf:Role ;
17
- rdfs:label "primary advisor"
18
- ] ;
19
- bf:role <http://id.loc.gov/vocabulary/relators/ths>
20
- ] ;
21
- bf:contribution [ a bf:Contribution ;
22
- bf:agent [ a bf:Agent , bf:Person ;
23
- rdfs:label "McDermott, Ray"
24
- ] ;
25
- bf:role [ a bf:Role ;
26
- rdfs:label "advisor"
27
- ] ;
28
- bf:role <http://id.loc.gov/vocabulary/relators/ths>
29
- ] ;
30
- bf:contribution [ a bf:Contribution ;
31
- bf:agent [ a bf:Agent , bf:Person ;
32
- rdfs:label "Willinsky, John, 1950-"
33
- ] ;
34
- bf:role [ a bf:Role ;
35
- rdfs:label "advisor"
36
- ] ;
37
- bf:role <http://id.loc.gov/vocabulary/relators/ths>
38
- ] ;
39
- bf:contribution [ a bf:Contribution ;
40
- bf:agent [ a bf:Agent , bf:Organization ;
41
- rdfs:label "Stanford University. Graduate School of Education"
42
- ]
43
- ]
44
- bf:genreForm [ a bf:GenreForm ;
45
- rdfs:label "theses" ;
46
- bf:source [ a bf:Source ;
47
- bf:code "marcgt"
48
- ]
49
- ] ;
50
- bf:language <http://id.loc.gov/vocabulary/iso639-2/eng> ;
51
- bf:summary [ a bf:Summary ;
52
- rdfs:label "Since 1939, 46 eddies, or fictional movies about primary or secondary schooling that foreground a teacher..."
53
- ] ;
54
- bf:dissertation [ a bf:Dissertation ;
55
- rdfs:label "Thesis (Ph.D.)--Stanford University, 2015."
56
- ]
57
- ] .
58
-
59
- :xn109qc9773_instance a bf:Instance ;
60
- rdfs:label "From superteacher to 'bad teacher': goals 2000, comic book films, and changing depictions of educators in the movies" ;
61
- bf:title [ a bf:Title ;
62
- bf:mainTitle "From superteacher to 'bad teacher'" ;
63
- bf:subTitle "goals 2000, comic book films, and changing depictions of educators in the movies"
64
- ] ;
65
- bf:provisionActivity [ a bf:ProvisionActivity , a bf:Publication ;
66
- bf:date "2015" ;
67
- bf:place [ a bf:Place ;
68
- bf:code "xx" ;
69
- bf:source [ a bf:Source ;
70
- bf:code "marccountry"
71
- ] ;
72
- ] ;
73
- bf:issuance <http://id.loc.gov/vocabulary/issuance/mono>
74
- ] ;
75
- bf:carrier [ a bf:Carrier ;
76
- rdfs:label "digital"
77
- ] ;
78
- bf:extent [ a bf:Extent ;
79
- rdfs:label "1 online resource"
80
- ] ;
81
- bf:note [ a bf:Note ;
82
- rdfs:label "Submitted to the Graduate School of Education."
83
- ] ;
84
- bf:responsibilityStatement "Derisa Grant."
85
- ] .
86
-
87
- :xn109qc9773_item [ a bf:Item ;
88
- bf:electronicLocator [ a rdf:Resource ;
89
- rdf:value <https://purl.stanford.edu/xn109qc9773> ;
90
- bf:note [ a bf:Note ;
91
- rdfs:label "primary display" ;
92
- bf:noteType "URL usage"
93
- ]
94
- ]
95
- ] .
@@ -1,158 +0,0 @@
1
- { "version": "1.0",
2
- "lastUpdated": "2018-11-13",
3
- "druid": "xn109qc9773",
4
- "descriptiveMetadata": {
5
- "title": [{
6
- "primary": "TRUE",
7
- "titleParts": [
8
- {"mainTitle": "From superteacher to 'bad teacher'"},
9
- {"subTitle": "goals 2000, comic book films, and changing depictions of educators in the movies"}
10
- ],
11
- "titleFull": "From superteacher to 'bad teacher': goals 2000, comic book films, and changing depictions of educators in the movies",
12
- "titleBrief": "From superteacher to 'bad teacher'"
13
- }],
14
- "origin": [
15
- {
16
- "primary": "TRUE",
17
- "event": "creation",
18
- "agent": [{
19
- "type": "personal",
20
- "name": {
21
- "nameFromSource": "Grant, Derisa",
22
- "lastName": "Grant",
23
- "firstName": "Derisa"
24
- }
25
- }]
26
- },
27
- {
28
- "event": "creation",
29
- "agent": [{
30
- "type": "personal",
31
- "name": {
32
- "nameFromSource": "Labaree, David F.",
33
- "lastName": "Labaree",
34
- "firstName": "David F.",
35
- "nameDate": {
36
- "type": "life",
37
- "startDate": "1947",
38
- "endDate": "open"
39
- }
40
- }
41
- }],
42
- "role": [
43
- {"roleTerm": "primary advisor"},
44
- {
45
- "roleTerm": "thesis advisor",
46
- "roleAuthority": "marcrelator",
47
- "roleValueURI": "http://id.loc.gov/vocabulary/relators/ths"
48
- }
49
- ]
50
- },
51
- {
52
- "event": "creation",
53
- "agent": [{
54
- "type": "personal",
55
- "name": {
56
- "nameFromSource": "McDermott, Ray",
57
- "lastName": "McDermott",
58
- "firstName": "Ray"
59
- }
60
- }],
61
- "role": [
62
- {"roleTerm": "advisor"},
63
- {
64
- "roleTerm": "thesis advisor",
65
- "roleAuthority": "marcrelator",
66
- "roleValueURI": "http://id.loc.gov/vocabulary/relators/ths"
67
- }
68
- ]
69
- },
70
- {
71
- "event": "creation",
72
- "agent": [{
73
- "type": "personal",
74
- "name": {
75
- "nameFromSource": "Willinsky, John",
76
- "lastName": "Willinsky",
77
- "firstName": "John",
78
- "nameDate": {
79
- "type": "life",
80
- "startDate": "1950",
81
- "endDate": "open"
82
- }
83
- }
84
- }],
85
- "role": [
86
- {"roleTerm": "advisor"},
87
- {
88
- "roleTerm": "thesis advisor",
89
- "roleAuthority": "marcrelator",
90
- "roleValueURI": "http://id.loc.gov/vocabulary/relators/ths"
91
- }
92
- ]
93
- },
94
- {
95
- "event": "creation",
96
- "agent": [{
97
- "type": "corporate",
98
- "name": {"nameParts": [
99
- "Stanford University",
100
- "Graduate School of Education"
101
- ]}
102
- }]
103
- },
104
- {
105
- "event": "publication",
106
- "place": [{
107
- "code": "xx",
108
- "authority": "marccountry"
109
- }],
110
- "date": {"singleDate": "2015"},
111
- "periodicity": [{
112
- "value": "monographic",
113
- "vocabulary": "MODS issuance"
114
- }]
115
- }
116
- ],
117
- "typeOfResource": [{
118
- "typeOfResourceTerm": "text",
119
- "authority": "MODS typeOfResource"
120
- }],
121
- "genre": [{
122
- "genreTerm": "theses",
123
- "authority": "marcgt"
124
- }],
125
- "language": [{
126
- "languageTerm": "English",
127
- "languageAuthority": "iso639-2b",
128
- "languageValueURI": "http://id.loc.gov/vocabulary/iso639-2/eng"
129
- }],
130
- "form": {
131
- "appliesTo": "resource",
132
- "medium": "digital",
133
- "extent": {
134
- "extentStatement": "1 online resource",
135
- "extentNumber": 1,
136
- "extentUnit": "online resource"
137
- }
138
- },
139
- "access": ["online"],
140
- "abstract": "Since 1939, 46 eddies, or fictional movies about primary or secondary schooling that foreground a teacher, have been released in the United States. From the 1950s through the 1990s, eddies often featured two interconnected and dominant tropes: the separation of home and school, and a superteacher, or a dedicated educator who uses unconventional teaching methods. However, many of the eddies made after 2000 blur or wholly erase the boundary between home and school, and nearly half of the 15 eddies made after 2000 feature unsavory or morally ambiguous teacher protagonists. This dissertation explores the contexts surrounding the genre's shift in tropes, and asserts that changes in eddies coincide with broader changes within the film industry, as well as with changes in educational policy and rhetoric. Specifically, generic changes in eddies coincide with the rise of the comic book film in the early 2000s, and President Bill Clinton's 1994 Goals 2000: Educate America Act, through which the Clinton administration framed education reform as a systemic problem requiring federal interventions and gained the public's support for federally led reforms. By the early 2000s, caped crusaders had begun proving lucrative at the box office, and the federal government had gained unprecedented traction in schools. Concurrently, the cinematic teacher--with no mask, no cape, and no federal authority&#x2014;was increasingly depicted as a drug addict, a coward, or a cheater who brought the dysfunction of her home life into the classroom.",
141
- "note": [
142
- {"value": "Submitted to the Graduate School of Education."},
143
- {
144
- "type": "thesis",
145
- "value": "Thesis (Ph.D.)--Stanford University, 2015."
146
- },
147
- {
148
- "type": "statementOfResponsibility",
149
- "value": "Derisa Grant."
150
- }
151
- ],
152
- "accessURL": [{
153
- "type": "purl",
154
- "url": "https://purl.stanford.edu/xn109qc9773",
155
- "primary": "TRUE"
156
- }]
157
- }
158
- }
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Cocina
4
- module Models
5
- # Rights description builder for items
6
- class DroRightsDescriptionBuilder < RightsDescriptionBuilder
7
- # @param [Cocina::Models::DRO] cocina_item
8
-
9
- # This overrides the superclass
10
- # @return [Cocina::Models::DROAccess]
11
- def object_access
12
- @object_access ||= cocina.access
13
- end
14
-
15
- private
16
-
17
- def object_level_access
18
- super + access_level_from_files.uniq.map { |str| "#{str} (file)" }
19
- end
20
-
21
- def access_level_from_files
22
- # dark access doesn't permit any file access
23
- return [] if object_access.view == 'dark'
24
-
25
- file_access_nodes.reject { |fa| same_as_object_access?(fa) }.flat_map do |fa|
26
- file_access_from_file(fa)
27
- end
28
- end
29
-
30
- # rubocop:disable Metrics/MethodLength
31
- def file_access_from_file(file_access)
32
- basic_access = if file_access[:view] == 'location-based'
33
- "location: #{file_access[:location]}"
34
- else
35
- file_access[:view]
36
- end
37
-
38
- return [basic_access] if file_access[:view] == file_access[:download]
39
-
40
- basic_access += ' (no-download)' if file_access[:view] != 'dark'
41
-
42
- case file_access[:download]
43
- when 'stanford'
44
- [basic_access, 'stanford']
45
- when 'location-based'
46
- # Here we're using location to mean download location.
47
- [basic_access, "location: #{file_access[:location]}"]
48
- else
49
- [basic_access]
50
- end
51
- end
52
- # rubocop:enable Metrics/MethodLength
53
-
54
- def same_as_object_access?(file_access)
55
- (file_access[:view] == object_access.view && file_access[:download] == object_access.download) ||
56
- (object_access.view == 'citation-only' && file_access[:view] == 'dark')
57
- end
58
-
59
- def file_access_nodes
60
- Array(cocina.structural.contains)
61
- .flat_map { |fs| Array(fs.structural.contains) }
62
- .map { |file| file.access.to_h }
63
- .uniq
64
- end
65
- end
66
- end
67
- end
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Cocina
4
- module Models
5
- # RightsDescriptionBuilder
6
- class RightsDescriptionBuilder
7
- # @param [Cocina::Models::AdminPolicy, Cocina::Models::DRO] cocina_object
8
- def self.build(cocina_object)
9
- new(cocina_object).build
10
- end
11
-
12
- def initialize(cocina_object)
13
- @cocina = cocina_object
14
- end
15
-
16
- # This is set up to work for APOs, but this method is to be overridden on sub classes
17
- # @return [Cocina::Models::AdminPolicyDefaultAccess]
18
- def object_access
19
- @object_access ||= cocina.administrative.accessTemplate
20
- end
21
-
22
- def build
23
- return 'controlled digital lending' if object_access.controlledDigitalLending
24
-
25
- return ['dark'] if object_access.view == 'dark'
26
-
27
- object_level_access
28
- end
29
-
30
- private
31
-
32
- attr_reader :cocina
33
-
34
- # rubocop:disable Metrics/MethodLength
35
- def object_level_access
36
- case object_access.view
37
- when 'citation-only'
38
- ['citation']
39
- when 'world'
40
- world_object_access
41
- when 'location-based'
42
- case object_access.download
43
- when 'none'
44
- ["location: #{object_access.location} (no-download)"]
45
- else
46
- ["location: #{object_access.location}"]
47
- end
48
- when 'stanford'
49
- stanford_object_access
50
- end
51
- end
52
- # rubocop:enable Metrics/MethodLength
53
-
54
- def stanford_object_access
55
- case object_access.download
56
- when 'none'
57
- ['stanford (no-download)']
58
- when 'location-based'
59
- # this is an odd case we might want to move away from. See https://github.com/sul-dlss/cocina-models/issues/258
60
- ['stanford (no-download)', "location: #{object_access.location}"]
61
- else
62
- ['stanford']
63
- end
64
- end
65
-
66
- def world_object_access
67
- case object_access.download
68
- when 'stanford'
69
- ['stanford', 'world (no-download)']
70
- when 'none'
71
- ['world (no-download)']
72
- when 'world'
73
- ['world']
74
- when 'location-based'
75
- # this is an odd case we might want to move away from. See https://github.com/sul-dlss/cocina-models/issues/258
76
- ['world (no-download)', "location: #{object_access.location}"]
77
- end
78
- end
79
- end
80
- end
81
- end
@@ -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