rubydora 1.6.3 → 1.7.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
  SHA1:
3
- metadata.gz: 3446c99b699e41f3fb8e24b636313a510c7b77cc
4
- data.tar.gz: a0b85f13192eeb58e95423ce84eb5956285f1879
3
+ metadata.gz: be337fe4d014e05130587d975c1388050ab192e6
4
+ data.tar.gz: 6eca752e25d923e8832c0b24cb2e724a90b932fc
5
5
  SHA512:
6
- metadata.gz: 7b280b7c624ba9037034ee314a2a03e6e91bc36c8690a89dd3a74b43e58a7239afe52a05657f7ee41aa54f8cf9decc1426e9e8335f285baffa0a83046fce8937
7
- data.tar.gz: 4b96fe24d6ec7878662bad578a9a4171d27af9e8bf245fe03a1f5b1b6dfe1b25d7156d8a9f695fe2575ed562671e7bb22c84a22eae6c63cc4b4c02b6a4cbe2de
6
+ metadata.gz: 48229e6eeee8bb507b7914aee56244ba2bf179c75bcb7f61b9c1711860c27cd9cf27ac0f7bff6ced99221c021868f05dd54278a15da897801964abe26857ee0f
7
+ data.tar.gz: 87b6f2cc39e89dd69c39c15f6b5003ae5c99dee2cc04159ab06ff839117289bba4ce70a42c7692c9214624f8a9a27d6d1c9381d9d5009cf0ae9e941a932214b5
data/.mailmap ADDED
@@ -0,0 +1,8 @@
1
+ Mark Bussey <mark@curationexperts.com> mark-dce <mark@curationexperts.com>
2
+ Andrew Myers <andrew_myers@wgbh.org> afred <afredmyers@gmail.com>
3
+ Chris Beer <chris@cbeer.info> <chris@cbeer.info>
4
+ Chris Beer <chris@cbeer.info> <cabeer@stanford.edu>
5
+ Chris Beer <chris@cbeer.info> <chris_beer@wgbh.org>
6
+ Justin Coyne <justin@curationexperts.com> <justin.coyne@yourmediashelf.com>
7
+ Justin Coyne <justin@curationexperts.com> <digger250@gmail.com>
8
+ David Chandek-Stark <dchandekstark@gmail.com>
data/.travis.yml CHANGED
@@ -1,7 +1,11 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "1.9.3"
4
- - "2.0.0"
3
+ - 1.9.3
4
+ - 2.0.0
5
+
6
+ gemfile:
7
+ - gemfiles/gemfile.rails3
8
+ - gemfiles/gemfile.rails4
5
9
 
6
10
  notifications:
7
11
  irc: "irc.freenode.org#projecthydra"
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,113 @@
1
+ # How to Contribute
2
+
3
+ We want your help to make Project Hydra great.
4
+ There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things.
5
+
6
+ ## Hydra Project Intellectual Property Licensing and Ownership
7
+
8
+ All code contributors must have an Individual Contributor License Agreement (iCLA) on file with the Hydra Project Steering Group.
9
+ If the contributor works for an institution, the institution must have a Corporate Contributor License Agreement (cCLA) on file.
10
+
11
+ https://wiki.duraspace.org/display/hydra/Hydra+Project+Intellectual+Property+Licensing+and+Ownership
12
+
13
+ You should also add yourself to the `CONTRIBUTORS.md` file in the root of the project.
14
+
15
+ ## Contribution Tasks
16
+
17
+ * Reporting Issues
18
+ * Making Changes
19
+ * Submitting Changes
20
+ * Merging Changes
21
+
22
+ ### Reporting Issues
23
+
24
+ * Make sure you have a [GitHub account](https://github.com/signup/free)
25
+ * Submit a [Github issue](./issues) by:
26
+ * Clearly describing the issue
27
+ * Provide a descriptive summary
28
+ * Explain the expected behavior
29
+ * Explain the actual behavior
30
+ * Provide steps to reproduce the actual behavior
31
+
32
+ ### Making Changes
33
+
34
+ * Fork the repository on GitHub
35
+ * Create a topic branch from where you want to base your work.
36
+ * This is usually the master branch.
37
+ * To quickly create a topic branch based on master; `git branch fix/master/my_contribution master`
38
+ * Then checkout the new branch with `git checkout fix/master/my_contribution`.
39
+ * Please avoid working directly on the `master` branch.
40
+ * You may find the [hub suite of commands](https://github.com/defunkt/hub) helpful
41
+ * Make commits of logical units.
42
+ * Your commit should include a high level description of your work in HISTORY.textile
43
+ * Check for unnecessary whitespace with `git diff --check` before committing.
44
+ * Make sure your commit messages are [well formed](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
45
+ * If you created an issue, you can close it by including "Closes #issue" in your commit message. See [Github's blog post for more details](https://github.com/blog/1386-closing-issues-via-commit-messages)
46
+
47
+ ```
48
+ Present tense short summary (50 characters or less)
49
+
50
+ More detailed description, if necessary. It should be wrapped to 72
51
+ characters. Try to be as descriptive as you can, even if you think that
52
+ the commit content is obvious, it may not be obvious to others. You
53
+ should add such description also if it's already present in bug tracker,
54
+ it should not be necessary to visit a webpage to check the history.
55
+
56
+ Include Closes #<issue-number> when relavent.
57
+
58
+ Description can have multiple paragraphs and you can use code examples
59
+ inside, just indent it with 4 spaces:
60
+
61
+ class PostsController
62
+ def index
63
+ respond_with Post.limit(10)
64
+ end
65
+ end
66
+
67
+ You can also add bullet points:
68
+
69
+ - you can use dashes or asterisks
70
+
71
+ - also, try to indent next line of a point for readability, if it's too
72
+ long to fit in 72 characters
73
+ ```
74
+
75
+ * Make sure you have added the necessary tests for your changes.
76
+ * Run _all_ the tests to assure nothing else was accidentally broken.
77
+ * When you are ready to submit a pull request
78
+
79
+ ### Submitting Changes
80
+
81
+ [Detailed Walkthrough of One Pull Request per Commit](http://ndlib.github.io/practices/one-commit-per-pull-request/)
82
+
83
+ * Read the article ["Using Pull Requests"](https://help.github.com/articles/using-pull-requests) on GitHub.
84
+ * Make sure your branch is up to date with its parent branch (i.e. master)
85
+ * `git checkout master`
86
+ * `git pull --rebase`
87
+ * `git checkout <your-branch>`
88
+ * `git rebase master`
89
+ * It is likely a good idea to run your tests again.
90
+ * Squash the commits for your branch into one commit
91
+ * `git rebase --interactive HEAD~<number-of-commits>` ([See Github help](https://help.github.com/articles/interactive-rebase))
92
+ * To determine the number of commits on your branch: `git log master..<your-branch> --oneline | wc -l`
93
+ * Squashing your branch's changes into one commit is "good form" and helps the person merging your request to see everything that is going on.
94
+ * Push your changes to a topic branch in your fork of the repository.
95
+ * Submit a pull request from your fork to the project.
96
+
97
+ ### Merging Changes
98
+
99
+ * It is considered "poor from" to merge your own request.
100
+ * Please take the time to review the changes and get a sense of what is being changed. Things to consider:
101
+ * Does the commit message explain what is going on?
102
+ * Does the code changes have tests? _Not all changes need new tests, some changes are refactorings_
103
+ * Does the commit contain more than it should? Are two separate concerns being addressed in one commit?
104
+ * Did the Travis tests complete successfully?
105
+ * If you are uncertain, bring other contributors into the conversation by creating a comment that includes their @username.
106
+ * If you like the pull request, but want others to chime in, create a +1 comment and tag a user.
107
+
108
+ # Additional Resources
109
+
110
+ * [General GitHub documentation](http://help.github.com/)
111
+ * [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
112
+ * [Pro Git](http://git-scm.com/book) is both a free and excellent book about Git.
113
+ * [A Git Config for Contributing](http://ndlib.github.io/practices/my-typical-per-project-git-config/)
data/Gemfile CHANGED
@@ -2,10 +2,6 @@ source "http://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'activemodel', ">= 3.1.1"
6
- gem 'backports'
7
-
8
- gem 'rcov', :platform => :mri_18
9
5
  gem 'simplecov', :platform => :mri_19
10
6
  gem 'simplecov-rcov', :platform => :mri_19
11
7
  gem 'jruby-openssl', :platform => :jruby
data/LICENSE.txt CHANGED
@@ -1,20 +1,19 @@
1
- Copyright (c) 2010 Chris Beer
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ ##########################################################################
2
+ # rubydora
3
+ #
4
+ # Copyright © 2011 Chris Beer, WGBH
5
+ # Copyright © 2012 Chris Beer, WGBH, MediaShelf
6
+ # Copyright © 2013 Data Curation Experts, Stanford University
7
+ # Additional copyright may be held by others, as reflected in the commit history.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
data/Notices.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Chris Beer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc CHANGED
@@ -1,5 +1,6 @@
1
1
  = rubydora
2
2
  {<img src="https://travis-ci.org/projecthydra/rubydora.png?branch=master" alt="Build Status" />}[https://travis-ci.org/projecthydra/rubydora]
3
+ {<img src="https://badge.fury.io/rb/rubydora.png" alt="Gem Version" />}[http://badge.fury.io/rb/rubydora]
3
4
 
4
5
  Rubydora is a low-level Fedora Commons REST API consumer, providing direct access to REST API methods, as well as a primitive ruby abstraction.
5
6
 
data/Rakefile CHANGED
@@ -49,7 +49,7 @@ task :ci => 'jetty:clean' do
49
49
  :jetty_port => ENV['TEST_JETTY_PORT'] || 8983,
50
50
  :solr_home => File.expand_path(File.dirname(__FILE__) + '/jetty/solr'),
51
51
  :fedora_home => File.expand_path(File.dirname(__FILE__) + '/jetty/fedora/default'),
52
- :startup_wait => 60,
52
+ :startup_wait => 90,
53
53
  :java_opts => ['-Xmx256m', '-XX:MaxPermSize=128m']
54
54
  }
55
55
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.6.3
1
+ 1.7.0
@@ -0,0 +1,11 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec :path=>"../"
4
+
5
+ gem 'activemodel', '~> 3.2.13'
6
+
7
+ group :development, :test do
8
+ gem 'rcov', :platform => :mri_18
9
+ gem 'simplecov', :platform => :mri_19
10
+ gem 'simplecov-rcov', :platform => :mri_19
11
+ end
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec :path=>"../"
4
+
5
+ gem 'activemodel', '~> 4.0.0'
6
+
7
+ group :development, :test do
8
+ gem 'simplecov', :platform => :mri_19
9
+ gem 'simplecov-rcov', :platform => :mri_19
10
+ end
@@ -1,9 +1,9 @@
1
1
  module Rubydora::AuditTrail
2
2
 
3
- def audit_trail
4
- @audit_trail ||= FedoraAuditTrail.new(self)
3
+ def audit_trail(pid)
4
+ FedoraAuditTrail.new(object_xml(pid: pid))
5
5
  end
6
-
6
+
7
7
  private
8
8
 
9
9
  AT_NS = {'audit' => 'info:fedora/fedora-system:def/audit#'}
@@ -11,8 +11,8 @@ module Rubydora::AuditTrail
11
11
  AT_XPATH = '/foxml:digitalObject/foxml:datastream[@ID = "AUDIT"]/descendant::audit:auditTrail'
12
12
 
13
13
  class FedoraAuditTrail
14
- def initialize(object)
15
- @ng_xml = Nokogiri::XML(object.repository.object_xml(:pid => object.pid)).xpath(AT_XPATH, FOXML_NS.merge(AT_NS))
14
+ def initialize(object_xml)
15
+ @ng_xml = Nokogiri::XML(object_xml).xpath(AT_XPATH, FOXML_NS.merge(AT_NS))
16
16
  end
17
17
  def records
18
18
  if !@records
@@ -75,7 +75,7 @@ module Rubydora
75
75
  return @asOfDateTime
76
76
  end
77
77
 
78
- return self.class.new(@digital_object, @dsid, @options.merge(:asOfDateTime => asOfDateTime))
78
+ return self.class.new(@digital_object, dsid, @options.merge(:asOfDateTime => asOfDateTime))
79
79
  end
80
80
 
81
81
  def self.default_attributes
@@ -100,7 +100,7 @@ module Rubydora
100
100
  # @param [String] Datastream ID
101
101
  # @param [Hash] default attribute values (used esp. for creating new datastreams)
102
102
  def initialize digital_object, dsid, options = {}, default_instance_attributes = {}
103
- _run_initialize_callbacks do
103
+ run_callbacks :initialize do
104
104
  @digital_object = digital_object
105
105
  @dsid = dsid
106
106
  @options = options
@@ -119,7 +119,7 @@ module Rubydora
119
119
  # Does this datastream already exist?
120
120
  # @return [Boolean]
121
121
  def new?
122
- digital_object.nil? || digital_object.new? || profile_xml.blank?
122
+ digital_object.nil? || digital_object.new_record? || profile.empty?
123
123
  end
124
124
 
125
125
  # This method is overridden in ActiveFedora, so we didn't
@@ -260,62 +260,25 @@ module Rubydora
260
260
 
261
261
  return @profile = {} unless digital_object.respond_to? :repository
262
262
 
263
- @profile = begin
264
- xml = profile_xml(opts)
265
-
266
- (self.profile_xml_to_hash(xml) unless xml.blank?) || {}
267
- end
263
+ @profile = repository.datastream_profile(pid, dsid, opts[:validateChecksum], asOfDateTime)
268
264
  end
269
265
 
270
- def profile_xml opts = {}
271
- @profile_xml = nil unless opts.empty?
272
-
273
- @profile_xml ||= begin
274
-
275
- options = { :pid => pid, :dsid => dsid }
276
- options.merge!(opts)
277
- options[:asOfDateTime] = asOfDateTime if asOfDateTime
278
- options[:validateChecksum] = true if repository.config[:validateChecksum]
279
- repository.datastream(options)
280
- rescue RestClient::Unauthorized => e
281
- raise e
282
- rescue RestClient::ResourceNotFound
283
- # the datastream is new
284
- ''
285
- end
266
+ def profile= profile_hash
267
+ raise ArgumentError, "Must pass a profile, you passed #{profile_hash.class}" unless profile_hash.kind_of? Hash
268
+ @profile = profile_hash
286
269
  end
287
270
 
288
- def profile= profile_xml
289
- @profile = self.profile_xml_to_hash(profile_xml)
290
- end
291
-
292
- def profile_xml_to_hash profile_xml
293
- profile_xml.gsub! '<datastreamProfile', '<datastreamProfile xmlns="http://www.fedora.info/definitions/1/0/management/"' unless profile_xml =~ /xmlns=/
294
- doc = Nokogiri::XML(profile_xml)
295
- h = doc.xpath('/management:datastreamProfile/*', {'management' => "http://www.fedora.info/definitions/1/0/management/"} ).inject({}) do |sum, node|
296
- sum[node.name] ||= []
297
- sum[node.name] << node.text
298
- sum
299
- end.reject { |key, values| values.empty? }
300
- h.select { |key, values| values.length == 1 }.each do |key, values|
301
- h[key] = values.reject { |x| x.empty? }.first
271
+ def versions
272
+ versions = repository.versions_for_datastream(pid, dsid)
273
+ versions.map do |asOfDateTime, profile|
274
+ self.class.new(@digital_object, dsid, asOfDateTime: asOfDateTime, profile: profile)
302
275
  end
303
-
304
- h['dsSize'] &&= h['dsSize'].to_i rescue h['dsSize']
305
- h['dsCreateDate'] &&= Time.parse(h['dsCreateDate']) rescue h['dsCreateDate']
306
- h['dsChecksumValid'] &&= h['dsChecksumValid'] == 'true'
307
- h['dsVersionable'] &&= h['dsVersionable'] == 'true'
308
- h
309
276
  end
310
277
 
311
- def versions
312
- versions_xml = repository.datastream_versions(:pid => pid, :dsid => dsid)
313
- return [] if versions_xml.nil?
314
- versions_xml.gsub! '<datastreamProfile', '<datastreamProfile xmlns="http://www.fedora.info/definitions/1/0/management/"' unless versions_xml =~ /xmlns=/
315
- doc = Nokogiri::XML(versions_xml)
316
- doc.xpath('//management:datastreamProfile', {'management' => "http://www.fedora.info/definitions/1/0/management/"} ).map do |ds|
317
- self.class.new @digital_object, @dsid, :profile => ds.to_s, :asOfDateTime => ds.xpath('management:dsCreateDate', 'management' => "http://www.fedora.info/definitions/1/0/management/").text
318
- end
278
+ def current_version?
279
+ return true if new?
280
+ vers = versions
281
+ return vers.empty? || dsVersionID == vers.first.dsVersionID
319
282
  end
320
283
 
321
284
  # Add datastream to Fedora
@@ -406,7 +369,6 @@ module Rubydora
406
369
  # @return [Hash]
407
370
  def reset_profile_attributes
408
371
  @profile = nil
409
- @profile_xml = nil
410
372
  @datastream_content = nil
411
373
  @content = nil
412
374
  @changed_attributes = {}
@@ -14,14 +14,13 @@ module Rubydora
14
14
  include ActiveModel::Dirty
15
15
  include Rubydora::ModelsMixin
16
16
  include Rubydora::RelationshipsMixin
17
- include Rubydora::AuditTrail
18
17
 
19
18
  extend Deprecation
20
19
 
21
20
  attr_reader :pid
22
21
 
23
22
  # mapping object parameters to profile elements
24
- OBJ_ATTRIBUTES = {:state => :objState, :ownerId => :objOwnerId, :label => :objLabel, :logMessage => nil, :lastModifiedDate => :objLastModDate }
23
+ OBJ_ATTRIBUTES = {:state => :objState, :ownerId => :objOwnerId, :label => :objLabel, :logMessage => nil, :lastModifiedDate => :objLastModDate, :createdDate => :objCreateDate }
25
24
 
26
25
  OBJ_DEFAULT_ATTRIBUTES = { }
27
26
 
@@ -40,6 +39,12 @@ module Rubydora
40
39
  RUBY
41
40
  end
42
41
 
42
+ def state= val
43
+ raise ArgumentError, "Allowed values for state are 'I', 'A' and 'D'. You provided '#{val}'" unless ['I', 'A', 'D'].include?(val)
44
+ state_will_change! unless val == state
45
+ @state = val
46
+ end
47
+
43
48
  # Find an existing Fedora object
44
49
  #
45
50
  # @param [String] pid
@@ -83,7 +88,7 @@ module Rubydora
83
88
  # @param [Rubydora::Repository] repository context
84
89
  # @param [Hash] options default attribute values (used esp. for creating new datastreams
85
90
  def initialize pid, repository = nil, options = {}
86
- _run_initialize_callbacks do
91
+ run_callbacks :initialize do
87
92
  self.pid = pid
88
93
  @repository = repository
89
94
  @options = options
@@ -94,6 +99,11 @@ module Rubydora
94
99
  end
95
100
  end
96
101
 
102
+ def audit_trail
103
+ @audit_trail ||= repository.audit_trail(self.pid)
104
+ end
105
+
106
+
97
107
  ##
98
108
  # Return a full uri pid (for use in relations, etc
99
109
  def uri
@@ -104,9 +114,10 @@ module Rubydora
104
114
 
105
115
  # Does this object already exist?
106
116
  # @return [Boolean]
107
- def new?
108
- self.profile_xml.blank?
117
+ def new_record?
118
+ self.profile.empty?
109
119
  end
120
+ alias :new? :new_record?
110
121
 
111
122
  def asOfDateTime asOfDateTime = nil
112
123
  if asOfDateTime == nil
@@ -123,49 +134,15 @@ module Rubydora
123
134
  # Retrieve the object profile as a hash (and cache it)
124
135
  # @return [Hash] see Fedora #getObject documentation for keys
125
136
  def profile
126
- return {} if profile_xml.nil?
127
-
128
137
  @profile ||= begin
129
- profile_xml.gsub! '<objectProfile', '<objectProfile xmlns="http://www.fedora.info/definitions/1/0/access/"' unless profile_xml =~ /xmlns=/
130
- doc = Nokogiri::XML(profile_xml)
131
- h = doc.xpath('/access:objectProfile/*', {'access' => "http://www.fedora.info/definitions/1/0/access/"} ).inject({}) do |sum, node|
132
- sum[node.name] ||= []
133
- sum[node.name] << node.text
134
-
135
- if node.name == "objModels"
136
- sum[node.name] = node.xpath('access:model', {'access' => "http://www.fedora.info/definitions/1/0/access/"}).map { |x| x.text }
137
- end
138
-
139
- sum
140
- end.reject { |key, values| values.empty? }
141
-
142
- h.select { |key, values| values.length == 1 }.each do |key, values|
143
- next if key == "objModels"
144
- h[key] = values.reject { |x| x.empty? }.first
145
- end
146
138
  @new = false
147
-
148
- h
149
-
139
+ repository.object_profile(pid, asOfDateTime)
150
140
  end.freeze
151
141
  end
152
142
 
153
- def profile_xml
154
- @profile_xml ||= begin
155
- options = { :pid => pid }
156
- options[:asOfDateTime] = asOfDateTime if asOfDateTime
157
- repository.object(options)
158
- rescue RestClient::ResourceNotFound => e
159
- ''
160
- end
161
- end
162
-
163
143
  def versions
164
- versions_xml = repository.object_versions(:pid => pid)
165
- versions_xml.gsub! '<fedoraObjectHistory', '<fedoraObjectHistory xmlns="http://www.fedora.info/definitions/1/0/access/"' unless versions_xml =~ /xmlns=/
166
- doc = Nokogiri::XML(versions_xml)
167
- doc.xpath('//access:objectChangeDate', {'access' => 'http://www.fedora.info/definitions/1/0/access/' } ).map do |changeDate|
168
- self.class.new pid, repository, :asOfDateTime => changeDate.text
144
+ repository.versions_for_object(pid).map do |changeDate|
145
+ self.class.new pid, repository, :asOfDateTime => changeDate
169
146
  end
170
147
  end
171
148
 
@@ -212,7 +189,6 @@ module Rubydora
212
189
  if self.new?
213
190
  self.pid = repository.ingest to_api_params.merge(:pid => pid)
214
191
  @profile = nil #will cause a reload with updated data
215
- @profile_xml = nil
216
192
  else
217
193
  p = to_api_params
218
194
  repository.modify_object p.merge(:pid => pid) unless p.empty?
@@ -231,7 +207,6 @@ module Rubydora
231
207
  run_callbacks :destroy do
232
208
  @datastreams = nil
233
209
  @profile = nil
234
- @profile_xml = nil
235
210
  @pid = nil
236
211
  nil
237
212
  end
@@ -0,0 +1,89 @@
1
+ module Rubydora
2
+ # This class abstracts away all of the API details including XML parsing
3
+ # This allows the driver (Fc3Service) to be swapped out without having to modify
4
+ # the ORM layer (e.g. Datastream, DigitalObject, Repository)
5
+ class Fc3Service
6
+ include RestApiClient
7
+ include Rubydora::AuditTrail
8
+
9
+ attr_reader :config
10
+ def initialize(config)
11
+ @config = config
12
+ end
13
+
14
+ # Reserve a new pid for the object
15
+ # @params [Hash] options
16
+ # @option options [String] :namespace the namespece for the pid
17
+ def mint(options={})
18
+ d = Nokogiri::XML(next_pid(options))
19
+ d.xpath('//fedora:pid', 'fedora' => 'http://www.fedora.info/definitions/1/0/management/').text
20
+ end
21
+
22
+
23
+ # repository profile (from API-A-LITE data)
24
+ # @return [Hash]
25
+ def repository_profile
26
+ begin
27
+ profile_xml = self.describe.strip
28
+ h = ProfileParser.parse_repository_profile(profile_xml)
29
+ h.select { |key, value| value.length == 1 }.each do |key, value|
30
+ next if key == "objModels"
31
+ h[key] = value.first
32
+ end
33
+
34
+ h
35
+ rescue
36
+ nil
37
+ end
38
+ end
39
+
40
+ def object_profile(pid, asOfDateTime = nil)
41
+ options = {pid: pid}
42
+ options[:asOfDateTime] = asOfDateTime if asOfDateTime
43
+ begin
44
+ xml = object(options)
45
+ ProfileParser.parse_object_profile(xml)
46
+ rescue RestClient::ResourceNotFound
47
+ {}
48
+ end
49
+ end
50
+
51
+ def datastream_profile(pid, dsid, validateChecksum, asOfDateTime = nil)
52
+ xml = begin
53
+ options = { pid: pid, dsid: dsid}
54
+ options[:validateChecksum] = validateChecksum if validateChecksum
55
+ options[:asOfDateTime] = asOfDateTime if asOfDateTime
56
+ options[:validateChecksum] = true if config[:validateChecksum]
57
+ datastream(options)
58
+ rescue RestClient::Unauthorized => e
59
+ raise e
60
+ rescue RestClient::ResourceNotFound
61
+ # the datastream is new
62
+ ''
63
+ end
64
+
65
+ ProfileParser.parse_datastream_profile(xml)
66
+ end
67
+
68
+ def versions_for_datastream(pid, dsid)
69
+ versions_xml = datastream_versions(:pid => pid, :dsid => dsid)
70
+ return {} if versions_xml.nil?
71
+ versions_xml.gsub! '<datastreamProfile', '<datastreamProfile xmlns="http://www.fedora.info/definitions/1/0/management/"' unless versions_xml =~ /xmlns=/
72
+ doc = Nokogiri::XML(versions_xml)
73
+ versions = {}
74
+ doc.xpath('//management:datastreamProfile', {'management' => "http://www.fedora.info/definitions/1/0/management/"} ).each do |ds|
75
+ key = ds.xpath('management:dsCreateDate', 'management' => "http://www.fedora.info/definitions/1/0/management/").text
76
+ versions[key] = ProfileParser.parse_datastream_profile(ds.to_s)
77
+ end
78
+ versions
79
+ end
80
+
81
+ def versions_for_object(pid)
82
+ versions_xml = object_versions(:pid => pid)
83
+ versions_xml.gsub! '<fedoraObjectHistory', '<fedoraObjectHistory xmlns="http://www.fedora.info/definitions/1/0/access/"' unless versions_xml =~ /xmlns=/
84
+ doc = Nokogiri::XML(versions_xml)
85
+ doc.xpath('//access:objectChangeDate', {'access' => 'http://www.fedora.info/definitions/1/0/access/' } ).map(&:text)
86
+ end
87
+
88
+ end
89
+ end