dor-services 9.1.0 → 9.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 136d61d182d9ce8c75cd211f5b1d76c5a27f7db15811939718ecf4257a025a9b
4
- data.tar.gz: ddb8aaab834a7c7c78fe7da5388127bd8978740ac9fa5b59e1b25a34b6c0aca4
3
+ metadata.gz: f696769ddd2ceb91345d4d0b7aa5b3ebdfa1b84a3c990055187f058b2d422a66
4
+ data.tar.gz: 0d354e436399a02330fdd07db2fae0b0eddfa14c710d93807aadb925dfa57c0f
5
5
  SHA512:
6
- metadata.gz: 904c66a42965b98fa202d6044d2e82557a673f520fb06d011dcc3e40a4d42ed5ccf0eeadf725743066b7087a664da0567a7cf0fb7ea0086e094e40ee4dbada2c
7
- data.tar.gz: 73d3fb910e501d6c85e67d32d459f2af338e1373ffaed6dabb3ed00e2245b4e8534753c369cb5882785d065fee6b5e204b5e57a8a7a295b538fd016bcb75e1c8
6
+ metadata.gz: 4a645755fe069b45ed3f07f02b742990acc25234214f3968e997b5c76475b70df1c3bccc400f6831aab1fc2a6770d409b3cedcb65f4dd7a36e38fdf0e2752bbe
7
+ data.tar.gz: 88a519d69bea0c6a08ea8ce6569468778e10431595e759f8e38ee4c049674125cef29f0425f83f59597ba3b62bd4c7d348c5bc5115b5213167414e1991626db4
@@ -92,7 +92,6 @@ module Dor
92
92
  autoload :OpenDataLicenseService
93
93
  autoload :SearchService
94
94
  autoload :SuriService
95
- autoload :TagService
96
95
  end
97
96
 
98
97
  eager_load!
@@ -8,7 +8,7 @@ module Dor
8
8
  t.root(path: 'embargoMetadata')
9
9
  t.status
10
10
  t.embargo_status(path: 'status', index_as: [:symbol])
11
- t.release_date(path: 'releaseDate', index_as: [:dateable])
11
+ t.release_date(path: 'releaseDate', type: :time)
12
12
  t.release_access(path: 'releaseAccess') do
13
13
  t.use do
14
14
  t.human(attributes: { type: 'useAndReproduction' })
@@ -35,10 +35,8 @@ module Dor
35
35
 
36
36
  def to_solr(solr_doc = {}, *args)
37
37
  solr_doc = super
38
- #::Solrizer.insert_field(solr_doc, field_name, value, *index_types)
39
- rd1 = release_date
40
38
  rd20 = twenty_pct_release_date
41
- ::Solrizer.insert_field(solr_doc, 'embargo_release', rd1.utc.strftime('%FT%TZ'), :dateable) unless rd1.blank?
39
+ ::Solrizer.insert_field(solr_doc, 'embargo_release', release_date.first.utc.strftime('%FT%TZ'), :dateable) unless release_date.first.blank?
42
40
  ::Solrizer.insert_field(solr_doc, 'twenty_pct_visibility_release', rd20.utc.strftime('%FT%TZ'), :dateable) unless rd20.blank?
43
41
  solr_doc
44
42
  end
@@ -60,19 +58,6 @@ module Dor
60
58
  term_values(:status).first
61
59
  end
62
60
 
63
- # Sets the release date. Does NOT convert to beginning-of-day.
64
- # @param [Time] rd the release date object
65
- def release_date=(rd = Time.now.utc)
66
- update_values([:release_date] => rd.utc.xmlschema)
67
- end
68
-
69
- # Current releaseDate value
70
- # @return [Time]
71
- def release_date
72
- rd = term_values(:release_date).first
73
- rd.nil? || rd.empty? ? nil : Time.parse(rd)
74
- end
75
-
76
61
  def twenty_pct_status=(new_status)
77
62
  update_values([:twenty_pct_status] => new_status)
78
63
  end
@@ -8,6 +8,7 @@ module Dor
8
8
  # ids for previous and current catkeys
9
9
  CATKEY_TYPE_ID = 'catkey'
10
10
  PREVIOUS_CATKEY_TYPE_ID = 'previous_catkey'
11
+ BARCODE_TYPE_ID = 'barcode'
11
12
 
12
13
  set_terminology do |t|
13
14
  t.root(path: 'identityMetadata')
@@ -69,16 +70,6 @@ module Dor
69
70
  end
70
71
  alias source_id= sourceId=
71
72
 
72
- def tags
73
- tag
74
- end
75
-
76
- # helper method to get just the content type tag
77
- def content_type_tag
78
- content_tag = tags.select { |tag| tag.include?('Process : Content Type') }
79
- content_tag.size == 1 ? content_tag[0].split(':').last.strip : ''
80
- end
81
-
82
73
  def otherId(type = nil)
83
74
  result = find_by_terms(:otherId).to_a
84
75
  if type.nil?
@@ -154,6 +145,25 @@ module Dor
154
145
  otherId(PREVIOUS_CATKEY_TYPE_ID)
155
146
  end
156
147
 
148
+ def barcode
149
+ otherId(BARCODE_TYPE_ID).first
150
+ end
151
+
152
+ # Convenience method to set the barcode
153
+ # @param [String] val the new barcode
154
+ # @return [String] same value, as per Ruby assignment convention
155
+ def barcode=(val)
156
+ if val.blank? # if we are setting the barcode to blank, remove the node from XML
157
+ remove_other_Id(BARCODE_TYPE_ID)
158
+ elsif barcode.blank? # if there is no current barcode, then add it
159
+ add_other_Id(BARCODE_TYPE_ID, val)
160
+ else # if there is a current barcode, update the current barcode to the new value
161
+ update_other_Id(BARCODE_TYPE_ID, val)
162
+ end
163
+
164
+ val
165
+ end
166
+
157
167
  # Helper method to get the release tags as a nodeset
158
168
  # @return [Nokogiri::XML::NodeSet] all release tags and their attributes
159
169
  def release_tags
@@ -170,61 +180,6 @@ module Dor
170
180
  return_hash
171
181
  end
172
182
 
173
- def to_solr(solr_doc = {}, *args)
174
- solr_doc = super(solr_doc, *args)
175
-
176
- if digital_object.respond_to?(:profile)
177
- digital_object.profile.each_pair do |property, value|
178
- add_solr_value(solr_doc, property.underscore, value, (property =~ /Date/ ? :date : :symbol), [:stored_searchable])
179
- end
180
- end
181
-
182
- if sourceId.present?
183
- (name, id) = sourceId.split(/:/, 2)
184
- add_solr_value(solr_doc, 'dor_id', id, :symbol, [:stored_searchable])
185
- add_solr_value(solr_doc, 'identifier', sourceId, :symbol, [:stored_searchable])
186
- add_solr_value(solr_doc, 'source_id', sourceId, :symbol, [])
187
- end
188
- otherId.compact.each do |qid|
189
- # this section will solrize barcode and catkey, which live in otherId
190
- (name, id) = qid.split(/:/, 2)
191
- add_solr_value(solr_doc, 'dor_id', id, :symbol, [:stored_searchable])
192
- add_solr_value(solr_doc, 'identifier', qid, :symbol, [:stored_searchable])
193
- add_solr_value(solr_doc, "#{name}_id", id, :symbol, [])
194
- end
195
-
196
- # do some stuff to make tags in general and project tags specifically more easily searchable and facetable
197
- find_by_terms(:tag).each do |tag|
198
- (prefix, rest) = tag.text.split(/:/, 2)
199
- prefix = prefix.downcase.strip.gsub(/\s/, '_')
200
- unless rest.nil?
201
- # this part will index a value in a field specific to the tag, e.g. registered_by_tag_*,
202
- # book_tag_*, project_tag_*, remediated_by_tag_*, etc. project_tag_* and registered_by_tag_*
203
- # definitley get used, but most don't. we can limit the prefixes that get solrized if things
204
- # get out of hand.
205
- add_solr_value(solr_doc, "#{prefix}_tag", rest.strip, :symbol, [])
206
- end
207
-
208
- # solrize each possible prefix for the tag, inclusive of the full tag.
209
- # e.g., for a tag such as "A : B : C", this will solrize to an _ssim field
210
- # that contains ["A", "A : B", "A : B : C"].
211
- tag_parts = tag.text.split(/:/)
212
- progressive_tag_prefix = ''
213
- tag_parts.each_with_index do |part, index|
214
- progressive_tag_prefix += ' : ' if index > 0
215
- progressive_tag_prefix += part.strip
216
- add_solr_value(solr_doc, 'exploded_tag', progressive_tag_prefix, :symbol, [])
217
- end
218
- end
219
-
220
- solr_doc
221
- end
222
-
223
- # maintain AF < 8 indexing behavior
224
- def prefix
225
- ''
226
- end
227
-
228
183
  private
229
184
 
230
185
  # Convert one release element into a Hash
@@ -20,6 +20,14 @@ module Dor
20
20
  t.human
21
21
  end
22
22
 
23
+ t._read(path: 'access', attributes: { type: 'read' }) do
24
+ t.machine do
25
+ t.embargo_release_date(path: 'embargoReleaseDate', type: :time)
26
+ end
27
+ end
28
+
29
+ t.embargo_release_date(proxy: %i[_read machine embargo_release_date])
30
+
23
31
  t.creative_commons path: '/use/machine[@type=\'creativeCommons\']', type: 'creativeCommons' do
24
32
  t.uri path: '@uri'
25
33
  end
@@ -136,73 +144,6 @@ module Dor
136
144
  @dra_object = nil # until TODO complete, we'll expect to have to reparse after modification
137
145
  end
138
146
 
139
- def to_solr(solr_doc = {}, *args)
140
- solr_doc = super(solr_doc, *args)
141
- dra = dra_object
142
- solr_doc['rights_primary_ssi'] = dra.index_elements[:primary]
143
- solr_doc['rights_errors_ssim'] = dra.index_elements[:errors] if dra.index_elements[:errors].size > 0
144
- solr_doc['rights_characteristics_ssim'] = dra.index_elements[:terms] if dra.index_elements[:terms].size > 0
145
-
146
- solr_doc['rights_descriptions_ssim'] = [
147
- dra.index_elements[:primary],
148
-
149
- (dra.index_elements[:obj_locations_qualified] || []).map do |rights_info|
150
- rule_suffix = rights_info[:rule] ? " (#{rights_info[:rule]})" : ''
151
- "location: #{rights_info[:location]}#{rule_suffix}"
152
- end,
153
- (dra.index_elements[:file_locations_qualified] || []).map do |rights_info|
154
- rule_suffix = rights_info[:rule] ? " (#{rights_info[:rule]})" : ''
155
- "location: #{rights_info[:location]} (file)#{rule_suffix}"
156
- end,
157
-
158
- (dra.index_elements[:obj_agents_qualified] || []).map do |rights_info|
159
- rule_suffix = rights_info[:rule] ? " (#{rights_info[:rule]})" : ''
160
- "agent: #{rights_info[:agent]}#{rule_suffix}"
161
- end,
162
- (dra.index_elements[:file_agents_qualified] || []).map do |rights_info|
163
- rule_suffix = rights_info[:rule] ? " (#{rights_info[:rule]})" : ''
164
- "agent: #{rights_info[:agent]} (file)#{rule_suffix}"
165
- end,
166
-
167
- (dra.index_elements[:obj_groups_qualified] || []).map do |rights_info|
168
- rule_suffix = rights_info[:rule] ? " (#{rights_info[:rule]})" : ''
169
- "#{rights_info[:group]}#{rule_suffix}"
170
- end,
171
- (dra.index_elements[:file_groups_qualified] || []).map do |rights_info|
172
- rule_suffix = rights_info[:rule] ? " (#{rights_info[:rule]})" : ''
173
- "#{rights_info[:group]} (file)#{rule_suffix}"
174
- end,
175
-
176
- (dra.index_elements[:obj_world_qualified] || []).map do |rights_info|
177
- rule_suffix = rights_info[:rule] ? " (#{rights_info[:rule]})" : ''
178
- "world#{rule_suffix}"
179
- end,
180
- (dra.index_elements[:file_world_qualified] || []).map do |rights_info|
181
- rule_suffix = rights_info[:rule] ? " (#{rights_info[:rule]})" : ''
182
- "world (file)#{rule_suffix}"
183
- end
184
- ].flatten.uniq
185
-
186
- # these two values are returned by index_elements[:primary], but are just a less granular version of
187
- # what the other more specific fields return, so discard them
188
- solr_doc['rights_descriptions_ssim'] -= %w[access_restricted access_restricted_qualified world_qualified]
189
- solr_doc['rights_descriptions_ssim'] += ['dark (file)'] if dra.index_elements[:terms].include? 'none_read_file'
190
-
191
- solr_doc['obj_rights_locations_ssim'] = dra.index_elements[:obj_locations] unless dra.index_elements[:obj_locations].blank?
192
- solr_doc['file_rights_locations_ssim'] = dra.index_elements[:file_locations] unless dra.index_elements[:file_locations].blank?
193
- solr_doc['obj_rights_agents_ssim'] = dra.index_elements[:obj_agents] unless dra.index_elements[:obj_agents].blank?
194
- solr_doc['file_rights_agents_ssim'] = dra.index_elements[:file_agents] unless dra.index_elements[:file_agents].blank?
195
-
196
- # suppress empties
197
- %w(use_statement_ssim copyright_ssim).each do |key|
198
- solr_doc[key] = solr_doc[key].reject(&:blank?).flatten unless solr_doc[key].nil?
199
- end
200
- add_solr_value(solr_doc, 'use_license_machine', use_license.first, :string, [:stored_sortable])
201
- add_solr_value(solr_doc, 'use_licenses_machine', use_license, :symbol, [:stored_searchable])
202
-
203
- solr_doc
204
- end
205
-
206
147
  def use_license
207
148
  use_license = []
208
149
  use_license += Array(creative_commons)
@@ -211,11 +152,6 @@ module Dor
211
152
  use_license.reject(&:blank?)
212
153
  end
213
154
 
214
- # maintain AF < 8 indexing behavior
215
- def prefix
216
- ''
217
- end
218
-
219
155
  def rights
220
156
  xml = ng_xml
221
157
  if xml.search('//rightsMetadata/access[@type=\'read\']/machine/group').length == 1
@@ -76,11 +76,11 @@ module Dor
76
76
 
77
77
  delegate :full_title, :stanford_mods, to: :descMetadata
78
78
  delegate :rights, to: :rightsMetadata
79
- delegate :catkey, :catkey=, :source_id, :source_id=,
79
+ delegate :catkey, :catkey=, :source_id, :source_id=, :barcode, :barcode=,
80
80
  :objectId, :objectId=, :objectCreator, :objectCreator=,
81
81
  :objectLabel, :objectLabel=, :objectType, :objectType=,
82
- :other_ids=, :otherId, :tag=, :tags, :release_tags,
83
- :previous_catkeys, :content_type_tag, to: :identityMetadata
82
+ :other_ids=, :otherId, :release_tags, :previous_catkeys,
83
+ to: :identityMetadata
84
84
 
85
85
  def read_rights=(rights)
86
86
  rightsMetadata.set_read_rights(rights)
@@ -1,13 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'deprecation'
4
+
3
5
  module Dor
4
6
  class AdminPolicyObject < Dor::Abstract
7
+ extend Deprecation
5
8
  has_many :things, property: :is_governed_by, class_name: 'ActiveFedora::Base'
6
9
  has_object_type 'adminPolicy'
7
10
  has_metadata name: 'administrativeMetadata', type: Dor::AdministrativeMetadataDS, label: 'Administrative Metadata'
8
11
  has_metadata name: 'roleMetadata', type: Dor::RoleMetadataDS, label: 'Role Metadata'
9
12
  has_metadata name: 'defaultObjectRights', type: Dor::DefaultObjectRightsDS, label: 'Default Object Rights'
10
- belongs_to :agreement_object, property: :referencesAgreement, class_name: 'Dor::Item'
13
+ belongs_to :agreement_object, property: :referencesAgreement, class_name: 'Dor::Agreement'
11
14
 
12
15
  delegate :add_roleplayer, :purge_roles, :roles, to: :roleMetadata
13
16
  delegate :mods_title, :mods_title=, to: :descMetadata
@@ -29,11 +32,13 @@ module Dor
29
32
  def agreement
30
33
  agreement_object ? agreement_object.pid : ''
31
34
  end
35
+ deprecation_deprecate agreement: 'use #agreement_object_id instead'
32
36
 
33
37
  def agreement=(val)
34
38
  raise ArgumentError, 'agreement must have a valid druid' if val.blank?
35
39
 
36
40
  self.agreement_object = Dor.find val.to_s, cast: true
37
41
  end
42
+ deprecation_deprecate :agreement= => 'use #agreement_object_id= instead'
38
43
  end
39
44
  end
@@ -17,10 +17,12 @@ module Dor
17
17
  def release_embargo(release_agent = 'unknown')
18
18
  embargo_service.release(release_agent)
19
19
  end
20
+ deprecation_deprecate release_embargo: 'this moved to dor-service-app'
20
21
 
21
22
  def release_20_pct_vis_embargo(release_agent = 'unknown')
22
23
  embargo_service.release_20_pct_vis(release_agent)
23
24
  end
25
+ deprecation_deprecate release_20_pct_vis_embargo: 'this moved to dor-service-app'
24
26
 
25
27
  def embargoed?
26
28
  embargoMetadata.status == 'embargoed'
@@ -29,6 +31,7 @@ module Dor
29
31
  def update_embargo(new_date)
30
32
  embargo_service.update(new_date)
31
33
  end
34
+ deprecation_deprecate update_embargo: 'Use the method in EmbargoService instead'
32
35
 
33
36
  def embargo_service
34
37
  EmbargoService.new(self)
@@ -22,10 +22,11 @@ module Dor
22
22
  :regactiondttm, :documentaccess, :submit_date, :symphonyStatus,
23
23
  datastream: 'properties', multiple: false
24
24
 
25
- has_attributes :citation_verified, :abstract_provided, :dissertation_uploaded,
26
- :supplemental_files_uploaded, :permissions_provided,
27
- :permission_files_uploaded, :rights_selected,
28
- :cc_license_selected, :submitted_to_registrar,
25
+ has_attributes :citation_verified, :abstract_provided, :format_reviewed,
26
+ :dissertation_uploaded, :supplemental_files_uploaded,
27
+ :permissions_provided, :permission_files_uploaded,
28
+ :rights_selected, :cc_license_selected,
29
+ :submitted_to_registrar,
29
30
  datastream: 'workflow', multiple: false
30
31
 
31
32
  has_metadata name: 'properties', type: ActiveFedora::SimpleDatastream, versionable: false do |m|
@@ -77,6 +78,7 @@ module Dor
77
78
  has_metadata name: 'workflow', type: ActiveFedora::SimpleDatastream, versionable: false do |m|
78
79
  m.field 'citation_verified', :string
79
80
  m.field 'abstract_provided', :string
81
+ m.field 'format_reviewed', :string
80
82
  m.field 'dissertation_uploaded', :string
81
83
  m.field 'supplemental_files_uploaded', :string
82
84
  m.field 'permissions_provided', :string
@@ -35,6 +35,7 @@ module Dor
35
35
 
36
36
  events.add_event('embargo', release_agent, 'Embargo released')
37
37
  end
38
+ deprecation_deprecate release: 'this moved to dor-service-app'
38
39
 
39
40
  def release_20_pct_vis(release_agent)
40
41
  # Set status to released
@@ -55,25 +56,16 @@ module Dor
55
56
 
56
57
  events.add_event('embargo', release_agent, '20% Visibility Embargo released')
57
58
  end
59
+ deprecation_deprecate release_20_pct_vis: 'this moved to dor-service-app'
58
60
 
59
61
  def update(new_date)
60
62
  raise ArgumentError, 'You cannot change the embargo date of an item that is not embargoed.' if embargoMetadata.status != 'embargoed'
61
63
  raise ArgumentError, 'You cannot set the embargo date to a past date.' if new_date.past?
62
64
 
63
- updated = false
64
- rightsMetadata.ng_xml.search('//embargoReleaseDate').each do |node|
65
- node.content = new_date.beginning_of_day.utc.xmlschema
66
- updated = true
67
- end
68
- rightsMetadata.ng_xml_will_change!
69
- rightsMetadata.save
70
- raise 'No release date in rights metadata, cannot proceed!' unless updated
71
-
72
- embargoMetadata.ng_xml.xpath('//releaseDate').each do |node|
73
- node.content = new_date.beginning_of_day.utc.xmlschema
74
- end
75
- embargoMetadata.ng_xml_will_change!
76
- embargoMetadata.save
65
+ time = new_date.beginning_of_day.utc
66
+ rightsMetadata.embargo_release_date = time
67
+ embargoMetadata.release_date = time
68
+ obj.save!
77
69
  end
78
70
 
79
71
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dor
4
- VERSION = '9.1.0'
4
+ VERSION = '9.5.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dor-services
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.1.0
4
+ version: 9.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Klein
@@ -20,7 +20,7 @@ authors:
20
20
  autorequire:
21
21
  bindir: bin
22
22
  cert_chain: []
23
- date: 2020-03-11 00:00:00.000000000 Z
23
+ date: 2020-05-28 00:00:00.000000000 Z
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: active-fedora
@@ -450,7 +450,6 @@ files:
450
450
  - lib/dor/services/open_data_license_service.rb
451
451
  - lib/dor/services/search_service.rb
452
452
  - lib/dor/services/suri_service.rb
453
- - lib/dor/services/tag_service.rb
454
453
  - lib/dor/static_config.rb
455
454
  - lib/dor/static_config/fedora_config.rb
456
455
  - lib/dor/static_config/solr_config.rb
@@ -1,100 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dor
4
- # Manage tags on an object
5
- class TagService
6
- def self.add(item, tag)
7
- new(item).add(tag)
8
- end
9
-
10
- def self.remove(item, tag)
11
- new(item).remove(tag)
12
- end
13
-
14
- def self.update(item, old_tag, new_tag)
15
- new(item).update(old_tag, new_tag)
16
- end
17
-
18
- def initialize(item)
19
- @item = item
20
- end
21
-
22
- # Add an administrative tag to an item, you will need to seperately save the item to write it to fedora
23
- # @param tag [string] The tag you wish to add
24
- def add(tag)
25
- normalized_tag = validate_and_normalize_tag(tag, identity_metadata.tags)
26
- identity_metadata.add_value(:tag, normalized_tag)
27
- end
28
-
29
- def remove(tag)
30
- normtag = normalize_tag(tag)
31
- tag_nodes
32
- .select { |node| normalize_tag(node.content) == normtag }
33
- .each { identity_metadata.ng_xml_will_change! }
34
- .each(&:remove)
35
- .any?
36
- end
37
-
38
- def update(old_tag, new_tag)
39
- normtag = normalize_tag(old_tag)
40
- tag_nodes
41
- .select { |node| normalize_tag(node.content) == normtag }
42
- .each { identity_metadata.ng_xml_will_change! }
43
- .each { |node| node.content = normalize_tag(new_tag) }
44
- .any?
45
- end
46
-
47
- private
48
-
49
- attr_reader :item
50
- def identity_metadata
51
- item.identityMetadata
52
- end
53
-
54
- def tag_nodes
55
- identity_metadata.ng_xml.search('//tag')
56
- end
57
-
58
- # turns a tag string into an array with one element per tag part.
59
- # split on ":", disregard leading and trailing whitespace on tokens.
60
- def split_tag_to_arr(tag_str)
61
- tag_str.split(':').map(&:strip)
62
- end
63
-
64
- # turn a tag array back into a tag string with a standard format
65
- def normalize_tag_arr(tag_arr)
66
- tag_arr.join(' : ')
67
- end
68
-
69
- # take a tag string and return a normalized tag string
70
- def normalize_tag(tag_str)
71
- normalize_tag_arr(split_tag_to_arr(tag_str))
72
- end
73
-
74
- # take a proposed tag string and a list of the existing tags for the object being edited. if
75
- # the proposed tag is valid, return it in normalized form. if not, raise an exception with an
76
- # explanatory message.
77
- def validate_and_normalize_tag(tag_str, existing_tag_list)
78
- tag_arr = validate_tag_format(tag_str)
79
-
80
- # note that the comparison for duplicate tags is case-insensitive, but we don't change case as part of the normalized version
81
- # we return, because we want to preserve the user's intended case.
82
- normalized_tag = normalize_tag_arr(tag_arr)
83
- dupe_existing_tag = existing_tag_list.detect { |existing_tag| normalize_tag(existing_tag).casecmp(normalized_tag) == 0 }
84
- raise "An existing tag (#{dupe_existing_tag}) is the same, consider using update_tag?" if dupe_existing_tag
85
-
86
- normalized_tag
87
- end
88
-
89
- # Ensure that an administrative tag meets the proper mininum format
90
- # @param tag_str [String] the tag
91
- # @return [Array] the tag split into an array via ':'
92
- def validate_tag_format(tag_str)
93
- tag_arr = split_tag_to_arr(tag_str)
94
- raise ArgumentError, "Invalid tag structure: tag '#{tag_str}' must have at least 2 elements" if tag_arr.length < 2
95
- raise ArgumentError, "Invalid tag structure: tag '#{tag_str}' contains empty elements" if tag_arr.detect(&:empty?)
96
-
97
- tag_arr
98
- end
99
- end
100
- end