rubydora 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.4
@@ -42,6 +42,11 @@ module Rubydora
42
42
  call_after_initialize
43
43
  end
44
44
 
45
+ # Helper method to get digital object pid
46
+ def pid
47
+ digital_object.pid
48
+ end
49
+
45
50
  # Does this datastream already exist?
46
51
  # @return [Boolean]
47
52
  def new?
@@ -51,10 +56,19 @@ module Rubydora
51
56
  # Retrieve the content of the datastream (and cache it)
52
57
  # @return [String]
53
58
  def content
54
- @content ||= repository.datastream_dissemination :pid => digital_object.pid, :dsid => dsid
59
+ @content ||= repository.datastream_dissemination :pid => pid, :dsid => dsid
55
60
  end
56
61
  alias_method :read, :content
57
62
 
63
+ # Get the URL for the datastream content
64
+ # @return [String]
65
+ def url
66
+ repository.datastream_url(pid, dsid) + "/content"
67
+ end
68
+
69
+ # Set the content of the datastream
70
+ # @param [String or IO]
71
+ # @return [String or IO]
58
72
  def content= content
59
73
  @file = content
60
74
  @content = content.dup
@@ -66,7 +80,7 @@ module Rubydora
66
80
  # @return [Hash] see Fedora #getDatastream documentation for keys
67
81
  def profile
68
82
  @profile ||= begin
69
- profile_xml = repository.datastream(:pid => digital_object.pid, :dsid => dsid)
83
+ profile_xml = repository.datastream(:pid => pid, :dsid => dsid)
70
84
  profile_xml.gsub! '<datastreamProfile', '<datastreamProfile xmlns="http://www.fedora.info/definitions/1/0/access/"' unless profile_xml =~ /xmlns=/
71
85
  doc = Nokogiri::XML(profile_xml)
72
86
  h = doc.xpath('/access:datastreamProfile/*', {'access' => "http://www.fedora.info/definitions/1/0/access/"} ).inject({}) do |sum, node|
@@ -93,7 +107,7 @@ module Rubydora
93
107
  # Add datastream to Fedora
94
108
  # @return [Rubydora::Datastream]
95
109
  def create
96
- repository.add_datastream to_api_params.merge({ :pid => digital_object.pid, :dsid => dsid })
110
+ repository.add_datastream to_api_params.merge({ :pid => pid, :dsid => dsid })
97
111
  reset_profile_attributes
98
112
  Datastream.new(digital_object, dsid)
99
113
  end
@@ -102,7 +116,7 @@ module Rubydora
102
116
  # @return [Rubydora::Datastream]
103
117
  def save
104
118
  return create if new?
105
- repository.modify_datastream to_api_params.merge({ :pid => digital_object.pid, :dsid => dsid })
119
+ repository.modify_datastream to_api_params.merge({ :pid => pid, :dsid => dsid })
106
120
  reset_profile_attributes
107
121
  Datastream.new(digital_object, dsid)
108
122
  end
@@ -110,7 +124,7 @@ module Rubydora
110
124
  # Purge the datastream from Fedora
111
125
  # @return [Rubydora::Datastream] `self`
112
126
  def delete
113
- repository.purge_datastream(:pid => digital_object.pid, :dsid => dsid) unless self.new?
127
+ repository.purge_datastream(:pid => pid, :dsid => dsid) unless self.new?
114
128
  digital_object.datastreams.delete(dsid)
115
129
  reset_profile_attributes
116
130
  self
@@ -125,6 +125,8 @@ module Rubydora
125
125
  h = Hash.new { |h,k| h[k] = Datastream.new self, k }
126
126
  end
127
127
  end
128
+ alias_method :datastream, :datastreams
129
+ alias_method :[], :datastreams
128
130
 
129
131
  # persist the object to Fedora, either as a new object
130
132
  # by modifing the existing object
@@ -0,0 +1,55 @@
1
+ module Rubydora::Ext
2
+ # Rubydora extension to load dynamically load modules into an object based on defined models
3
+ module ModelLoader
4
+ # @param [Hash] args
5
+ # @option args [Class] :base_namespace
6
+ # @option args [Class] :method
7
+ # @option args [Class] :class
8
+ #
9
+ def self.load args = {}
10
+ args[:class] ||= Rubydora::DigitalObject
11
+ args[:method] ||= :models
12
+
13
+ args[:class].extension_parameters[:ModelLoaderMixin] ||= {}
14
+ args[:class].extension_parameters[:ModelLoaderMixin][:namespaces] ||= []
15
+ args[:class].extension_parameters[:ModelLoaderMixin][:namespaces] << args[:base_namespace]
16
+ args[:class].extension_parameters[:ModelLoaderMixin][:method] ||= args[:method]
17
+ args[:class].use_extension(ModelLoaderMixin)
18
+ end
19
+
20
+ module ModelLoaderMixin
21
+ # @param [Class] base
22
+ def self.extended(document)
23
+ self.module_names(document).each do |model|
24
+ document.class.extension_parameters[:ModelLoaderMixin][:namespaces].each do |ns|
25
+ begin
26
+ mod = self.string_to_constant [ns, model].compact.map { |x| x.to_s }.join("/")
27
+ document.send(:extend, mod)
28
+ rescue NameError
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ def self.string_to_constant lower_case_and_underscored_word
35
+ camel_cased_word = lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
36
+
37
+ names = camel_cased_word.split('::')
38
+ names.shift if names.empty? || names.first.empty?
39
+
40
+ constant = Object
41
+ names.each do |name|
42
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
43
+ end
44
+ constant
45
+ end
46
+
47
+ private
48
+ def self.module_names(document)
49
+ arr = document.send(document.class.extension_parameters[:ModelLoaderMixin][:method])
50
+ arr &&= [arr] unless arr.is_a? Array
51
+ arr.map { |x| x.gsub('info:fedora/', '').downcase.gsub(/[^a-z0-9_:]+/, '_').gsub(':', '/').gsub(/_{2,}/, '_').gsub(/^_|_$/, '') }
52
+ end
53
+ end
54
+ end
55
+ end
@@ -63,7 +63,7 @@ module Rubydora::Ext
63
63
  send(method_name, doc)
64
64
  end
65
65
 
66
- doc.reject { |k,v| v.nil? or v.empty? }
66
+ doc.reject { |k,v| v.nil? or (v.respond_to?(:empty?) and v.empty?) }
67
67
  end
68
68
 
69
69
  # add solr document attributes from the object profile
@@ -79,7 +79,7 @@ module Rubydora::Ext
79
79
 
80
80
  # add solr document attributes from the object datastreams
81
81
  # @param [Hash] doc Solr document object (pass-by-reference)
82
- def datstreams_to_solr doc
82
+ def datastreams_to_solr doc
83
83
  datastreams.each do |dsid, ds|
84
84
  doc['disseminates_s'] ||= []
85
85
  doc['disseminates_s'] << [dsid]
@@ -90,8 +90,8 @@ module Rubydora::Ext
90
90
  # add solr document attributes by querying the resource index
91
91
  # @param [Hash] doc Solr document object (pass-by-reference)
92
92
  def relations_to_solr doc
93
- self.repository.sparql("SELECT ? relation ?object FROM <#ri> WHERE {
94
- #{uri} ?relation ?object
93
+ self.repository.sparql("SELECT ?relation ?object FROM <#ri> WHERE {
94
+ <#{uri}> ?relation ?object
95
95
  }").each do |row|
96
96
  solr_field = "ri_#{row['relation'].split('#').last}_s"
97
97
  doc[solr_field] ||= []
@@ -5,6 +5,17 @@ module Rubydora
5
5
  def self.included(base)
6
6
  base.extend ExtendableClassMethods
7
7
 
8
+ base.class_eval do
9
+ # Provide a class-level hash for extension parameters
10
+ # @return [Hash]
11
+ def self.extension_parameters
12
+ ## This variable should NOT be @@, since we're in a class method,
13
+ # it's just @ to be a class variable. Confusing, but it
14
+ # passes the tests this way.
15
+ @extension_parameters ||= {}
16
+ end
17
+ end
18
+
8
19
  base.after_initialize do
9
20
  apply_extensions
10
21
  end
@@ -223,8 +223,6 @@ module Rubydora
223
223
  client[dissemination_url(pid,sdef,method,options)].get
224
224
  end
225
225
 
226
- private
227
-
228
226
  # Generate a REST API compatible URI
229
227
  # @param [String] base base URI
230
228
  # @param [Hash] options to convert to URL parameters
data/lib/rubydora.rb CHANGED
@@ -36,6 +36,13 @@ module Rubydora
36
36
  @repository ||= self.connect(self.default_config)
37
37
  end
38
38
 
39
+ # Set the default Fedora Repository
40
+ # @param [Rubydora::Repository] repository
41
+ # @return Rubydora::Repository
42
+ def self.repository= repository
43
+ @repository = repository
44
+ end
45
+
39
46
  # Default repository connection information
40
47
  # TODO: read ENV variables?
41
48
  # @return Hash
data/rubydora.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rubydora}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Chris Beer"]
12
- s.date = %q{2011-04-18}
12
+ s.date = %q{2011-04-19}
13
13
  s.description = %q{Fedora Commons REST API ruby library : REQUIRES FCREPO 3.4+}
14
14
  s.email = %q{chris@cbeer.info}
15
15
  s.extra_rdoc_files = [
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
28
28
  "lib/rubydora/datastream.rb",
29
29
  "lib/rubydora/digital_object.rb",
30
30
  "lib/rubydora/ext.rb",
31
+ "lib/rubydora/ext/model_loader.rb",
31
32
  "lib/rubydora/ext/solr.rb",
32
33
  "lib/rubydora/extension_parameters.rb",
33
34
  "lib/rubydora/models_mixin.rb",
@@ -39,7 +40,9 @@ Gem::Specification.new do |s|
39
40
  "rubydora.gemspec",
40
41
  "spec/datastream_spec.rb",
41
42
  "spec/digital_object_spec.rb",
43
+ "spec/ext_model_loader_spec.rb",
42
44
  "spec/ext_solr_spec.rb",
45
+ "spec/extension_parameters_spec.rb",
43
46
  "spec/integration_test_spec.rb",
44
47
  "spec/repository_spec.rb",
45
48
  "spec/resource_index_spec.rb",
@@ -54,7 +57,9 @@ Gem::Specification.new do |s|
54
57
  s.test_files = [
55
58
  "spec/datastream_spec.rb",
56
59
  "spec/digital_object_spec.rb",
60
+ "spec/ext_model_loader_spec.rb",
57
61
  "spec/ext_solr_spec.rb",
62
+ "spec/extension_parameters_spec.rb",
58
63
  "spec/integration_test_spec.rb",
59
64
  "spec/repository_spec.rb",
60
65
  "spec/resource_index_spec.rb",
@@ -138,47 +138,6 @@ describe Rubydora::DigitalObject do
138
138
  end
139
139
  end
140
140
 
141
- describe "extensions" do
142
- module FakeExtension
143
- end
144
-
145
- module OtherFakeExtension
146
-
147
- end
148
- before(:each) do
149
- @mock_repository = mock()
150
- end
151
-
152
- after(:each) do
153
- Rubydora::DigitalObject.registered_extensions = []
154
- end
155
-
156
- it "should be extendable" do
157
- Rubydora::DigitalObject.use_extension FakeExtension
158
- @object = Rubydora::DigitalObject.new 'pid', @mock_repository
159
- @object.is_a?(FakeExtension).should == true
160
- end
161
-
162
- it "should be extendable conditionally" do
163
- Rubydora::DigitalObject.use_extension(FakeExtension) { |x| true }
164
- Rubydora::DigitalObject.use_extension(OtherFakeExtension) { |x| false }
165
- @object = Rubydora::DigitalObject.new 'pid', @mock_repository
166
- @object.is_a?(FakeExtension).should == true
167
- @object.is_a?(OtherFakeExtension).should == false
168
- end
169
-
170
- it "should be able to introspect object profiles" do
171
- @mock_repository.should_receive(:object).any_number_of_times.with({:pid => 'pid'}).and_return <<-XML
172
- <objectProfile>
173
- <a>1</a>
174
- </objectProfile>
175
- XML
176
- Rubydora::DigitalObject.use_extension(FakeExtension) { |x| x.profile['a'] == '1' }
177
- @object = Rubydora::DigitalObject.new 'pid', @mock_repository
178
- @object.is_a?(FakeExtension).should == true
179
- end
180
-
181
- end
182
141
 
183
142
  describe "models" do
184
143
  before(:each) do
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'rubydora/ext/model_loader'
3
+
4
+ describe Rubydora::Ext::ModelLoader do
5
+
6
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rubydora::ExtensionParameters do
4
+ describe "extension parameters" do
5
+ class MockExtensionParametersClass
6
+ include Rubydora::Callbacks
7
+ register_callback :after_initialize
8
+ include Rubydora::ExtensionParameters
9
+ end
10
+
11
+ it "should have extension parameters at the class level" do
12
+ MockExtensionParametersClass.extension_parameters[:a] = 1
13
+
14
+ MockExtensionParametersClass.extension_parameters.should == { :a => 1 }
15
+
16
+ end
17
+ end
18
+
19
+ describe "DigitalObject" do
20
+ module FakeExtension
21
+ end
22
+
23
+ module OtherFakeExtension
24
+
25
+ end
26
+ before(:each) do
27
+ @mock_repository = mock()
28
+ end
29
+
30
+ after(:each) do
31
+ Rubydora::DigitalObject.registered_extensions = []
32
+ end
33
+
34
+ it "should be extendable" do
35
+ Rubydora::DigitalObject.use_extension FakeExtension
36
+ @object = Rubydora::DigitalObject.new 'pid', @mock_repository
37
+ @object.is_a?(FakeExtension).should == true
38
+ end
39
+
40
+ it "should be extendable conditionally" do
41
+ Rubydora::DigitalObject.use_extension(FakeExtension) { |x| true }
42
+ Rubydora::DigitalObject.use_extension(OtherFakeExtension) { |x| false }
43
+ @object = Rubydora::DigitalObject.new 'pid', @mock_repository
44
+ @object.is_a?(FakeExtension).should == true
45
+ @object.is_a?(OtherFakeExtension).should == false
46
+ end
47
+
48
+ it "should be able to introspect object profiles" do
49
+ @mock_repository.should_receive(:object).any_number_of_times.with({:pid => 'pid'}).and_return <<-XML
50
+ <objectProfile>
51
+ <a>1</a>
52
+ </objectProfile>
53
+ XML
54
+ Rubydora::DigitalObject.use_extension(FakeExtension) { |x| x.profile['a'] == '1' }
55
+ @object = Rubydora::DigitalObject.new 'pid', @mock_repository
56
+ @object.is_a?(FakeExtension).should == true
57
+ end
58
+ end
59
+ end
60
+
@@ -51,6 +51,11 @@ describe Rubydora::Repository do
51
51
  @repository.should_receive(:profile).and_return nil
52
52
  lambda { @repository.ping }.should raise_error
53
53
  end
54
+
55
+ it "should return true if a connection is established" do
56
+ @repository.should_receive(:profile).and_return true
57
+ @repository.ping.should == true
58
+ end
54
59
  end
55
60
 
56
61
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubydora
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Chris Beer
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-18 00:00:00 -04:00
18
+ date: 2011-04-19 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -183,6 +183,7 @@ files:
183
183
  - lib/rubydora/datastream.rb
184
184
  - lib/rubydora/digital_object.rb
185
185
  - lib/rubydora/ext.rb
186
+ - lib/rubydora/ext/model_loader.rb
186
187
  - lib/rubydora/ext/solr.rb
187
188
  - lib/rubydora/extension_parameters.rb
188
189
  - lib/rubydora/models_mixin.rb
@@ -194,7 +195,9 @@ files:
194
195
  - rubydora.gemspec
195
196
  - spec/datastream_spec.rb
196
197
  - spec/digital_object_spec.rb
198
+ - spec/ext_model_loader_spec.rb
197
199
  - spec/ext_solr_spec.rb
200
+ - spec/extension_parameters_spec.rb
198
201
  - spec/integration_test_spec.rb
199
202
  - spec/repository_spec.rb
200
203
  - spec/resource_index_spec.rb
@@ -237,7 +240,9 @@ summary: Fedora Commons REST API ruby library
237
240
  test_files:
238
241
  - spec/datastream_spec.rb
239
242
  - spec/digital_object_spec.rb
243
+ - spec/ext_model_loader_spec.rb
240
244
  - spec/ext_solr_spec.rb
245
+ - spec/extension_parameters_spec.rb
241
246
  - spec/integration_test_spec.rb
242
247
  - spec/repository_spec.rb
243
248
  - spec/resource_index_spec.rb