spotlight-oaipmh-resources 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +56 -0
  3. data/app/controllers/spotlight/resources/harvester_controller.rb +58 -0
  4. data/app/jobs/spotlight/resources/perform_harvests_job.rb +44 -0
  5. data/app/mailer/spotlight/harvesting_complete_mailer.rb +20 -0
  6. data/app/models/spotlight/resources/exceptions.rb +17 -0
  7. data/app/models/spotlight/resources/harvest_type.rb +7 -0
  8. data/app/models/spotlight/resources/harvester.rb +46 -0
  9. data/app/models/spotlight/resources/oaipmh_harvester.rb +41 -0
  10. data/app/models/spotlight/resources/oaipmh_mods_converter.rb +468 -0
  11. data/app/models/spotlight/resources/oaipmh_mods_item.rb +61 -0
  12. data/app/models/spotlight/resources/solr_converter.rb +180 -0
  13. data/app/models/spotlight/resources/solr_harvester.rb +42 -0
  14. data/app/models/spotlight/resources/solr_harvesting_item.rb +50 -0
  15. data/app/services/spotlight/resources/oaipmh_builder.rb +166 -0
  16. data/app/services/spotlight/resources/solr_harvesting_builder.rb +115 -0
  17. data/app/views/catalog/_show.html.erb +10 -0
  18. data/app/views/spotlight/harvesting_complete_mailer/harvest_failed.html.erb +6 -0
  19. data/app/views/spotlight/harvesting_complete_mailer/harvest_indexed.html.erb +13 -0
  20. data/app/views/spotlight/resources/harvester/_form.html.erb +36 -0
  21. data/config/default_solr_mapping.yml +20 -0
  22. data/config/locales/en.yml +32 -0
  23. data/config/mapping.yml +172 -0
  24. data/config/marc_mapping.yml +190 -0
  25. data/config/routes.rb +5 -0
  26. data/lib/generators/spotlight/oaipmh/resources/install_generator.rb +16 -0
  27. data/lib/spotlight/oaipmh/resources.rb +11 -0
  28. data/lib/spotlight/oaipmh/resources/engine.rb +23 -0
  29. data/lib/spotlight/oaipmh/resources/version.rb +8 -0
  30. metadata +253 -0
@@ -0,0 +1,115 @@
1
+ module Spotlight
2
+ module Resources
3
+ # transforms a OaipmhHarvester into solr documents
4
+ class SolrHarvestingBuilder < Spotlight::SolrDocumentBuilder
5
+
6
+ def to_solr
7
+ begin
8
+ return to_enum(:to_solr) { 0 } unless block_given?
9
+
10
+ base_doc = super
11
+
12
+ mapping_file = nil
13
+ if (!resource.data[:solr_mapping_file].eql?("Default Mapping File") && !resource.data[:solr_mapping_file].eql?("New Mapping File"))
14
+ mapping_file = resource.data[:mapping_file]
15
+ end
16
+
17
+ max_batch_count = Spotlight::Oaipmh::Resources::Engine.config.solr_harvest_batch_max
18
+
19
+ @solr_converter = SolrConverter.new(resource.data[:set], resource.exhibit.slug, mapping_file)
20
+ @solr_converter.parse_mapping_file(@solr_converter.mapping_file)
21
+
22
+ unique_id_field = nil
23
+ if (!@solr_converter.get_unique_id_field.nil?)
24
+ unique_id_field = @solr_converter.get_unique_id_field
25
+ end
26
+
27
+ count = 0
28
+ totalrecords = 0
29
+
30
+ #If the resumption token was stored, begin there.
31
+ if (resource.data.include?(:cursor) && !resource.data[:cursor].blank?)
32
+ page = resource.data[:cursor]
33
+ harvests = resource.paginate(page)
34
+ else
35
+ page = 1
36
+ harvests = resource.harvests
37
+ end
38
+
39
+ if (resource.data.include?(:count) && !resource.data[:count].blank?)
40
+ totalrecords = resource.data[:count]
41
+ end
42
+
43
+ last_page_evaluated = harvests['response']['docs'].blank?
44
+
45
+ while (!last_page_evaluated)
46
+ harvests['response']['docs'].each do |record|
47
+ @item = SolrHarvestingItem.new(exhibit, @solr_converter)
48
+
49
+ @item.metadata = record
50
+ @item.parse_record(unique_id_field)
51
+ begin
52
+ @item_solr = @item.to_solr
53
+ @item_sidecar = @item.sidecar_data
54
+
55
+ #Add the sidecar info for editing
56
+ sidecar ||= resource.document_model.new(id: @item.id).sidecar(resource.exhibit)
57
+ sidecar.update(data: @item_sidecar)
58
+ yield base_doc.merge(@item_solr) if @item_solr.present?
59
+
60
+ count = count + 1
61
+ totalrecords = totalrecords + 1
62
+ curtime = Time.zone.now
63
+ resource.get_job_entry.update(job_item_count: totalrecords, end_time: curtime)
64
+
65
+ rescue Exception => e
66
+ Delayed::Worker.logger.add(Logger::ERROR, @item.id + ' did not index successfully')
67
+ Delayed::Worker.logger.add(Logger::ERROR, e.message)
68
+ Delayed::Worker.logger.add(Logger::ERROR, e.backtrace)
69
+ end
70
+ end #End of each loop
71
+ page = page + 1
72
+ #Stop harvesting if the batch has reached the maximum allowed value
73
+ if (!last_page_evaluated)
74
+ if (max_batch_count != -1 && count >= max_batch_count)
75
+ schedule_next_batch(page, totalrecords)
76
+ break
77
+ else
78
+ harvests = resource.paginate(page)
79
+
80
+ end
81
+ end
82
+
83
+
84
+ #Terminate the loop if it is empty
85
+ if (harvests['response']['docs'].blank?)
86
+ last_page_evaluated = true
87
+ end
88
+ end #End of while loop
89
+ rescue
90
+ resource.get_job_entry.failed!
91
+ raise
92
+ end
93
+ if (last_page_evaluated)
94
+ resource.get_job_entry.succeeded!
95
+ end
96
+
97
+ end
98
+
99
+ def get_unique_id_field_name(mapping_file)
100
+ mapping_config = YAML.load_file(mapping_file)
101
+ mapping_config.each do |field|
102
+ if (!field.key?("spotlight-field") || field['spotlight-field'].blank?)
103
+ raise InvalidMappingFile, "spotlight-field is required for each entry"
104
+ end
105
+ end
106
+ end
107
+
108
+ def schedule_next_batch(cursor, count)
109
+ Spotlight::Resources::PerformHarvestsJob.perform_later(resource.data[:type], resource.data[:base_url], resource.data[:set], resource.data[:mapping_file], resource.exhibit, resource.data[:user], resource.data[:job_entry], cursor, count)
110
+ end
111
+
112
+
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,10 @@
1
+ <% doc_presenter = show_presenter(document) %>
2
+ <%# default partial to display solr document fields in catalog show view -%>
3
+ <dl class="dl-horizontal dl-invert ddtest">
4
+ <% document_show_fields(document).each do |field_name, field| -%>
5
+ <% if should_render_show_field? document, field %>
6
+ <dt class="blacklight-<%= field_name.parameterize %> col-md-3"><%= render_document_show_field_label document, field: field_name %></dt>
7
+ <dd class="blacklight-<%= field_name.parameterize %> col-md-9"><%= doc_presenter.field_value field_name %></dd>
8
+ <% end -%>
9
+ <% end -%>
10
+ </dl>
@@ -0,0 +1,6 @@
1
+ <p><%= t :".title" %></p>
2
+
3
+ <p><%= t :".body", set: @set, title: @exhibit.title %></p>
4
+ <% if (!@message.blank?) %>
5
+ <p>The failure message given was '<%=@message%>'</p>
6
+ <% end %>
@@ -0,0 +1,13 @@
1
+ <p><%= t :".title" %></p>
2
+
3
+ <p><%= t :".body", set: @set, title: @exhibit.title %></p>
4
+ <% if (!@failed_items.blank?) %>
5
+ <p>The following items did not index properly and were not added:</p>
6
+ <p>
7
+ <%
8
+ @failed_items.each do |item| %>
9
+ <%=item %></br>
10
+ <% end %>
11
+ </p>
12
+ <% end %>
13
+
@@ -0,0 +1,36 @@
1
+ <%= bootstrap_form_for([current_exhibit, @resource.becomes(Spotlight::Resources::Harvester)], url: spotlight_oaipmh_resources_engine.exhibit_harvester_path(exhibit_id: current_exhibit), layout: :horizontal, label_col: 'col-md-2', control_col: 'col-sm-6 col-md-6' ) do |f| %>
2
+ <%= f.select :type, Spotlight::Resources::HarvestType::HARVEST_TYPES, {}, :onChange=>"toggleHarvesters(this.value);" %>
3
+ <%= f.text_field :url, help: t('.url-field.help'), label: t('.url') %>
4
+ <%= f.text_field :set, help: t('.set-field.help'), label: t('.set') %>
5
+ <span id="oaiharvester"><%= f.select :mapping_file, Spotlight::Resources::OaipmhHarvester.mapping_files, {}, :onChange=>"toggleUploadArea(this.value);" %></span>
6
+ <span id="solrharvester" style="display:none"><%= f.select :solr_mapping_file, Spotlight::Resources::SolrHarvester.mapping_files, {}, :onChange=>"toggleUploadArea(this.value);" %></span>
7
+ <div id="custom_mapping_file_div" style="display:none"><%= f.file_field :custom_mapping, help: t('.custom-mapping-field.help'), label: t('.custom-mapping') %></div>
8
+ <div class="form-actions">
9
+ <div class="primary-actions">
10
+ <%= cancel_link @resource, :back, class: 'btn btn-default' %>
11
+ <%= f.submit t('.add_item'), class: 'btn btn-primary' %>
12
+ </div>
13
+ </div>
14
+ <% end %>
15
+
16
+ <%= javascript_tag do %>
17
+ function toggleUploadArea(value) {
18
+ if(value=='New Mapping File') {
19
+ document.getElementById("custom_mapping_file_div").style.display = "block";
20
+ }
21
+ else {
22
+ document.getElementById("custom_mapping_file_div").style.display = "none";
23
+ }
24
+ }
25
+
26
+ function toggleHarvesters(value) {
27
+ if(value=='MODS') {
28
+ document.getElementById("oaiharvester").style.display = "block";
29
+ document.getElementById("solrharvester").style.display = "none";
30
+ }
31
+ else {
32
+ document.getElementById("oaiharvester").style.display = "none";
33
+ document.getElementById("solrharvester").style.display = "block";
34
+ }
35
+ }
36
+ <% end %>
@@ -0,0 +1,20 @@
1
+ #Structure:
2
+ #
3
+ # - spotlight-field: xxx (field names should be separated with dashes except for the suffix: firstpart-secondpart_ssim or _tesim)
4
+ # multivalue-breaks: "yes" (optional) - use this for splitting out multiple values to be broken on (and faceted on) individually (ex - subjects)
5
+ # default-value: xxx (optional)
6
+ # delimiter: xxx (optional, what to separate all path values with. Defaults to a space)
7
+ # solr-field:
8
+ # - field-name: xxx (repeatable - all path fields will be concatenated)
9
+ #
10
+ # Make sure to set unique-id_tesim if you want to choose an identifier for your record.
11
+ # Otherwise, reharvesting will result in the addition of more records rather than overwriting
12
+ # existing records.
13
+
14
+ - spotlight-field: unique-id_tesim
15
+ solr-field:
16
+ - field-name: "hashKey"
17
+
18
+ - spotlight-field: full_title_tesim
19
+ solr-field:
20
+ - field-name: "artist.romanizedName"
@@ -0,0 +1,32 @@
1
+ en:
2
+ spotlight:
3
+ resources:
4
+ harvester:
5
+ form:
6
+ title: 'Metadata Harvesting'
7
+ type: "Harvesting Type"
8
+ type-field:
9
+ help: "Choose where to harvest from (eg - Solr, OAI)"
10
+ url: "Base URL"
11
+ add_item: "Harvest items"
12
+ url-field:
13
+ help: "Add the base URL of the data to be harvested."
14
+ set: "Set spec"
15
+ set-field:
16
+ help: "Type in the set name to be harvested."
17
+ mapping-file: "Select Mapping File"
18
+ mapping-file-field:
19
+ help: "Select Mapping File to Use (default is mapping.yml)"
20
+ custom-mapping: "Custom Mapping File"
21
+ custom-mapping-field:
22
+ help: "Upload an optional mapping file (YML format)."
23
+ performharvest:
24
+ success: "Successfully scheduled '%{set}' for harvesting."
25
+ harvesting_complete_mailer:
26
+ harvest_indexed:
27
+ title: "Your harvest has just finished being processed."
28
+ body: "The %{set} set has been indexed from the harvest and added to the exhibit %{title}."
29
+ harvest_failed:
30
+ title: "Your harvest has failed to import."
31
+ body: "The %{set} harvest for the exhibit %{title} has failed."
32
+
@@ -0,0 +1,172 @@
1
+ #Structure:
2
+
3
+ # - spotlight-field: xxx
4
+ # default-value: xxx (optional)
5
+ # delimiter: xxx (optional, what to separate all path values with. Defaults to a space)
6
+ # mods:
7
+ # - path: xxx (repeatable - all path fields will be concatenated)
8
+ # delimiter: " "
9
+ # attribute: displayLabel
10
+ # attribute-value: collection
11
+ # mods-path: xxx
12
+ # mods-value: xx
13
+ # subpaths:
14
+ # - subpath: xxx
15
+ # - subpath: xxx
16
+ #
17
+ - spotlight-field: unique-id_tesim
18
+ mods:
19
+ - path: recordInfo/recordIdentifier
20
+ - spotlight-field: unique-id-sort_tesi
21
+ mods:
22
+ - path: recordInfo/recordIdentifier
23
+ - spotlight-field: full_title_tesim
24
+ delimiter: ": "
25
+ mods:
26
+ - path: titleInfo
27
+ delimiter: " "
28
+ subpaths:
29
+ - subpath: nonSort
30
+ - subpath: title
31
+ - path: titleInfo/subTitle
32
+ - spotlight-field: citation-title_tesim
33
+ mods:
34
+ - path: titleInfo/title
35
+ - spotlight-field: creator_tesim
36
+ mods:
37
+ - path: plain_name
38
+ delimiter: " , "
39
+ mods-path: role/roleTerm
40
+ mods-value: creator
41
+ subpaths:
42
+ - subpath: namePart
43
+ - spotlight-field: start-date_tesim
44
+ mods:
45
+ - path: originInfo/dateCreated
46
+ delimiter: "|"
47
+ attribute: point
48
+ attribute-value: start
49
+ - spotlight-field: end-date_tesim
50
+ mods:
51
+ - path: originInfo/dateCreated
52
+ delimiter: "|"
53
+ attribute: point
54
+ attribute-value: end
55
+ - spotlight-field: date_tesim
56
+ mods:
57
+ - path: originInfo/dateCreated
58
+ attribute: '!point'
59
+ attribute-value:
60
+ - spotlight-field: contributer_tesim
61
+ delimiter: " , "
62
+ mods:
63
+ - path: plain_name
64
+ delimiter: " , "
65
+ mods-path: role/roleTerm
66
+ mods-value: '!creator'
67
+ subpaths:
68
+ - subpath: namePart
69
+ - spotlight-field: spotlight_upload_description_tesim
70
+ delimiter: "|"
71
+ mods:
72
+ - path: abstract
73
+ - path: note
74
+ attribute: type
75
+ attribute-value:
76
+ - spotlight-field: format_tesim
77
+ delimiter: "|"
78
+ mods:
79
+ - path: physicalDescription/extent
80
+ - spotlight-field: language_ssim
81
+ default-value: English
82
+ delimiter: "|"
83
+ mods:
84
+ - path: language/languageTerm
85
+ - spotlight-field: repository_ssim
86
+ delimiter: "|"
87
+ mods:
88
+ - path: location/physicalLocation
89
+ attribute: type
90
+ attribute-value: repository
91
+ - path: relatedItem
92
+ subpaths:
93
+ - subpath: location/physicalLocation
94
+ attribute: displayLabel
95
+ attribute-value: collection
96
+ - spotlight-field: subjects_ssim
97
+ delimiter: "|"
98
+ mods:
99
+ - path: subject
100
+ delimiter: "--"
101
+ subpaths:
102
+ - subpath: name/namePart
103
+ - subpath: topic
104
+ - subpath: geographic
105
+ - subpath: genre
106
+ - spotlight-field: type_ssim
107
+ delimiter: "|"
108
+ mods:
109
+ - path: genre
110
+ - spotlight-field: origin_ssim
111
+ mods:
112
+ - path: originInfo/place/placeTerm
113
+ - spotlight-field: biography_tesim
114
+ delimiter: "|"
115
+ mods:
116
+ - path: note
117
+ attribute: type
118
+ attribute-value: biographical/historical
119
+ - spotlight-field: statement-of-responsibility_tesim
120
+ delimiter: "|"
121
+ mods:
122
+ - path: note
123
+ attribute: type
124
+ attribute-value: statement of responsibility
125
+ - spotlight-field: citation_tesim
126
+ delimiter: "|"
127
+ mods:
128
+ - path: note
129
+ attribute: type
130
+ attribute-value: preferred citation
131
+ - spotlight-field: physical-form_tesim
132
+ delimiter: "|"
133
+ mods:
134
+ - path: note
135
+ attribute: type
136
+ attribute-value: additional physical form
137
+ - spotlight-field: language-info_tesim
138
+ delimiter: "|"
139
+ mods:
140
+ - path: note
141
+ attribute: type
142
+ attribute-value: language
143
+ - spotlight-field: publications_tesim
144
+ delimiter: "|"
145
+ mods:
146
+ - path: note
147
+ attribute: type
148
+ attribute-value: publications
149
+ - spotlight-field: funding_tesim
150
+ mods:
151
+ - path: note
152
+ attribute: type
153
+ attribute-value: funding
154
+ - spotlight-field: funding_ssim
155
+ mods:
156
+ - path: note
157
+ attribute: type
158
+ attribute-value: funding
159
+ - spotlight-field: thumbnail_url_ssm
160
+ mods:
161
+ - path: location/url
162
+ attribute: access
163
+ attribute-value: preview
164
+ - spotlight-field: full_image_url_ssm
165
+ mods:
166
+ - path: location/url
167
+ attribute: access
168
+ attribute-value: raw object
169
+ - spotlight-field: rights_tesim
170
+ mods:
171
+ - path: accessCondition
172
+
@@ -0,0 +1,190 @@
1
+ #Structure:
2
+
3
+ # - spotlight-field: xxx
4
+ # default-value: xxx (optional)
5
+ # delimiter: xxx (optional, what to separate all path values with. Defaults to a space)
6
+ # mods:
7
+ # - path: xxx (repeatable - all path fields will be concatenated)
8
+ # delimiter: " "
9
+ # attribute: displayLabel
10
+ # attribute-value: collection
11
+ # mods-path: xxx
12
+ # mods-value: xx
13
+ # subpaths:
14
+ # - subpath: xxx
15
+ # - subpath: xxx
16
+ #
17
+ - spotlight-field: unique-id_tesim
18
+ mods:
19
+ - path: recordInfo/recordIdentifier
20
+ - spotlight-field: full_title_tesim
21
+ delimiter: ": "
22
+ mods:
23
+ - path: titleInfo
24
+ delimiter: " "
25
+ subpaths:
26
+ - subpath: nonSort
27
+ - subpath: title
28
+ - path: titleInfo/subTitle
29
+ - spotlight-field: citation-title_tesim
30
+ mods:
31
+ - path: titleInfo/title
32
+ - spotlight-field: creator_tesim
33
+ mods:
34
+ - path: plain_name
35
+ delimiter: " , "
36
+ mods-path: role/roleTerm
37
+ mods-value: creator
38
+ subpaths:
39
+ - subpath: namePart
40
+ - spotlight-field: start-date_tesim
41
+ mods:
42
+ - path: originInfo/dateCreated
43
+ delimiter: "|"
44
+ attribute: point
45
+ attribute-value: start
46
+ - spotlight-field: end-date_tesim
47
+ mods:
48
+ - path: originInfo/dateCreated
49
+ delimiter: "|"
50
+ attribute: point
51
+ attribute-value: end
52
+ - spotlight-field: publisher_tesim
53
+ mods:
54
+ - path: originInfo
55
+ subpaths:
56
+ - subpath: place/placeTerm
57
+ - subpath: publisher
58
+ - subpath: dateIssued
59
+ - spotlight-field: date_tesim
60
+ mods:
61
+ - path: originInfo/dateCreated
62
+ attribute: '!point'
63
+ attribute-value:
64
+ - spotlight-field: classification_ssim
65
+ mods:
66
+ - path: classification
67
+ - spotlight-field: classification_tesim
68
+ mods:
69
+ - path: classification
70
+ - spotlight-field: contributer_tesim
71
+ delimiter: "|"
72
+ mods:
73
+ - path: plain_name
74
+ delimiter: ", "
75
+ mods-path: role/roleTerm
76
+ mods-value: '!creator'
77
+ subpaths:
78
+ - subpath: namePart
79
+ - subpath: role/roleTerm
80
+ - spotlight-field: spotlight_upload_description_tesim
81
+ delimiter: "|"
82
+ mods:
83
+ - path: abstract
84
+ - spotlight-field: format_tesim
85
+ delimiter: "|"
86
+ mods:
87
+ - path: physicalDescription/extent
88
+ - spotlight-field: physical-description_tesim
89
+ delimiter: "|"
90
+ mods:
91
+ - path: physicalDescription/note
92
+ - spotlight-field: language_ssim
93
+ default-value: English
94
+ delimiter: "|"
95
+ mods:
96
+ - path: language/languageTerm
97
+ - spotlight-field: language_tesim
98
+ default-value: English
99
+ delimiter: "|"
100
+ mods:
101
+ - path: language/languageTerm
102
+ - spotlight-field: repository_ssim
103
+ delimiter: "|"
104
+ mods:
105
+ - path: location/physicalLocation
106
+ attribute: type
107
+ attribute-value: repository
108
+ - path: relatedItem
109
+ subpaths:
110
+ - subpath: location/physicalLocation
111
+ attribute: displayLabel
112
+ attribute-value: collection
113
+ - spotlight-field: repository_tesim
114
+ delimiter: "|"
115
+ mods:
116
+ - path: location/physicalLocation
117
+ attribute: type
118
+ attribute-value: repository
119
+ - path: relatedItem
120
+ subpaths:
121
+ - subpath: location/physicalLocation
122
+ attribute: displayLabel
123
+ attribute-value: collection
124
+ - spotlight-field: subjects_ssim
125
+ delimiter: "|"
126
+ mods:
127
+ - path: subject
128
+ delimiter: "--"
129
+ subpaths:
130
+ - subpath: name/namePart
131
+ - subpath: topic
132
+ - subpath: genre
133
+ - spotlight-field: subjects_tesim
134
+ delimiter: "|"
135
+ mods:
136
+ - path: subject
137
+ delimiter: "--"
138
+ subpaths:
139
+ - subpath: name/namePart
140
+ - subpath: topic
141
+ - subpath: genre
142
+ - spotlight-field: genre_tesim
143
+ delimiter: ";"
144
+ mods:
145
+ - path: genre
146
+ - spotlight-field: place_tesim
147
+ delimiter: "|"
148
+ mods:
149
+ - path: subject/hierarchicalGeographic
150
+ delimiter: "--"
151
+ subpaths:
152
+ - subpath: country
153
+ - subpath: state
154
+ - subpath: city
155
+ - spotlight-field: origin_ssim
156
+ mods:
157
+ - path: originInfo/place/placeTerm
158
+ - spotlight-field: origin_tesim
159
+ mods:
160
+ - path: originInfo/place/placeTerm
161
+ - spotlight-field: attribution_tesim
162
+ delimiter: "|"
163
+ mods:
164
+ - path: note
165
+ attribute: type
166
+ attribute-value: statement of responsibility
167
+ - spotlight-field: note_tesim
168
+ delimiter: "|"
169
+ mods:
170
+ - path: note
171
+ attribute: type
172
+ attribute-value: '!statement of responsibility'
173
+ - spotlight-field: thumbnail_url_ssm
174
+ mods:
175
+ - path: location/url
176
+ attribute: access
177
+ attribute-value: preview
178
+ - spotlight-field: full_image_url_ssm
179
+ mods:
180
+ - path: location/url
181
+ attribute: access
182
+ attribute-value: raw object
183
+ - spotlight-field: rights_tesim
184
+ mods:
185
+ - path: accessCondition
186
+ - spotlight-field: creation_date_tesim
187
+ mods:
188
+ - path: originInfo/dateIssued
189
+ - path: originInfo/dateCreated
190
+