rubydora 1.8.1 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,12 @@
1
+ sudo: false
1
2
  language: ruby
2
3
  rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - 2.1
4
+ - 2.1.10
5
+ - 2.2.5
6
+ - 2.3.1
6
7
 
7
- gemfile:
8
- - gemfiles/gemfile.rails3
9
- - gemfiles/gemfile.rails4
8
+ jdk:
9
+ - oraclejdk8
10
10
 
11
11
  notifications:
12
12
  irc: "irc.freenode.org#projecthydra"
data/Gemfile CHANGED
@@ -1,7 +1,6 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'simplecov', :platform => :mri_19
6
- gem 'simplecov-rcov', :platform => :mri_19
7
5
  gem 'jruby-openssl', :platform => :jruby
6
+ gem 'activesupport', '< 5' if RUBY_VERSION < '2.2.2'
@@ -0,0 +1,86 @@
1
+ # rubydora
2
+ [<img src="https://travis-ci.org/projecthydra/rubydora.png?branch=master"
3
+ alt="Build Status" />](https://travis-ci.org/projecthydra/rubydora) [<img
4
+ src="https://badge.fury.io/rb/rubydora.png" alt="Gem Version"
5
+ />](http://badge.fury.io/rb/rubydora)
6
+
7
+ Rubydora is a low-level Fedora Commons REST API consumer, providing direct
8
+ access to REST API methods, as well as a primitive ruby abstraction.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ gem install rubydora
14
+ ```
15
+
16
+ ## Examples
17
+
18
+ ```
19
+ > repo = Rubydora.connect :url => 'http://localhost:8983/fedora', :user => 'fedoraAdmin', :password => 'fedoraAdmin'
20
+ => #<Rubydora::Repository:0x101859538 @config={:url=>"http://localhost:8983/fedora", :user=>"fedoraAdmin", :password=>"fedoraAdmin"}>
21
+
22
+ > obj = repo.find('test:1')
23
+ => #<Rubydora::DigitalObject:0x101977230 @pid="test:1", @repository=#<Rubydora::Repository:0x1019beef0 @config={:user=>"fedoraAdmin", :url=>"http://localhost:8983/fedora", :password=>"fedora"}>>
24
+
25
+ > obj.new?
26
+ => true
27
+
28
+ > obj = obj.save
29
+ => #<Rubydora::DigitalObject:0x1017601b8 @pid="test:1", @repository=#<Rubydora::Repository:0x1018e3058 @config={:url=>"http://localhost:8983/fedora", :user=>"fedoraAdmin", :password=>"fedoraAdmin"}, @client=#<RestClient::Resource:0x101882910 @options={:user=>"fedoraAdmin", :password=>"fedoraAdmin"}, @block=nil, @url="http://localhost:8983/fedora">>>
30
+
31
+ > obj.profile
32
+ => {"objDissIndexViewURL"=>"http://localhost:8983/fedora/get/test:1/fedora-system:3/viewMethodIndex", "objLabel"=>"", "objModels"=>"info:fedora/fedora-system:FedoraObject-3.0", "objCreateDate"=>"2011-04-18T13:34:11.285Z", "objOwnerId"=>"fedoraAdmin", "objState"=>"A", "objItemIndexViewURL"=>"http://localhost:8983/fedora/get/test:1/fedora-system:3/viewItemIndex", "objLastModDate"=>"2011-04-18T13:47:30.110Z"}
33
+
34
+ > obj.models
35
+ => ["info:fedora/fedora-system:FedoraObject-3.0"]
36
+
37
+ > obj.models << 'info:fedora/test:cmodel'
38
+ => ["info:fedora/fedora-system:FedoraObject-3.0", "info:fedora/test:cmodel"]
39
+
40
+ > obj2 = repo.find('test:2')
41
+ => [...]
42
+
43
+ > obj1.parts << obj2
44
+ => [...]
45
+
46
+ > obj.datastreams
47
+ => {"DC"=>#<Rubydora::Datastream:0x101860180 @dsid="DC" ...> }
48
+
49
+ > ds = obj.datastreams['File']
50
+ => #<Rubydora::Datastream:0x1017f26a8 @dsid="File" ...>
51
+ > ds.controlGroup = 'R'
52
+ => "R"
53
+ > ds.dsLocation = 'http://example.org/index.html'
54
+ => "http://example.org/index.html"
55
+ > ds.dsLabel = 'Example redirect datastream'
56
+ => "Example redirect datastream"
57
+ > ds.mimeType = 'text/html'
58
+ => "text/html"
59
+ > ds.save
60
+ => #<Rubydora::Datastream:0x10177a568 @dsid="File" ...>
61
+
62
+ > obj.datastreams
63
+ => {"DC"=>#<Rubydora::Datastream:0x101860180 @dsid="DC" ..., "File"=>#<Rubydora::Datastream:0x10177a568 @dsid="File" ...>}
64
+
65
+ > obj.datastreams["File"].delete
66
+ => true
67
+ > obj.datastreams["File"].new?
68
+ => true
69
+ ```
70
+
71
+ ## Contributing to rubydora
72
+
73
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
74
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
75
+ * Fork the project
76
+ * Start a feature/bugfix branch
77
+ * Commit and push until you are happy with your contribution
78
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
79
+ * Please try not to mess with the Rakefile, version, or history. If you want
80
+ to have your own version, or is otherwise necessary, that is fine, but
81
+ please isolate to its own commit so I can cherry-pick around it.
82
+
83
+ ## Copyright
84
+
85
+ Copyright (c) 2011 Chris Beer. See LICENSE.txt for further details.
86
+
data/Rakefile CHANGED
@@ -1,56 +1,57 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
3
  require 'jettywrapper'
4
+ require 'yard'
4
5
  require 'bundler/gem_tasks'
5
6
 
7
+ ZIP_URL = 'https://github.com/projecthydra/hydra-jetty/archive/v7.2.0.zip'
8
+
6
9
  begin
7
10
  Bundler.setup(:default, :development)
8
11
  rescue Bundler::BundlerError => e
9
12
  $stderr.puts e.message
10
- $stderr.puts "Run `bundle install` to install missing gems"
13
+ $stderr.puts 'Run `bundle install` to install missing gems'
11
14
  exit e.status_code
12
15
  end
13
16
 
14
17
  # Get your spec rake tasks working in RSpec 2.0
15
-
16
18
  require 'rspec/core/rake_task'
17
19
 
18
20
  desc 'Default: run ci build.'
19
21
  task :default => :ci
20
22
 
21
- desc "Run specs"
23
+ desc 'Run specs'
22
24
  RSpec::Core::RakeTask.new do |t|
23
-
24
- if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.8/
25
+ if ENV['COVERAGE'] && RUBY_VERSION =~ /^1.8/
25
26
  t.rcov = true
26
27
  t.rcov_opts = %w{--exclude spec\/*,gems\/*,ruby\/* --aggregate coverage.data}
27
28
  end
28
29
  end
29
30
 
30
- require 'yard'
31
- YARD::Rake::YardocTask.new do |t|
32
- t.options = ["--readme", "README.rdoc"]
31
+ YARD::Rake::YardocTask.new do |yt|
32
+ yt.files = ['lib/**/*.rb']
33
+ yt.options = ['--readme', 'README.md']
33
34
  end
34
35
 
35
- desc "Open an irb session preloaded with this library"
36
+ desc 'Open an irb session preloaded with this library'
36
37
  task :console do
37
- sh "irb -rubygems -I lib -r rubydora.rb"
38
+ sh 'irb -rubygems -I lib -r rubydora.rb'
38
39
  end
39
40
 
40
- desc "Execute Continuous Integration build"
41
+ desc 'Execute Continuous Integration build'
41
42
  task :ci => 'jetty:clean' do
42
43
  unless ENV['environment'] == 'test'
43
- exec("rake ci environment=test")
44
+ exec('rake ci environment=test')
44
45
  end
45
46
 
46
47
  jetty_params = {
47
- :jetty_home => File.expand_path(File.dirname(__FILE__) + '/jetty'),
48
- :quiet => false,
49
- :jetty_port => ENV['TEST_JETTY_PORT'] || 8983,
50
- :solr_home => File.expand_path(File.dirname(__FILE__) + '/jetty/solr'),
51
- :fedora_home => File.expand_path(File.dirname(__FILE__) + '/jetty/fedora/default'),
48
+ :jetty_home => File.expand_path(File.dirname(__FILE__) + '/jetty'),
49
+ :quiet => true,
50
+ :jetty_port => ENV['TEST_JETTY_PORT'] || 8983,
51
+ :solr_home => File.expand_path(File.dirname(__FILE__) + '/jetty/solr'),
52
+ :fedora_home => File.expand_path(File.dirname(__FILE__) + '/jetty/fedora/default'),
52
53
  :startup_wait => 90,
53
- :java_opts => ['-Xmx256m', '-XX:MaxPermSize=128m']
54
+ :java_opts => ['-Xmx256m', '-XX:MaxPermSize=128m']
54
55
  }
55
56
 
56
57
  error = Jettywrapper.wrap(jetty_params) do
@@ -60,14 +61,10 @@ task :ci => 'jetty:clean' do
60
61
  raise "test failures: #{error}" if error
61
62
  end
62
63
 
63
-
64
- desc "Execute specs with coverage"
65
- task :coverage do
64
+ desc 'Execute specs with coverage'
65
+ task :coverage do
66
66
  # Put spec opts in a file named .rspec in root
67
- ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
67
+ ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
68
68
  ENV['COVERAGE'] = 'true' unless ruby_engine == 'jruby'
69
-
70
-
71
69
  Rake::Task['spec'].invoke
72
70
  end
73
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.1
1
+ 1.9.0
@@ -23,9 +23,6 @@ module Rubydora
23
23
  require 'time'
24
24
  require 'hooks'
25
25
 
26
- if CSV.const_defined? :Reader
27
- require 'fastercsv'
28
- end
29
26
  require 'restclient'
30
27
  require 'nokogiri'
31
28
 
@@ -35,7 +32,7 @@ module Rubydora
35
32
  class << self
36
33
  # Connect to Fedora Repository
37
34
  # @return Rubydora::Repository
38
- def connect *args
35
+ def connect(*args)
39
36
  Repository.new *args
40
37
  end
41
38
 
@@ -48,7 +45,7 @@ module Rubydora
48
45
  # Set the default Fedora Repository
49
46
  # @param [Rubydora::Repository] repository
50
47
  # @return Rubydora::Repository
51
- def repository= repository
48
+ def repository=(repository)
52
49
  @repository = repository
53
50
  end
54
51
 
@@ -64,6 +61,6 @@ module Rubydora
64
61
 
65
62
  class FedoraInvalidRequest < RubydoraError; end
66
63
 
67
- class RecordNotFound < RubydoraError; end
64
+ class RecordNotFound < RubydoraError; end
68
65
 
69
66
  end
@@ -1,11 +1,11 @@
1
1
  module Rubydora
2
2
  ##
3
- # This is an attempt to implement an Array-like
4
- # object that calls a method after data is modified
3
+ # This is an attempt to implement an Array-like
4
+ # object that calls a method after data is modified
5
5
  class ArrayWithCallback < Array
6
6
  ##
7
7
  # FIXME: It would be nice to use Rubydora::Callbacks here,
8
- # however, this method requires instance-level callbacks
8
+ # however, this method requires instance-level callbacks
9
9
 
10
10
  [:<<, :collect!, :map!, :compact!, :concat, :delete, :delete_at, :delete_if, :pop, :push, :reject!, :replace, :select!, :[]=, :slice!, :uniq! ].each do |method|
11
11
  class_eval <<-RUBY
@@ -25,7 +25,7 @@ module Rubydora
25
25
  end
26
26
 
27
27
  # duck-typing Rubydora::Callbacks call_* methods
28
- def call_on_change changes = {}
28
+ def call_on_change(changes = {})
29
29
  self.on_change.each do |h|
30
30
  h.call(self, changes)
31
31
  end
@@ -5,19 +5,19 @@ module Rubydora::AuditTrail
5
5
  end
6
6
 
7
7
  private
8
-
8
+
9
9
  AT_NS = {'audit' => 'info:fedora/fedora-system:def/audit#'}
10
10
  FOXML_NS = {'foxml' => 'info:fedora/fedora-system:def/foxml#'}
11
11
  AT_XPATH = '/foxml:digitalObject/foxml:datastream[@ID = "AUDIT"]/descendant::audit:auditTrail'
12
-
12
+
13
13
  class FedoraAuditTrail
14
14
  def initialize(object_xml)
15
- @ng_xml = Nokogiri::XML(object_xml).xpath(AT_XPATH, FOXML_NS.merge(AT_NS))
15
+ @ng_xml = Nokogiri::XML(object_xml).xpath(AT_XPATH, FOXML_NS.merge(AT_NS))
16
16
  end
17
17
  def records
18
- if !@records
18
+ unless @records
19
19
  @records = []
20
- @ng_xml.xpath('.//audit:record', AT_NS).each do |node|
20
+ @ng_xml.xpath('.//audit:record', AT_NS).each do |node|
21
21
  @records << FedoraAuditRecord.new(node)
22
22
  end
23
23
  end
@@ -27,7 +27,7 @@ module Rubydora::AuditTrail
27
27
  @ng_xml.to_xml
28
28
  end
29
29
  end
30
-
30
+
31
31
  class FedoraAuditRecord
32
32
  def initialize(node)
33
33
  @record = node
@@ -53,6 +53,6 @@ module Rubydora::AuditTrail
53
53
  def justification
54
54
  @record.at_xpath('audit:justification', AT_NS).text
55
55
  end
56
- end
56
+ end
57
57
 
58
58
  end
@@ -1,10 +1,10 @@
1
1
  module Rubydora
2
2
 
3
- # Provides class level methods for handling
4
- # callback methods that alter object instances
3
+ # Provides class level methods for handling
4
+ # callback methods that alter object instances
5
5
  module Callbacks
6
6
  # add callback framework to base class
7
- # @param [Class] base
7
+ # @param [Class] base
8
8
  def self.included(base)
9
9
  base.extend ExtendableClassMethods
10
10
  end
@@ -19,10 +19,10 @@ module Rubydora
19
19
 
20
20
  # register callback procs
21
21
  # @param [Array<Symbol>] hook name
22
- def register_callback *attrs
23
- attrs.each do |method_name|
22
+ def register_callback(*attrs)
23
+ attrs.each do |method_name|
24
24
  next if methods.include? method_name.to_s
25
- instance_eval %Q{
25
+ instance_eval "
26
26
  def #{method_name}(&blk)
27
27
  self.hooks[:#{method_name}] ||= []
28
28
  self.hooks[:#{method_name}] << blk
@@ -31,9 +31,9 @@ module Rubydora
31
31
  def clear_#{method_name}_blocks!
32
32
  self.hooks[:#{method_name}] = []
33
33
  end
34
- }
34
+ "
35
35
 
36
- class_eval %Q{
36
+ class_eval "
37
37
  def call_#{method_name}
38
38
  self.class.hooks[:#{method_name}] ||= []
39
39
  self.class.hooks[:#{method_name}].each do |h|
@@ -41,7 +41,7 @@ module Rubydora
41
41
  end
42
42
  end
43
43
 
44
- }
44
+ "
45
45
  end
46
46
  end
47
47
  end
@@ -2,7 +2,7 @@ require 'equivalent-xml'
2
2
  module Rubydora
3
3
  # This class represents a Fedora datastream object
4
4
  # and provides helper methods for creating and manipulating
5
- # them.
5
+ # them.
6
6
  class Datastream
7
7
  extend ActiveModel::Callbacks
8
8
  define_model_callbacks :save, :create, :destroy
@@ -21,42 +21,41 @@ module Rubydora
21
21
 
22
22
  define_attribute_methods DS_ATTRIBUTES.keys
23
23
 
24
- # accessors for datastream attributes
24
+ # accessors for datastream attributes
25
25
  DS_ATTRIBUTES.each do |attribute, profile_name|
26
26
  define_method attribute.to_s do
27
27
  var = "@#{attribute.to_s}".to_sym
28
28
  if instance_variable_defined?(var)
29
29
  instance_variable_get var
30
30
  elsif profile.has_key? profile_name.to_s
31
- profile[profile_name.to_s]
31
+ profile[profile_name.to_s]
32
32
  else
33
33
  default_attributes[attribute.to_sym]
34
34
  end
35
35
  end
36
36
 
37
- class_eval %Q{
37
+ class_eval "
38
38
  def #{attribute.to_s}= val
39
39
  validate_#{attribute.to_s}!(val) if respond_to?(:validate_#{attribute.to_s}!, true)
40
40
  #{attribute.to_s}_will_change! unless val == #{attribute.to_s}
41
41
  @#{attribute.to_s} = val
42
42
  end
43
- }
43
+ "
44
44
  end
45
45
 
46
46
  DS_READONLY_ATTRIBUTES = [ :dsCreateDate , :dsSize, :dsVersionID ]
47
47
  DS_READONLY_ATTRIBUTES.each do |attribute|
48
- class_eval %Q{
48
+ class_eval "
49
49
  def #{attribute.to_s}
50
50
  @#{attribute} || profile['#{attribute.to_s}'] || default_attributes[:#{attribute}]
51
51
  end
52
- }
52
+ "
53
53
 
54
54
  def dsChecksumValid
55
55
  profile(:validateChecksum=>true)['dsChecksumValid']
56
56
  end
57
57
  end
58
58
 
59
-
60
59
  # Create humanized accessors for the DS attribute (dsState -> state, dsCreateDate -> createDate)
61
60
  (DS_ATTRIBUTES.keys + DS_READONLY_ATTRIBUTES).select { |k| k.to_s =~ /^ds/ }.each do |attribute|
62
61
  simple_attribute = attribute.to_s.sub(/^ds/, '')
@@ -69,13 +68,12 @@ module Rubydora
69
68
  end
70
69
  end
71
70
 
72
-
73
- def asOfDateTime asOfDateTime = nil
74
- if asOfDateTime == nil
71
+ def asOfDateTime(asOfDateTime = nil)
72
+ if asOfDateTime.nil?
75
73
  return @asOfDateTime
76
74
  end
77
75
 
78
- return self.class.new(@digital_object, dsid, @options.merge(:asOfDateTime => asOfDateTime))
76
+ self.class.new(@digital_object, dsid, @options.merge(:asOfDateTime => asOfDateTime))
79
77
  end
80
78
 
81
79
  def self.default_attributes
@@ -86,7 +84,7 @@ module Rubydora
86
84
  @default_attributes ||= self.class.default_attributes
87
85
  end
88
86
 
89
- def default_attributes= attributes
87
+ def default_attributes=(attributes)
90
88
  @default_attributes = default_attributes.merge attributes
91
89
  end
92
90
 
@@ -95,11 +93,11 @@ module Rubydora
95
93
  # may not already exist in the datastore.
96
94
  #
97
95
  # Provides `after_initialize` callback for extensions
98
- #
96
+ #
99
97
  # @param [Rubydora::DigitalObject]
100
98
  # @param [String] Datastream ID
101
99
  # @param [Hash] default attribute values (used esp. for creating new datastreams)
102
- def initialize digital_object, dsid, options = {}, default_instance_attributes = {}
100
+ def initialize(digital_object, dsid, options = {}, default_instance_attributes = {})
103
101
  run_callbacks :initialize do
104
102
  @digital_object = digital_object
105
103
  @dsid = dsid
@@ -119,7 +117,10 @@ module Rubydora
119
117
  # Does this datastream already exist?
120
118
  # @return [Boolean]
121
119
  def new?
122
- digital_object.nil? || digital_object.new_record? || profile.empty?
120
+ digital_object.nil? ||
121
+ (digital_object.respond_to?(:new_record?) && digital_object.new_record?) ||
122
+ (digital_object.respond_to?(:new?) && digital_object.new?) ||
123
+ profile.empty?
123
124
  end
124
125
 
125
126
  # This method is overridden in ActiveFedora, so we didn't
@@ -131,7 +132,7 @@ module Rubydora
131
132
  # @param [Boolean] ensure_fetch <true> if true, it will grab the content from the repository if is not already loaded
132
133
  # @return [String]
133
134
  def local_or_remote_content(ensure_fetch = true)
134
- return @content if new?
135
+ return @content if new?
135
136
 
136
137
  @content ||= ensure_fetch ? datastream_content : @datastream_content
137
138
 
@@ -169,16 +170,17 @@ module Rubydora
169
170
  end
170
171
 
171
172
  # Set the content of the datastream
172
- # @param [String or IO]
173
+ # @param [String or IO]
173
174
  # @return [String or IO]
174
- def content= new_content
175
+ def content=(new_content)
175
176
  raise "Can't change values on older versions" if @asOfDateTime
176
- @content = new_content
177
+ @content = new_content
177
178
  end
178
179
 
179
180
  def content_changed?
180
181
  return false if ['E','R'].include? controlGroup
181
- return true if new? and !local_or_remote_content(false).blank? # new datastreams must have content
182
+ return false unless content_loaded?
183
+ return true if new? && !local_or_remote_content(false).blank? # new datastreams must have content
182
184
 
183
185
  if controlGroup == "X"
184
186
  if self.eager_load_datastream_content
@@ -208,12 +210,16 @@ module Rubydora
208
210
  return dsLocation.present? if ['E','R'].include? controlGroup
209
211
 
210
212
  # type M has content if dsLocation is not empty
211
- return true if controlGroup == 'M' and dsLocation.present?
213
+ return true if controlGroup == 'M' && dsLocation.present?
212
214
 
213
215
  # if we've set content, then we have content
214
216
  behaves_like_io?(@content) || content.present?
215
217
  end
216
218
 
219
+ def content_loaded?
220
+ !@content.nil?
221
+ end
222
+
217
223
  def empty?
218
224
  !has_content?
219
225
  end
@@ -222,9 +228,9 @@ module Rubydora
222
228
  # it doesn't require holding the entire content in memory. If you specify the from and length
223
229
  # parameters it simulates a range request. Unfortunatly Fedora 3 doesn't have range requests,
224
230
  # so this method needs to download the whole thing and just seek to the part you care about.
225
- #
226
- # @param [Integer] from (bytes) the starting point you want to return.
227
- #
231
+ #
232
+ # @param [Integer] from (bytes) the starting point you want to return.
233
+ #
228
234
  def stream (from = 0, length = nil)
229
235
  counter = 0
230
236
  Enumerator.new do |blk|
@@ -246,7 +252,7 @@ module Rubydora
246
252
  # At the end of what we beginning of what we need. Write the end of what was read.
247
253
  offset = from - last_counter
248
254
  blk << chunk[offset..-1]
249
- else
255
+ else
250
256
  # In the middle. We need all of this
251
257
  blk << chunk
252
258
  end
@@ -259,18 +265,18 @@ module Rubydora
259
265
  # Retrieve the datastream profile as a hash (and cache it)
260
266
  # @param opts [Hash] :validateChecksum if you want fedora to validate the checksum
261
267
  # @return [Hash] see Fedora #getDatastream documentation for keys
262
- def profile opts= {}
268
+ def profile(opts= {})
263
269
  if @profile && !(opts[:validateChecksum] && !@profile.has_key?('dsChecksumValid'))
264
270
  ## Force a recheck of the profile if they've passed :validateChecksum and we don't have dsChecksumValid
265
271
  return @profile
266
272
  end
267
-
273
+
268
274
  return @profile = {} unless digital_object.respond_to? :repository
269
-
275
+
270
276
  @profile = repository.datastream_profile(pid, dsid, opts[:validateChecksum], asOfDateTime)
271
277
  end
272
278
 
273
- def profile= profile_hash
279
+ def profile=(profile_hash)
274
280
  raise ArgumentError, "Must pass a profile, you passed #{profile_hash.class}" unless profile_hash.kind_of? Hash
275
281
  @profile = profile_hash
276
282
  end
@@ -285,7 +291,7 @@ module Rubydora
285
291
  def current_version?
286
292
  return true if new?
287
293
  vers = versions
288
- return vers.empty? || dsVersionID == vers.first.dsVersionID
294
+ vers.empty? || dsVersionID == vers.first.dsVersionID
289
295
  end
290
296
 
291
297
  # Add datastream to Fedora
@@ -307,7 +313,7 @@ module Rubydora
307
313
  run_callbacks :save do
308
314
  raise RubydoraError.new("Unable to save #{self.inspect} without content") unless has_content?
309
315
  if new?
310
- create
316
+ create
311
317
  else
312
318
  p = repository.modify_datastream(to_api_params.merge({ :pid => pid, :dsid => dsid })) || {}
313
319
  reset_profile_attributes
@@ -353,15 +359,13 @@ module Rubydora
353
359
  controlGroup == 'X'
354
360
  end
355
361
 
356
-
357
-
358
362
  protected
359
- # datastream parameters
363
+ # datastream parameters
360
364
  # @return [Hash]
361
365
  def to_api_params
362
366
  h = default_api_params
363
367
  valid_changed_attributes = changes.keys.map { |x| x.to_sym }.select { |x| DS_ATTRIBUTES.key? x }
364
- valid_changed_attributes += [:content] if content_changed? and !valid_changed_attributes.include? :content
368
+ valid_changed_attributes += [:content] if content_changed? && !valid_changed_attributes.include?(:content)
365
369
  ## if we don't provide a mimeType, application/octet-stream will be used instead
366
370
  (valid_changed_attributes | [:mimeType]).each do |attribute|
367
371
  h[attribute.to_sym] = send(attribute) unless send(attribute).nil?
@@ -392,7 +396,7 @@ module Rubydora
392
396
  digital_object.repository
393
397
  end
394
398
 
395
- def asOfDateTime= val
399
+ def asOfDateTime=(val)
396
400
  @asOfDateTime = val
397
401
  end
398
402
 
@@ -400,7 +404,7 @@ module Rubydora
400
404
  raise "Can't change values on older versions" if @asOfDateTime
401
405
  end
402
406
 
403
- def validate_dsLocation! val
407
+ def validate_dsLocation!(val)
404
408
  URI.parse(val) unless val.nil?
405
409
  end
406
410
 
@@ -411,7 +415,7 @@ module Rubydora
411
415
  obj.is_a?(IO) || (defined?(Rack) && obj.is_a?(Rack::Test::UploadedFile))
412
416
  end
413
417
 
414
- def attribute_will_change! *args
418
+ def attribute_will_change!(*args)
415
419
  check_if_read_only
416
420
  super
417
421
  end