dor-services 5.1.0 → 5.1.1

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.
Files changed (41) hide show
  1. checksums.yaml +13 -5
  2. data/config/dev_console_env.rb +45 -32
  3. data/lib/dor-services.rb +52 -49
  4. data/lib/dor/datastreams/administrative_metadata_ds.rb +2 -2
  5. data/lib/dor/datastreams/content_metadata_ds.rb +114 -144
  6. data/lib/dor/datastreams/default_object_rights_ds.rb +10 -12
  7. data/lib/dor/datastreams/desc_metadata_ds.rb +4 -4
  8. data/lib/dor/datastreams/events_ds.rb +8 -8
  9. data/lib/dor/datastreams/identity_metadata_ds.rb +40 -23
  10. data/lib/dor/datastreams/rights_metadata_ds.rb +109 -0
  11. data/lib/dor/datastreams/role_metadata_ds.rb +4 -4
  12. data/lib/dor/datastreams/simple_dublin_core_ds.rb +6 -6
  13. data/lib/dor/datastreams/version_metadata_ds.rb +29 -10
  14. data/lib/dor/models/admin_policy_object.rb +3 -3
  15. data/lib/dor/models/describable.rb +5 -4
  16. data/lib/dor/models/editable.rb +29 -33
  17. data/lib/dor/models/embargoable.rb +1 -12
  18. data/lib/dor/models/governable.rb +4 -27
  19. data/lib/dor/models/identifiable.rb +60 -58
  20. data/lib/dor/models/item.rb +5 -9
  21. data/lib/dor/models/presentable.rb +15 -2
  22. data/lib/dor/models/processable.rb +34 -30
  23. data/lib/dor/models/publishable.rb +5 -14
  24. data/lib/dor/models/{releasable.rb → releaseable.rb} +59 -15
  25. data/lib/dor/models/rightsable.rb +25 -0
  26. data/lib/dor/models/versionable.rb +6 -3
  27. data/lib/dor/models/workflow_object.rb +4 -4
  28. data/lib/dor/services/cleanup_reset_service.rb +1 -2
  29. data/lib/dor/services/cleanup_service.rb +1 -1
  30. data/lib/dor/services/registration_service.rb +0 -3
  31. data/lib/dor/services/sdr_ingest_service.rb +1 -1
  32. data/lib/dor/services/search_service.rb +1 -1
  33. data/lib/dor/utils/sdr_client.rb +23 -0
  34. data/lib/dor/version.rb +1 -1
  35. data/lib/dor/workflow/document.rb +23 -22
  36. data/lib/tasks/rdoc.rake +4 -4
  37. metadata +113 -96
  38. data/config/environments/development.rb +0 -84
  39. data/config/environments/development.rb.old +0 -84
  40. data/config/environments/test.rb +0 -84
  41. data/lib/tasks/dor.rake +0 -39
@@ -1,20 +1,18 @@
1
1
  module Dor
2
- class DefaultObjectRightsDS < ActiveFedora::OmDatastream
2
+ class DefaultObjectRightsDS < ActiveFedora::OmDatastream
3
3
 
4
4
  set_terminology do |t|
5
5
  t.root :path => 'rightsMetadata', :index_as => [:not_searchable]
6
- t.copyright :path => 'copyright/human', :index_as => [:facetable]
7
- t.use_statement :path => '/use/human[@type=\'useAndReproduction\']', :index_as => [:facetable]
8
-
6
+ t.copyright :path => 'copyright/human', :index_as => [:symbol]
7
+ t.use_statement :path => '/use/human[@type=\'useAndReproduction\']', :index_as => [:symbol]
8
+
9
9
  t.use do
10
10
  t.machine
11
11
  t.human
12
12
  end
13
-
13
+
14
14
  t.creative_commons :path => '/use/machine', :type => 'creativeCommons'
15
15
  t.creative_commons_human :path => '/use/human[@type=\'creativeCommons\']'
16
-
17
-
18
16
  end
19
17
 
20
18
  define_template :creative_commons do |xml|
@@ -23,6 +21,7 @@ module Dor
23
21
  xml.machine(:type => "creativeCommons")
24
22
  }
25
23
  end
24
+
26
25
  def self.xml_template
27
26
  Nokogiri::XML::Builder.new do |xml|
28
27
  xml.rightsMetadata{
@@ -30,7 +29,7 @@ module Dor
30
29
  xml.machine{
31
30
  xml.world
32
31
  }
33
- }
32
+ }
34
33
  xml.access(:type => 'read'){
35
34
  xml.machine{
36
35
  xml.world
@@ -44,9 +43,8 @@ module Dor
44
43
  xml.copyright{
45
44
  xml.human
46
45
  }
47
-
48
- }
49
- end.doc
46
+ }
47
+ end.doc
48
+ end
50
49
  end
51
50
  end
52
- end
@@ -4,7 +4,7 @@ class DescMetadataDS < ActiveFedora::OmDatastream
4
4
  MODS_NS = 'http://www.loc.gov/mods/v3'
5
5
  set_terminology do |t|
6
6
  t.root :path => 'mods', :xmlns => MODS_NS, :index_as => [:not_searchable]
7
- t.originInfo :index_as => [:not_searchable] do
7
+ t.originInfo :index_as => [:not_searchable] do
8
8
  t.publisher :index_as => [:stored_searchable]
9
9
  t.date_created :path => 'dateCreated', :index_as => [:stored_searchable]
10
10
  t.place :index_as => [:not_searchable] do
@@ -31,9 +31,9 @@ class DescMetadataDS < ActiveFedora::OmDatastream
31
31
  def self.xml_template
32
32
  Nokogiri::XML::Builder.new do |xml|
33
33
  xml.mods( 'xmlns' => 'http://www.loc.gov/mods/v3', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',:version => '3.3', "xsi:schemaLocation" => 'http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-3.xsd'){
34
- xml.titleInfo{
35
- xml.title
36
- }
34
+ xml.titleInfo{
35
+ xml.title
36
+ }
37
37
  }
38
38
  end.doc
39
39
  end
@@ -3,12 +3,12 @@ class EventsDS < ActiveFedora::OmDatastream
3
3
  before_create :ensure_non_versionable
4
4
 
5
5
  set_terminology do |t|
6
- t.root(:path => "events")
6
+ t.root(:path => 'events')
7
7
  t.event do
8
- t.who :path => { :attribute => "who" }, :index_as => [:displayable, :not_searchable]
9
- t.type_ :path => { :attribute => "type" }, :index_as => [:displayable, :not_searchable]
10
- t.when :path => { :attribute => "when" }, :index_as => [:displayable, :not_searchable], :data_type => :date
11
- t.message :path => "text()", :index_as => [:displayable, :not_searchable]
8
+ t.who :path => { :attribute => 'who' }, :index_as => [:displayable, :not_searchable]
9
+ t.type_ :path => { :attribute => 'type' }, :index_as => [:displayable, :not_searchable]
10
+ t.when :path => { :attribute => 'when' }, :index_as => [:displayable, :not_searchable], :data_type => :date
11
+ t.message :path => 'text()', :index_as => [:displayable, :not_searchable]
12
12
  end
13
13
  end
14
14
 
@@ -21,7 +21,7 @@ class EventsDS < ActiveFedora::OmDatastream
21
21
  end
22
22
 
23
23
  def ensure_non_versionable
24
- self.versionable = "false"
24
+ self.versionable = 'false'
25
25
  end
26
26
 
27
27
  # Adds an event to the datastream
@@ -29,7 +29,7 @@ class EventsDS < ActiveFedora::OmDatastream
29
29
  # @param [String] who who is responsible for this event. Sets the who attribute for the event
30
30
  # @param [String] message what happened. Sets the content of the event with this message
31
31
  def add_event(type, who, message)
32
- ev = ng_xml.create_element "event", message,
32
+ ev = ng_xml.create_element 'event', message,
33
33
  :type => type, :who => who, :when => Time.now.xmlschema
34
34
  ng_xml.root.add_child(ev)
35
35
  ng_xml_will_change!
@@ -60,4 +60,4 @@ class EventsDS < ActiveFedora::OmDatastream
60
60
  end
61
61
 
62
62
  end
63
- end
63
+ end
@@ -4,18 +4,18 @@ class IdentityMetadataDS < ActiveFedora::OmDatastream
4
4
 
5
5
  set_terminology do |t|
6
6
  t.root(:path=>"identityMetadata")
7
- t.objectId :index_as => [:symbol, :searchable]
8
- t.objectType :index_as => [:symbol, :searchable, :facetable]
7
+ t.objectId :index_as => [:symbol]
8
+ t.objectType :index_as => [:symbol]
9
9
  t.objectLabel
10
10
  t.citationCreator
11
11
  t.sourceId
12
12
  t.otherId(:path => 'otherId') do
13
13
  t.name_(:path => { :attribute => 'name' })
14
14
  end
15
- t.agreementId :index_as => [:searchable, :facetable]
16
- t.tag :index_as => [:symbol, :searchable, :facetable]
15
+ t.agreementId :index_as => [:stored_searchable, :symbol]
16
+ t.tag :index_as => [:symbol]
17
17
  t.citationTitle
18
- t.objectCreator :index_as => [:searchable, :facetable]
18
+ t.objectCreator :index_as => [:stored_searchable, :symbol]
19
19
  t.adminPolicy :index_as => [:not_searchable]
20
20
  end
21
21
 
@@ -82,35 +82,52 @@ class IdentityMetadataDS < ActiveFedora::OmDatastream
82
82
 
83
83
  def to_solr(solr_doc=Hash.new, *args)
84
84
  super(solr_doc, *args)
85
+
85
86
  if digital_object.respond_to?(:profile)
86
- digital_object.profile.each_pair do |property,value|
87
- if property =~ /Date/
88
- add_solr_value(solr_doc, property.underscore, Time.parse(value).utc.xmlschema, :date, [:stored_searchable])
89
- else
90
- add_solr_value(solr_doc, property.underscore, value, :string, [:stored_searchable])
91
- end
87
+ digital_object.profile.each_pair do |property, value|
88
+ add_solr_value(solr_doc, property.underscore, value, (property =~ /Date/ ? :date : :symbol), [:stored_searchable])
92
89
  end
93
90
  end
91
+
94
92
  if sourceId.present?
95
- (name,id) = sourceId.split(/:/,2)
96
- add_solr_value(solr_doc, "dor_id", id, :string, [:searchable, :facetable])
97
- add_solr_value(solr_doc, "identifier", sourceId, :string, [:searchable, :facetable, :symbol])
98
- add_solr_value(solr_doc, "source_id", sourceId, :string, [:symbol, :searchable, :facetable])
93
+ (name, id) = sourceId.split(/:/, 2)
94
+ add_solr_value(solr_doc, "dor_id", id, :symbol, [:stored_searchable])
95
+ add_solr_value(solr_doc, "identifier", sourceId, :symbol, [:stored_searchable])
96
+ add_solr_value(solr_doc, "source_id", sourceId, :symbol, [])
99
97
  end
100
98
  otherId.compact.each { |qid|
101
- (name,id) = qid.split(/:/,2)
102
- add_solr_value(solr_doc, "dor_id", id, :string, [:searchable, :facetable])
103
- add_solr_value(solr_doc, "identifier", qid, :string, [:searchable, :facetable, :symbol])
104
- add_solr_value(solr_doc, "#{name}_id", id, :string, [:symbol, :searchable, :facetable])
99
+ # this section will solrize barcode and catkey, which live in otherId
100
+ (name, id) = qid.split(/:/, 2)
101
+ add_solr_value(solr_doc, "dor_id", id, :symbol, [:stored_searchable])
102
+ add_solr_value(solr_doc, "identifier", qid, :symbol, [:stored_searchable])
103
+ add_solr_value(solr_doc, "#{name}_id", id, :symbol, [])
105
104
  }
106
-
105
+
106
+ # do some stuff to make tags in general and project tags specifically more easily searchable and facetable
107
107
  self.find_by_terms(:tag).each { |tag|
108
- (top,rest) = tag.text.split(/:/,2)
108
+ (prefix, rest) = tag.text.split(/:/, 2)
109
+ prefix = prefix.downcase.strip.gsub(/\s/,'_')
109
110
  unless rest.nil?
110
- add_solr_value(solr_doc, "#{top.downcase.strip.gsub(/\s/,'_')}_tag", rest.strip, :string, [:symbol, :searchable, :facetable])
111
+ # this part will index a value in a field specific to the tag, e.g. registered_by_tag_*,
112
+ # book_tag_*, project_tag_*, remediated_by_tag_*, etc. project_tag_* and registered_by_tag_*
113
+ # definitley get used, but most don't. we can limit the prefixes that get solrized if things
114
+ # get out of hand.
115
+ add_solr_value(solr_doc, "#{prefix}_tag", rest.strip, :symbol, [])
116
+ end
117
+
118
+ # solrize each possible prefix for the tag, inclusive of the full tag.
119
+ # e.g., for a tag such as "A : B : C", this will solrize to an _ssim field
120
+ # that contains ["A", "A : B", "A : B : C"].
121
+ tag_parts = tag.text.split(/:/)
122
+ progressive_tag_prefix = ''
123
+ tag_parts.each_with_index do |part, index|
124
+ progressive_tag_prefix += " : " if index > 0
125
+ progressive_tag_prefix += part.strip
126
+ add_solr_value(solr_doc, "exploded_tag", progressive_tag_prefix, :symbol, [])
111
127
  end
112
128
  }
113
- solr_doc
129
+
130
+ return solr_doc
114
131
  end
115
132
  end #class
116
133
  end
@@ -0,0 +1,109 @@
1
+ module Dor
2
+ class RightsMetadataDS < ActiveFedora::OmDatastream
3
+ require 'dor/rights_auth'
4
+
5
+ attr_writer :dra_object
6
+
7
+ # This is separate from default_object_rights because
8
+ # (1) we cannot default to such a permissive state
9
+ # (2) this is real, not default
10
+ #
11
+ # Ultimately, default_object_rights should go away and APOs also use an instantation of this class
12
+
13
+ set_terminology do |t|
14
+ t.root :path => 'rightsMetadata', :index_as => [:not_searchable]
15
+ t.copyright :path => 'copyright/human', :index_as => [:symbol]
16
+ t.use_statement :path => '/use/human[@type=\'useAndReproduction\']', :index_as => [:symbol]
17
+
18
+ t.use do
19
+ t.machine
20
+ t.human
21
+ end
22
+
23
+ t.creative_commons :path => '/use/machine', :type => 'creativeCommons'
24
+ t.creative_commons_human :path => '/use/human[@type=\'creativeCommons\']'
25
+ end
26
+
27
+ define_template :creative_commons do |xml|
28
+ xml.use {
29
+ xml.human(:type => "creativeCommons")
30
+ xml.machine(:type => "creativeCommons")
31
+ }
32
+ end
33
+
34
+ def self.xml_template
35
+ Nokogiri::XML::Builder.new do |xml|
36
+ xml.rightsMetadata{
37
+ xml.access(:type => 'discover'){
38
+ xml.machine{ xml.none }
39
+ }
40
+ xml.access(:type => 'read'){
41
+ xml.machine{ xml.none } # dark default
42
+ }
43
+ xml.use{
44
+ xml.human(:type => 'useAndReproduction')
45
+ xml.human(:type => "creativeCommons")
46
+ xml.machine(:type => "creativeCommons")
47
+ }
48
+ xml.copyright{ xml.human }
49
+ }
50
+ end.doc
51
+ end
52
+
53
+ # just a wrapper to invalidate @dra_object
54
+ def content=(xml)
55
+ @dra_object = nil
56
+ super
57
+ end
58
+
59
+ def dra_object
60
+ @dra_object ||= Dor::RightsAuth.parse(self.ng_xml, true)
61
+ end
62
+
63
+ # @param rights [string] archetypical rights to assign: 'world', 'stanford', 'none' or 'dark'
64
+ # Moved from Governable
65
+ # slight misnomer: also sets discover rights!
66
+ # TODO: convert xpath reads to dra_object calls
67
+ def set_read_rights(rights)
68
+ raise(ArgumentError, "Argument '#{rights}' is not a recognized value") unless ['world','stanford','none','dark'].include? rights
69
+ rights_xml = self.ng_xml
70
+ if (rights_xml.search('//rightsMetadata/access[@type=\'read\']').length==0)
71
+ raise('The rights metadata stream doesnt contain an entry for machine read permissions. Consider populating it from the APO before trying to change it.')
72
+ end
73
+ label = rights=='dark' ? 'none' : 'world'
74
+ @dra_object = nil # until TODO complete, we'll expect to have to reparse after modification
75
+ rights_xml.search('//rightsMetadata/access[@type=\'discover\']/machine').each do |node|
76
+ node.children.remove
77
+ node.add_child Nokogiri::XML::Node.new(label,rights_xml)
78
+ end
79
+ rights_xml.search('//rightsMetadata/access[@type=\'read\']').each do |node|
80
+ node.children.remove
81
+ machine_node = Nokogiri::XML::Node.new('machine',rights_xml)
82
+ node.add_child(machine_node)
83
+ if rights == 'world'
84
+ machine_node.add_child Nokogiri::XML::Node.new(rights,rights_xml)
85
+ elsif rights == 'stanford'
86
+ group_node = Nokogiri::XML::Node.new('group',rights_xml)
87
+ group_node.content = "Stanford"
88
+ machine_node.add_child(group_node)
89
+ else # we know it is none or dark by the argument filter (first line)
90
+ machine_node.add_child Nokogiri::XML::Node.new('none',rights_xml)
91
+ end
92
+ end
93
+ end
94
+
95
+ def to_solr(solr_doc=Hash.new, *args)
96
+ super(solr_doc, *args)
97
+ dra = self.dra_object
98
+ solr_doc['rights_primary_ssi'] = dra.index_elements[:primary]
99
+ solr_doc['rights_errors_ssim'] = dra.index_elements[:errors] if dra.index_elements[:errors].size > 0
100
+ solr_doc['rights_characteristics_ssim'] = dra.index_elements[:terms] if dra.index_elements[:terms].size > 0
101
+ # suppress empties
102
+ %w[use_statement_ssim copyright_ssim].each do |key|
103
+ solr_doc[key] = solr_doc[key].reject{ |val| val.nil? || val == '' }.flatten unless solr_doc[key].nil?
104
+ end
105
+ solr_doc
106
+ end
107
+
108
+ end #class
109
+ end
@@ -37,11 +37,11 @@ class RoleMetadataDS < ActiveFedora::OmDatastream
37
37
  def to_solr(solr_doc=Hash.new, *args)
38
38
  self.find_by_xpath('/roleMetadata/role/*').each do |actor|
39
39
  role_type = actor.parent['type']
40
- val = [actor.at_xpath('identifier/@type'),actor.at_xpath('identifier/text()')].join ':'
41
- add_solr_value(solr_doc, "apo_role_#{actor.name}_#{role_type}", val, :string, [:searchable, :facetable, :symbol])
42
- add_solr_value(solr_doc, "apo_role_#{role_type}", val, :string, [:searchable, :facetable, :symbol])
40
+ val = [actor.at_xpath('identifier/@type'), actor.at_xpath('identifier/text()')].join ':'
41
+ add_solr_value(solr_doc, "apo_role_#{actor.name}_#{role_type}", val, :string, [:symbol])
42
+ add_solr_value(solr_doc, "apo_role_#{role_type}", val, :string, [:symbol])
43
43
  if ['dor-apo-manager','dor-apo-depositor'].include? role_type
44
- add_solr_value(solr_doc, "apo_register_permissions", val, :string, [:searchable, :facetable, :symbol])
44
+ add_solr_value(solr_doc, "apo_register_permissions", val, :string, [:symbol, :stored_searchable])
45
45
  end
46
46
  end
47
47
  solr_doc
@@ -3,9 +3,9 @@ class SimpleDublinCoreDs < ActiveFedora::OmDatastream
3
3
 
4
4
  set_terminology do |t|
5
5
  t.root(:path=>"dc", :xmlns=>"http://www.openarchives.org/OAI/2.0/oai_dc/", :schema=>"http://cosimo.stanford.edu/standards/oai_dc/v2/oai_dc.xsd", :namespace_prefix => 'oai_dc', :index_as => [:not_searchable])
6
- t.title( :index_as=>[:displayable, :facetable, :stored_searchable], :xmlns => "http://purl.org/dc/elements/1.1/", :namespace_prefix => 'dc')
7
- t.creator( :index_as=>[:displayable, :facetable, :stored_searchable], :xmlns => "http://purl.org/dc/elements/1.1/", :namespace_prefix => 'dc')
8
- t.identifier(:index_as=>[:displayable, :stored_searchable], :xmlns => "http://purl.org/dc/elements/1.1/", :namespace_prefix => 'dc')
6
+ t.title( :index_as=>[:stored_sortable, :stored_searchable], :xmlns => "http://purl.org/dc/elements/1.1/", :namespace_prefix => 'dc')
7
+ t.creator( :index_as=>[:stored_sortable, :stored_searchable], :xmlns => "http://purl.org/dc/elements/1.1/", :namespace_prefix => 'dc')
8
+ t.identifier(:index_as=>[:symbol, :stored_searchable], :xmlns => "http://purl.org/dc/elements/1.1/", :namespace_prefix => 'dc')
9
9
  end
10
10
 
11
11
  def self.xml_template
@@ -27,15 +27,15 @@ class SimpleDublinCoreDs < ActiveFedora::OmDatastream
27
27
  begin
28
28
  doc = super solr_doc, *args
29
29
 
30
- add_solr_value(doc, 'dc_title', self.title.first, :string, [:sortable])
31
- add_solr_value(doc, 'dc_creator', self.creator.first, :string, [:sortable])
30
+ add_solr_value(doc, 'dc_title', self.title.first, :string, [:stored_sortable, :stored_searchable])
31
+ add_solr_value(doc, 'dc_creator', self.creator.first, :string, [:stored_sortable, :stored_searchable])
32
32
 
33
33
  identifiers = {}
34
34
 
35
35
  self.identifier.each { |i| ns, val = i.split(":"); identifiers[ns] ||= val }
36
36
 
37
37
  identifiers.each do |ns, val|
38
- add_solr_value(doc, "dc_identifier_#{ns}", val, :string, [:sortable])
38
+ add_solr_value(doc, "dc_identifier_#{ns}", val, :string, [:stored_sortable, :stored_searchable])
39
39
  end
40
40
 
41
41
  return doc
@@ -107,7 +107,7 @@ module Dor
107
107
  end
108
108
  end
109
109
 
110
- # @return [Fixnum] value of the most current versionId
110
+ # @return [String] value of the most current versionId
111
111
  def current_version_id
112
112
  current_version=current_version_node
113
113
  if current_version.nil?
@@ -151,11 +151,6 @@ module Dor
151
151
  self.content = ng_xml.to_s
152
152
  end
153
153
 
154
- # @return [String] The value of the greatest versionId
155
- def current_version_id
156
- current_version_node[:versionId].to_s
157
- end
158
-
159
154
  # @return [Boolean] returns true if the current version has a tag and a description, false otherwise
160
155
  def current_version_closeable?
161
156
  current = current_version_node
@@ -168,9 +163,9 @@ module Dor
168
163
 
169
164
  # @return [String] The tag for the newest version
170
165
  def current_tag
171
- current_version_node[:tag].to_s
166
+ current_version_node[:tag].to_s
172
167
  end
173
-
168
+
174
169
  def tag_for_version(versionId)
175
170
  nodes=self.ng_xml.search('//version[@versionId=\''+versionId+'\']')
176
171
  if nodes.length == 1
@@ -179,6 +174,7 @@ module Dor
179
174
  ''
180
175
  end
181
176
  end
177
+
182
178
  # @return [String] The description for the specified version, or empty string if there is no description
183
179
  def description_for_version(versionId)
184
180
  nodes=self.ng_xml.search('//version[@versionId=\''+versionId+'\']')
@@ -188,7 +184,7 @@ module Dor
188
184
  ''
189
185
  end
190
186
  end
191
-
187
+
192
188
  # @return [String] The description for the current version
193
189
  def current_description
194
190
  desc_node=current_version_node.at_xpath('description')
@@ -197,7 +193,29 @@ module Dor
197
193
  end
198
194
  ''
199
195
  end
200
-
196
+
197
+ # Compares the current_version with the passed in known_version (usually SDRs version)
198
+ # If the known_version is greater than the current version, then all version nodes greater than the known_version are removed,
199
+ # then the current_version is incremented. This repairs the case where a previous call to open a new verison
200
+ # updates the versionMetadata datastream, but versioningWF is not initiated. Prevents the versions from getting
201
+ # out of synch with SDR
202
+ #
203
+ # @param [Integer] known_version object version you wish to synch to, usually SDR's version
204
+ # @param [Hash] opts optional parameters
205
+ # @option opts [String] :description describes the version change
206
+ # @option opts [Symbol] :significance which part of the version tag to increment
207
+ def sync_then_increment_version known_version, opts = {}
208
+ cv = current_version_id.to_i
209
+ raise Dor::Exception.new("Cannot sync to a version greater than current: #{cv}, requested #{known_version}") if cv < known_version
210
+
211
+ while cv != known_version &&
212
+ current_version_node.remove
213
+ cv = current_version_id.to_i
214
+ end
215
+
216
+ increment_version(opts[:description], opts[:significance])
217
+ end
218
+
201
219
  private
202
220
 
203
221
  # @return [Nokogiri::XML::Node] Node representing the current version
@@ -210,5 +228,6 @@ module Dor
210
228
  tags = find_by_terms(:version, :tag)
211
229
  tags.map{|t| VersionTag.parse(t.value)}.max
212
230
  end
231
+
213
232
  end
214
233
  end