active-fedora 2.3.7 → 2.3.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -1
- data/Gemfile.lock +4 -2
- data/History.txt +7 -0
- data/active-fedora.gemspec +2 -1
- data/lib/active_fedora.rb +0 -1
- data/lib/active_fedora/base.rb +32 -15
- data/lib/active_fedora/datastream.rb +1 -0
- data/lib/active_fedora/nokogiri_datastream.rb +18 -17
- data/lib/active_fedora/solr_service.rb +7 -0
- data/lib/active_fedora/version.rb +1 -1
- data/lib/fedora/connection.rb +111 -75
- data/lib/fedora/repository.rb +28 -14
- data/spec/integration/repository_spec.rb +14 -9
- data/spec/spec_helper.rb +2 -0
- data/spec/unit/connection_spec.rb +21 -21
- data/spec/unit/datastream_spec.rb +11 -0
- data/spec/unit/nokogiri_datastream_spec.rb +29 -3
- data/spec/unit/repository_spec.rb +2 -2
- data/spec/unit/solr_service_spec.rb +7 -0
- metadata +36 -20
data/.rvmrc
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
active-fedora (2.3.
|
5
|
-
activeresource
|
4
|
+
active-fedora (2.3.7)
|
5
|
+
activeresource (< 3.0.0)
|
6
6
|
equivalent-xml
|
7
7
|
facets
|
8
8
|
mediashelf-loggable
|
9
9
|
mime-types (>= 1.16)
|
10
10
|
multipart-post (= 1.1.2)
|
11
|
+
net-http-persistent
|
11
12
|
nokogiri
|
12
13
|
om (>= 1.0)
|
13
14
|
solr-ruby (>= 0.0.6)
|
@@ -38,6 +39,7 @@ GEM
|
|
38
39
|
mime-types (1.16)
|
39
40
|
mocha (0.9.12)
|
40
41
|
multipart-post (1.1.2)
|
42
|
+
net-http-persistent (2.1)
|
41
43
|
nokogiri (1.5.0)
|
42
44
|
om (1.4.0)
|
43
45
|
mediashelf-loggable
|
data/History.txt
CHANGED
data/active-fedora.gemspec
CHANGED
@@ -22,10 +22,11 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_dependency('nokogiri')
|
23
23
|
s.add_dependency('om', '>= 1.0')
|
24
24
|
s.add_dependency('solrizer', '>1.0.0')
|
25
|
-
s.add_dependency("activeresource")
|
25
|
+
s.add_dependency("activeresource", "<3.0.0")
|
26
26
|
s.add_dependency("mediashelf-loggable")
|
27
27
|
s.add_dependency("equivalent-xml")
|
28
28
|
s.add_dependency("facets")
|
29
|
+
s.add_dependency("net-http-persistent")
|
29
30
|
s.add_development_dependency("yard")
|
30
31
|
s.add_development_dependency("RedCloth") # for RDoc formatting
|
31
32
|
s.add_development_dependency("rake")
|
data/lib/active_fedora.rb
CHANGED
@@ -68,7 +68,6 @@ module ActiveFedora #:nodoc:
|
|
68
68
|
# 2. If it does not find a solr.yml and the fedora.yml contains a solr url, it will raise an configuration error
|
69
69
|
# 3. If it does not find a solr.yml and the fedora.yml does not contain a solr url, it will look in: +Rails.root+/config, +current working directory+/config, then the solr.yml shipped with gem
|
70
70
|
def self.init( options={} )
|
71
|
-
logger.level = Logger::ERROR if logger.respond_to? :level ###MediaShelf StubLogger doesn't have a level= method
|
72
71
|
# Make config_options into a Hash if nil is passed in as the value
|
73
72
|
options = {} if options.nil?
|
74
73
|
|
data/lib/active_fedora/base.rb
CHANGED
@@ -4,6 +4,7 @@ require 'active_fedora/semantic_node'
|
|
4
4
|
require "solrizer"
|
5
5
|
require 'nokogiri'
|
6
6
|
require "loggable"
|
7
|
+
require 'benchmark'
|
7
8
|
|
8
9
|
SOLR_DOCUMENT_ID = "id" unless (defined?(SOLR_DOCUMENT_ID) && !SOLR_DOCUMENT_ID.nil?)
|
9
10
|
ENABLE_SOLR_UPDATES = true unless defined?(ENABLE_SOLR_UPDATES)
|
@@ -122,8 +123,12 @@ module ActiveFedora
|
|
122
123
|
# Refreshes the object's info from Fedora
|
123
124
|
# Note: Currently just registers any new datastreams that have appeared in fedora
|
124
125
|
def refresh
|
125
|
-
|
126
|
-
|
126
|
+
ms = 1000 * Benchmark.realtime do
|
127
|
+
inner_object.load_attributes_from_fedora
|
128
|
+
@datastreams = datastreams_in_fedora.merge(datastreams_in_memory)
|
129
|
+
end
|
130
|
+
logger.debug "refreshing #{pid} took #{ms} ms"
|
131
|
+
@datastreams
|
127
132
|
end
|
128
133
|
|
129
134
|
#Deletes a Base object, also deletes the info indexed in Solr, and
|
@@ -945,11 +950,17 @@ module ActiveFedora
|
|
945
950
|
def update_index
|
946
951
|
if defined?( Solrizer::Fedora::Solrizer )
|
947
952
|
#logger.info("Trying to solrize pid: #{pid}")
|
948
|
-
|
949
|
-
|
953
|
+
ms = 1000 * Benchmark.realtime do
|
954
|
+
solrizer = Solrizer::Fedora::Solrizer.new
|
955
|
+
solrizer.solrize( self )
|
956
|
+
end
|
957
|
+
logger.debug "solrize for #{pid} took #{ms} ms"
|
950
958
|
else
|
951
959
|
#logger.info("Trying to update solr for pid: #{pid}")
|
952
|
-
|
960
|
+
ms = 1000 * Benchmark.realtime do
|
961
|
+
SolrService.instance.conn.update(self.to_solr)
|
962
|
+
end
|
963
|
+
logger.debug "solr update for #{pid} took #{ms} ms"
|
953
964
|
end
|
954
965
|
end
|
955
966
|
|
@@ -1090,17 +1101,23 @@ module ActiveFedora
|
|
1090
1101
|
|
1091
1102
|
# Pushes the object and all of its new or dirty datastreams into Fedora
|
1092
1103
|
def update
|
1093
|
-
result =
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1104
|
+
result = nil
|
1105
|
+
ms = 1000 * Benchmark.realtime do
|
1106
|
+
result = Fedora::Repository.instance.save(@inner_object)
|
1107
|
+
end
|
1108
|
+
logger.debug "instance save for #{pid} took #{ms} ms"
|
1109
|
+
ms = 1000 * Benchmark.realtime do
|
1110
|
+
datastreams_in_memory.each do |k,ds|
|
1111
|
+
if ds.dirty? || ds.new_object?
|
1112
|
+
if ds.class.included_modules.include?(ActiveFedora::MetadataDatastreamHelper) || ds.instance_of?(ActiveFedora::RelsExtDatastream)
|
1113
|
+
@metadata_is_dirty = true
|
1114
|
+
end
|
1115
|
+
result = ds.save
|
1116
|
+
end
|
1117
|
+
end
|
1118
|
+
refresh
|
1102
1119
|
end
|
1103
|
-
|
1120
|
+
logger.debug "datastream save for #{pid} took #{ms} ms"
|
1104
1121
|
return result
|
1105
1122
|
end
|
1106
1123
|
|
@@ -14,7 +14,8 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
|
|
14
14
|
alias_method(:om_term_values, :term_values) unless method_defined?(:om_term_values)
|
15
15
|
alias_method(:om_update_values, :update_values) unless method_defined?(:om_update_values)
|
16
16
|
|
17
|
-
attr_accessor :
|
17
|
+
attr_accessor :internal_solr_doc
|
18
|
+
attr_reader :ng_xml
|
18
19
|
|
19
20
|
#constructor, calls up to ActiveFedora::Datastream's constructor
|
20
21
|
def initialize(attrs=nil)
|
@@ -43,22 +44,22 @@ class ActiveFedora::NokogiriDatastream < ActiveFedora::Datastream
|
|
43
44
|
Nokogiri::XML::Document.parse("<xml/>")
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
47
|
+
def ng_xml=(new_xml)
|
48
|
+
case new_xml
|
49
|
+
when Nokogiri::XML::Document, Nokogiri::XML::Element, Nokogiri::XML::Node
|
50
|
+
@ng_xml = new_xml
|
51
|
+
when String
|
52
|
+
@ng_xml = Nokogiri::XML::Document.parse(new_xml)
|
53
|
+
else
|
54
|
+
raise TypeError, "You passed a #{new_xml.class} into the ng_xml of the #{self.dsid} datastream. NokogiriDatastream.ng_xml= only accepts Nokogiri::XML::Document, Nokogiri::XML::Element, Nokogiri::XML::Node, or raw XML (String) as inputs."
|
55
|
+
end
|
56
|
+
self.dirty = true
|
57
|
+
end
|
58
|
+
|
59
|
+
def content=(content)
|
60
|
+
super
|
61
|
+
self.ng_xml = Nokogiri::XML::Document.parse(content)
|
62
|
+
end
|
62
63
|
|
63
64
|
|
64
65
|
def to_xml(xml = self.ng_xml)
|
@@ -65,6 +65,13 @@ module ActiveFedora
|
|
65
65
|
return uri.gsub(/(:)/, '\\:')
|
66
66
|
end
|
67
67
|
|
68
|
+
# Escapes these characters
|
69
|
+
# + - || ! ( ) { } [ ] ^ " ~ * ? : \
|
70
|
+
# See: http://lucene.apache.org/java/2_4_0/queryparsersyntax.html#Escaping%20Special%20Characters
|
71
|
+
def self.escape_characters_for_query(value)
|
72
|
+
value.gsub(/([\#\+\-\|\{\}\^\"\~\*\:\>\<\?\(\)\[\]\+\!\\])/) {|v| "\\#{v}"}
|
73
|
+
end
|
74
|
+
|
68
75
|
|
69
76
|
end #SolrService
|
70
77
|
class SolrNotInitialized < StandardError;end
|
data/lib/fedora/connection.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "base64"
|
2
2
|
gem 'multipart-post'
|
3
3
|
require 'net/http/post/multipart'
|
4
|
+
require 'net/http/persistent'
|
4
5
|
require 'cgi'
|
5
6
|
require "mime/types"
|
6
7
|
require 'net/http'
|
@@ -46,6 +47,9 @@ module Fedora
|
|
46
47
|
# 409 Conflict
|
47
48
|
class ResourceConflict < ClientError; end # :nodoc:
|
48
49
|
|
50
|
+
# 415 Unsupported Media Type
|
51
|
+
class UnsupportedMediaType < ClientError; end # :nodoc:
|
52
|
+
|
49
53
|
# 5xx Server Error
|
50
54
|
class ServerError < ConnectionError; end # :nodoc:
|
51
55
|
|
@@ -60,6 +64,23 @@ module Fedora
|
|
60
64
|
# This class is used by ActiveResource::Base to interface with REST
|
61
65
|
# services.
|
62
66
|
class Connection
|
67
|
+
|
68
|
+
CLASSES = [
|
69
|
+
Net::HTTP::Delete,
|
70
|
+
Net::HTTP::Get,
|
71
|
+
Net::HTTP::Head,
|
72
|
+
Net::HTTP::Post,
|
73
|
+
Net::HTTP::Put
|
74
|
+
].freeze
|
75
|
+
|
76
|
+
MIME_TYPES = {
|
77
|
+
:binary => "application/octet-stream",
|
78
|
+
:json => "application/json",
|
79
|
+
:xml => "text/xml",
|
80
|
+
:none => "text/plain"
|
81
|
+
}.freeze
|
82
|
+
|
83
|
+
|
63
84
|
attr_reader :site, :surrogate
|
64
85
|
attr_accessor :format
|
65
86
|
|
@@ -78,84 +99,102 @@ module Fedora
|
|
78
99
|
@surrogate=surrogate
|
79
100
|
end
|
80
101
|
|
102
|
+
##
|
103
|
+
# Perform an HTTP Delete, Head, Get, Post, or Put.
|
104
|
+
|
105
|
+
CLASSES.each do |clazz|
|
106
|
+
verb = clazz.to_s.split("::").last.downcase
|
107
|
+
|
108
|
+
define_method verb do |*args|
|
109
|
+
path = args[0]
|
110
|
+
params = args[1] || {}
|
111
|
+
|
112
|
+
response_for clazz, path, params
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
81
116
|
# Set URI for remote service.
|
82
117
|
def site=(site)
|
83
118
|
@site = site.is_a?(URI) ? site : URI.parse(site)
|
84
119
|
end
|
85
120
|
|
86
|
-
# Execute a GET request.
|
87
|
-
# Used to get (find) resources.
|
88
|
-
def get(path, headers = {})
|
89
|
-
format.decode(request(:get, path, build_request_headers(headers)).body)
|
90
|
-
end
|
91
|
-
|
92
|
-
# Execute a DELETE request (see HTTP protocol documentation if unfamiliar).
|
93
|
-
# Used to delete resources.
|
94
|
-
def delete(path, headers = {})
|
95
|
-
request(:delete, path, build_request_headers(headers))
|
96
|
-
end
|
97
121
|
|
122
|
+
private
|
98
123
|
|
124
|
+
# Makes request to remote service.
|
125
|
+
def response_for(clazz, path, params)
|
126
|
+
logger.debug "#{clazz} #{path}"
|
127
|
+
request = clazz.new path
|
128
|
+
request.body = params[:body]
|
99
129
|
|
100
|
-
|
101
|
-
request(:get, path, build_request_headers(headers))
|
102
|
-
end
|
103
|
-
def post(path, body='', headers={})
|
104
|
-
do_method(:post, path, body, headers)
|
105
|
-
end
|
106
|
-
def put( path, body='', headers={})
|
107
|
-
do_method(:put, path, body, headers)
|
130
|
+
handle_request request, params[:upload], params[:type], params[:headers] || {}
|
108
131
|
end
|
109
132
|
|
110
|
-
private
|
111
|
-
def do_method(method, path, body = '', headers = {})
|
112
|
-
meth_map={:put=>Net::HTTP::Put::Multipart, :post=>Net::HTTP::Post::Multipart}
|
113
|
-
raise "undefined method: #{method}" unless meth_map.has_key? method
|
114
|
-
headers = build_request_headers(headers)
|
115
|
-
if body.respond_to?(:read)
|
116
|
-
if body.respond_to?(:original_filename?)
|
117
|
-
filename = File.basename(body.original_filename)
|
118
|
-
io = UploadIO.new(body, mime_type,filename)
|
119
|
-
elsif body.path
|
120
|
-
filename = File.basename(body.path)
|
121
|
-
else
|
122
|
-
filename="NOFILE"
|
123
|
-
end
|
124
|
-
mime_types = MIME::Types.of(filename)
|
125
|
-
mime_type ||= mime_types.empty? ? "application/octet-stream" : mime_types.first.content_type
|
126
|
-
|
127
|
-
io = nil
|
128
|
-
if body.is_a?(File)
|
129
|
-
io = UploadIO.new(body.path,mime_type)
|
130
|
-
else
|
131
|
-
io =UploadIO.new(body, mime_type, filename)
|
132
|
-
end
|
133
133
|
|
134
|
-
|
135
|
-
|
134
|
+
def handle_request request, upload, type, headers
|
135
|
+
handle_uploads request, upload, type
|
136
|
+
handle_headers request, upload, type, headers
|
137
|
+
result = http.request self.site, request
|
138
|
+
handle_response(result)
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
# Handle chunked uploads.
|
143
|
+
#
|
144
|
+
# +request+: A Net::HTTP request Object.
|
145
|
+
# +upload+: A Hash with the following keys:
|
146
|
+
# +:file+: The file to be HTTP chunked uploaded.
|
147
|
+
# +:headers+: A Hash containing additional HTTP headers.
|
148
|
+
# +:type+: A Symbol with the mime_type.
|
149
|
+
|
150
|
+
def handle_uploads request, upload, type
|
151
|
+
return unless upload
|
152
|
+
io = nil
|
153
|
+
if upload[:file].is_a?(File)
|
154
|
+
io = File.open upload[:file].path
|
136
155
|
else
|
137
|
-
|
156
|
+
io = upload[:file]
|
138
157
|
end
|
158
|
+
|
159
|
+
request.body_stream = io
|
139
160
|
end
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
161
|
+
|
162
|
+
|
163
|
+
def handle_headers request, upload, type, headers
|
164
|
+
request.basic_auth(self.site.user, self.site.password) if self.site.user
|
165
|
+
|
166
|
+
request.add_field "Accept", mime_type(type)
|
167
|
+
request.add_field "Content-Type", mime_type(type) if requires_content_type? request
|
168
|
+
|
169
|
+
headers.merge! chunked_headers upload
|
170
|
+
headers.each do |header, value|
|
171
|
+
request[header] = value
|
145
172
|
end
|
146
|
-
|
173
|
+
end
|
174
|
+
|
175
|
+
##
|
176
|
+
# Setting of chunked upload headers.
|
177
|
+
#
|
178
|
+
# +upload+: A Hash with the following keys:
|
179
|
+
# +:file+: The file to be HTTP chunked uploaded.
|
180
|
+
|
181
|
+
def chunked_headers upload
|
182
|
+
return {} unless upload
|
147
183
|
|
184
|
+
chunked_headers = {
|
185
|
+
"Content-Type" => mime_type(:binary),
|
186
|
+
"Transfer-Encoding" => "chunked"
|
187
|
+
}.merge upload[:headers] || {}
|
148
188
|
end
|
149
189
|
|
150
|
-
|
151
|
-
|
152
|
-
result = http.send(method, path, *arguments)
|
153
|
-
handle_response(result)
|
190
|
+
def requires_content_type? request
|
191
|
+
[Net::HTTP::Post, Net::HTTP::Put].include? request.class
|
154
192
|
end
|
155
193
|
|
156
194
|
# Handles response and error codes from remote service.
|
157
195
|
def handle_response(response)
|
158
196
|
message = "Error from Fedora: #{response.body}"
|
197
|
+
logger.debug "Response: #{response.code}"
|
159
198
|
case response.code.to_i
|
160
199
|
when 301,302
|
161
200
|
raise(Redirection.new(response))
|
@@ -173,6 +212,8 @@ module Fedora
|
|
173
212
|
raise(MethodNotAllowed.new(response, message))
|
174
213
|
when 409
|
175
214
|
raise(ResourceConflict.new(response, message))
|
215
|
+
when 415
|
216
|
+
raise UnsupportedMediaType.new(response, message)
|
176
217
|
when 422
|
177
218
|
raise(ResourceInvalid.new(response, message))
|
178
219
|
when 423...500
|
@@ -184,35 +225,30 @@ module Fedora
|
|
184
225
|
end
|
185
226
|
end
|
186
227
|
|
228
|
+
def mime_type type
|
229
|
+
if type.kind_of? String
|
230
|
+
type
|
231
|
+
else
|
232
|
+
MIME_TYPES[type] || MIME_TYPES[:xml]
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
187
236
|
# Creates new Net::HTTP instance for communication with
|
188
237
|
# remote service and resources.
|
189
238
|
def http
|
190
|
-
http
|
239
|
+
return @http if @http
|
240
|
+
@http = Net::HTTP::Persistent.new#(@site)
|
191
241
|
if(@site.is_a?(URI::HTTPS))
|
192
|
-
http.use_ssl = true
|
193
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
242
|
+
@http.use_ssl = true
|
243
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
194
244
|
|
195
245
|
if (defined?(SSL_CLIENT_CERT_FILE) && !SSL_CLIENT_CERT_FILE.nil? && defined?(SSL_CLIENT_KEY_FILE) && !SSL_CLIENT_KEY_FILE.nil? && defined?(SSL_CLIENT_KEY_PASS) && !SSL_CLIENT_KEY_PASS.nil?)
|
196
|
-
http.cert = OpenSSL::X509::Certificate.new( File.read(SSL_CLIENT_CERT_FILE) )
|
197
|
-
http.key = OpenSSL::PKey::RSA.new( File.read(SSL_CLIENT_KEY_FILE), SSL_CLIENT_KEY_PASS )
|
246
|
+
@http.cert = OpenSSL::X509::Certificate.new( File.read(SSL_CLIENT_CERT_FILE) )
|
247
|
+
@http.key = OpenSSL::PKey::RSA.new( File.read(SSL_CLIENT_KEY_FILE), SSL_CLIENT_KEY_PASS )
|
198
248
|
end
|
199
249
|
end
|
200
|
-
http
|
250
|
+
@http
|
201
251
|
end
|
202
252
|
|
203
|
-
def default_header
|
204
|
-
@default_header ||= { 'Content-Type' => format.mime_type }
|
205
|
-
end
|
206
|
-
|
207
|
-
# Builds headers for request to remote service.
|
208
|
-
def build_request_headers(headers)
|
209
|
-
headers.merge!({"From"=>surrogate}) if @surrogate
|
210
|
-
authorization_header.update(default_header).update(headers)
|
211
|
-
end
|
212
|
-
|
213
|
-
# Sets authorization header; authentication information is pulled from credentials provided with site URI.
|
214
|
-
def authorization_header
|
215
|
-
(@site.user || @site.password ? { 'Authorization' => 'Basic ' + ["#{@site.user}:#{ @site.password}"].pack('m').delete("\r\n") } : {})
|
216
|
-
end
|
217
253
|
end
|
218
254
|
end
|
data/lib/fedora/repository.rb
CHANGED
@@ -59,7 +59,7 @@ module Fedora
|
|
59
59
|
|
60
60
|
# Fetch the raw content of either a fedora object or datastream
|
61
61
|
def fetch_content(object_uri)
|
62
|
-
response = connection.
|
62
|
+
response = connection.get("#{url_for(object_uri)}?format=xml")
|
63
63
|
StringResponse.new(response.body, response.content_type)
|
64
64
|
end
|
65
65
|
|
@@ -95,7 +95,7 @@ module Fedora
|
|
95
95
|
params[:sessionToken] = options[:sessionToken] if options[:sessionToken]
|
96
96
|
includes = fields.inject("") { |s, f| s += "&#{f}=true"; s }
|
97
97
|
|
98
|
-
convert_xml(connection.get("#{fedora_url.path}/objects?#{params.to_fedora_query}#{includes}"))
|
98
|
+
convert_xml(XmlFormat.decode(connection.get("#{fedora_url.path}/objects?#{params.to_fedora_query}#{includes}").body))
|
99
99
|
end
|
100
100
|
|
101
101
|
# Retrieve an object from fedora and load it as an instance of the given model/class
|
@@ -103,10 +103,14 @@ module Fedora
|
|
103
103
|
# @param pid of the Fedora object to retrieve and deserialize
|
104
104
|
# @param klazz the Model whose deserialize method the object's FOXML will be passed into
|
105
105
|
def find_model(pid, klazz)
|
106
|
-
obj =
|
107
|
-
|
108
|
-
|
106
|
+
obj = nil
|
107
|
+
ms = 1000 * Benchmark.realtime do
|
108
|
+
obj = self.find_objects("pid=#{pid}").first
|
109
|
+
if obj.nil?
|
110
|
+
raise ActiveFedora::ObjectNotFoundError, "The repository does not have an object with pid #{pid}. The repository URL is #{self.base_url}"
|
111
|
+
end
|
109
112
|
end
|
113
|
+
logger.debug "loading #{pid} took #{ms} ms"
|
110
114
|
doc = Nokogiri::XML::Document.parse(obj.object_xml)
|
111
115
|
klazz.deserialize(doc)
|
112
116
|
end
|
@@ -132,7 +136,7 @@ module Fedora
|
|
132
136
|
case object
|
133
137
|
when Fedora::FedoraObject
|
134
138
|
pid = (object.pid ? object : 'new')
|
135
|
-
response = connection.post("#{url_for(pid)}?" + object.attributes.to_fedora_query, object.blob)
|
139
|
+
response = connection.post("#{url_for(pid)}?" + object.attributes.to_fedora_query, :body=>object.blob)
|
136
140
|
if response.code == '201'
|
137
141
|
object.pid = extract_pid(response)
|
138
142
|
object.new_object = false
|
@@ -142,10 +146,14 @@ module Fedora
|
|
142
146
|
end
|
143
147
|
when Fedora::Datastream
|
144
148
|
raise ArgumentError, "Missing dsID attribute" if object.dsid.nil?
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
object.blob
|
149
|
+
headers = {}
|
150
|
+
headers[:type] = object.attributes[:mimeType] if object.attributes[:mimeType]
|
151
|
+
if object.blob.respond_to? :read
|
152
|
+
headers[:upload] = {:file=>object.blob}
|
153
|
+
else
|
154
|
+
headers[:body]=object.blob
|
155
|
+
end
|
156
|
+
response = connection.post("#{url_for(object)}?" + object.attributes.to_fedora_query, headers)
|
149
157
|
if response.code == '201'
|
150
158
|
object.new_object = false
|
151
159
|
true
|
@@ -170,7 +178,13 @@ module Fedora
|
|
170
178
|
response.code == '200' || '307'
|
171
179
|
when Fedora::Datastream
|
172
180
|
raise ArgumentError, "Missing dsID attribute" if object.dsid.nil?
|
173
|
-
|
181
|
+
headers = {}
|
182
|
+
if object.blob.respond_to? :read
|
183
|
+
headers[:upload] = {:file=>object.blob}
|
184
|
+
else
|
185
|
+
headers[:body]=object.blob
|
186
|
+
end
|
187
|
+
response = connection.put("#{url_for(object)}?" + object.attributes.to_fedora_query, headers)
|
174
188
|
response.code == '200' || '201'
|
175
189
|
return response.code
|
176
190
|
else
|
@@ -225,7 +239,7 @@ module Fedora
|
|
225
239
|
content_to_ingest = content_to_ingest.read
|
226
240
|
end
|
227
241
|
|
228
|
-
connection.post(url,content_to_ingest)
|
242
|
+
connection.post(url, :body=>content_to_ingest)
|
229
243
|
end
|
230
244
|
|
231
245
|
# Fetch the given object using custom method. This is used to fetch other aspects of a fedora object,
|
@@ -245,11 +259,11 @@ module Fedora
|
|
245
259
|
end
|
246
260
|
|
247
261
|
extra_params.delete(:format) if method == :export
|
248
|
-
connection.
|
262
|
+
connection.get("#{url_for(object)}#{path}?#{extra_params.to_fedora_query}").body
|
249
263
|
end
|
250
264
|
|
251
265
|
def describe_repository
|
252
|
-
result_body = connection.
|
266
|
+
result_body = connection.get("#{fedora_url.path}/describe?xml=true").body
|
253
267
|
XmlSimple.xml_in(result_body)
|
254
268
|
end
|
255
269
|
|
@@ -140,6 +140,8 @@ end
|
|
140
140
|
describe Fedora::Repository, "find_objects" do
|
141
141
|
before(:all) do
|
142
142
|
Fedora::Repository.register(ActiveFedora.fedora_config[:url])
|
143
|
+
@mock_response = mock("Response")
|
144
|
+
@mock_response.stubs(:body).returns(sample_response_xml)
|
143
145
|
end
|
144
146
|
|
145
147
|
def fields_to_s(fields)
|
@@ -156,31 +158,33 @@ describe Fedora::Repository, "find_objects" do
|
|
156
158
|
|
157
159
|
it "should include all fields by default" do
|
158
160
|
when_find_objects('label~Image*') { |conn|
|
159
|
-
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s(Fedora::ALL_FIELDS))
|
161
|
+
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s(Fedora::ALL_FIELDS)).returns(@mock_response)
|
160
162
|
}
|
161
163
|
end
|
162
164
|
|
163
165
|
it "should include all fields when :include => :all " do
|
164
166
|
when_find_objects('label~Image*', :include => :all) { |conn|
|
165
|
-
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s(Fedora::ALL_FIELDS))
|
167
|
+
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s(Fedora::ALL_FIELDS)).returns(@mock_response)
|
166
168
|
}
|
167
169
|
end
|
168
170
|
|
169
171
|
it "should fetch results with limit" do
|
170
172
|
when_find_objects('label~Image*', :limit => 10) { |conn|
|
171
|
-
conn.expects(:get).with('/fedora/objects?maxResults=10&query=label%7EImage%2A&resultFormat=xml' + fields_to_s(Fedora::ALL_FIELDS))
|
173
|
+
conn.expects(:get).with('/fedora/objects?maxResults=10&query=label%7EImage%2A&resultFormat=xml' + fields_to_s(Fedora::ALL_FIELDS)).returns(@mock_response)
|
172
174
|
}
|
173
175
|
end
|
174
176
|
|
175
177
|
it "should fetch results with some fields but not :pid" do
|
176
178
|
when_find_objects('label~Image*', :select => [:label, :mDate]) { |conn|
|
177
|
-
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s([:pid, :label, :mDate]))
|
179
|
+
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s([:pid, :label, :mDate])).returns(@mock_response)
|
180
|
+
|
178
181
|
}
|
179
182
|
end
|
180
183
|
|
181
184
|
it "should fetch results with some fields with :pid" do
|
182
185
|
when_find_objects('label~Image*', :select => [:pid, :label, :mDate]) { |conn|
|
183
|
-
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s([:pid, :label, :mDate]))
|
186
|
+
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s([:pid, :label, :mDate])).returns(@mock_response)
|
187
|
+
|
184
188
|
}
|
185
189
|
end
|
186
190
|
|
@@ -203,7 +207,7 @@ describe Fedora::Repository, "find_objects" do
|
|
203
207
|
it "should convert xml response with 0 objectFields into array of FedoraObject" do
|
204
208
|
objects = when_find_objects('label~Image*', :select => [:pid, :label, :mDate]) { |conn|
|
205
209
|
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s([:pid, :label, :mDate])).
|
206
|
-
returns(
|
210
|
+
returns(@mock_response)
|
207
211
|
}
|
208
212
|
|
209
213
|
objects.session_token.should == 'aToken'
|
@@ -213,7 +217,7 @@ describe Fedora::Repository, "find_objects" do
|
|
213
217
|
it "should return FedoraObjects with new_object set to false" do
|
214
218
|
objects = when_find_objects('label~Image*', :select => [:pid, :label, :mDate]) { |conn|
|
215
219
|
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s([:pid, :label, :mDate])).
|
216
|
-
returns(
|
220
|
+
returns(@mock_response)
|
217
221
|
}
|
218
222
|
objects.each do |obj|
|
219
223
|
obj.should_not be_new_object
|
@@ -224,7 +228,7 @@ describe Fedora::Repository, "find_objects" do
|
|
224
228
|
it "should convert xml response with single objectFields into array of FedoraObject" do
|
225
229
|
objects = when_find_objects('label~Image*', :select => [:pid, :label, :mDate]) { |conn|
|
226
230
|
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s([:pid, :label, :mDate])).
|
227
|
-
returns(
|
231
|
+
returns(@mock_response)
|
228
232
|
}
|
229
233
|
|
230
234
|
objects.session_token.should == 'aToken'
|
@@ -234,9 +238,10 @@ describe Fedora::Repository, "find_objects" do
|
|
234
238
|
end
|
235
239
|
|
236
240
|
it "should convert xml response 2 objectFields into array of FedoraObject" do
|
241
|
+
@mock_response.stubs(:body).returns(sample_response_xml(2))
|
237
242
|
objects = when_find_objects('label~Image*', :select => [:pid, :label, :mDate]) { |conn|
|
238
243
|
conn.expects(:get).with('/fedora/objects?query=label%7EImage%2A&resultFormat=xml' + fields_to_s([:pid, :label, :mDate])).
|
239
|
-
returns(
|
244
|
+
returns(@mock_response)
|
240
245
|
}
|
241
246
|
|
242
247
|
objects.session_token.should == 'aToken'
|
data/spec/spec_helper.rb
CHANGED
@@ -14,6 +14,8 @@ end
|
|
14
14
|
ENV["RAILS_ENV"] ||= 'test'
|
15
15
|
RAILS_ENV = ENV["RAILS_ENV"]
|
16
16
|
|
17
|
+
logger.level = Logger::WARN if logger.respond_to? :level ###MediaShelf StubLogger doesn't have a level= method
|
18
|
+
|
17
19
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
18
20
|
Dir[File.join(File.dirname(__FILE__)+'/../lib/')+'**/*.rb'].each{|x| require x unless x.match(/railtie.rb$/)}
|
19
21
|
$VERBOSE=nil
|
@@ -2,24 +2,24 @@ require File.join( File.dirname(__FILE__), "../spec_helper" )
|
|
2
2
|
|
3
3
|
require 'active_resource'
|
4
4
|
require 'fedora/repository'
|
5
|
-
|
6
|
-
describe Fedora::Connection do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
5
|
+
### Removed by Justin 2011-9-23
|
6
|
+
# describe Fedora::Connection do
|
7
|
+
# it "should be creatable w/ a surrogate id" do
|
8
|
+
# c = Fedora::Connection.new('http://127.0.0.1/fedora', 'fubar', 'bob')
|
9
|
+
# c.site.to_s.should == "http://127.0.0.1/fedora"
|
10
|
+
# c.format.should == 'fubar'
|
11
|
+
# c.surrogate.should == 'bob'
|
12
|
+
# end
|
13
|
+
# it "should set a from header if surrogate defined." do
|
14
|
+
# c = Fedora::Connection.new('http://127.0.0.1/fedora', ActiveResource::Formats[:xml], 'bob')
|
15
|
+
# h = Hash.new
|
16
|
+
# r= c.send(:build_request_headers,h)
|
17
|
+
# r['From'].should == 'bob'
|
18
|
+
# end
|
19
|
+
# it "should not set a from header if surrogate undefined." do
|
20
|
+
# c = Fedora::Connection.new('http://127.0.0.1/fedora' )
|
21
|
+
# h = Hash.new
|
22
|
+
# r= c.send(:build_request_headers,h)
|
23
|
+
# r['From'].should be_nil
|
24
|
+
# end
|
25
|
+
# end
|
@@ -60,6 +60,17 @@ describe ActiveFedora::Datastream do
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
describe '.content=' do
|
64
|
+
it "should update the content and ng_xml, marking the datastream as dirty" do
|
65
|
+
sample_xml = "<foo><xmlelement/></foo>"
|
66
|
+
@test_datastream.should_not be_dirty
|
67
|
+
@test_datastream.blob.should_not be_equivalent_to(sample_xml)
|
68
|
+
@test_datastream.content = sample_xml
|
69
|
+
@test_datastream.should be_dirty
|
70
|
+
@test_datastream.blob.should be_equivalent_to(sample_xml)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
63
74
|
describe ".dirty?" do
|
64
75
|
it "should return the value of the @dirty attribute" do
|
65
76
|
@test_datastream.dirty.should equal(@test_datastream.dirty?)
|
@@ -10,7 +10,7 @@ describe ActiveFedora::NokogiriDatastream do
|
|
10
10
|
:empty_field => {:values => {}}
|
11
11
|
}
|
12
12
|
@sample_xml = XmlSimple.xml_in("<fields><coverage>coverage1</coverage><coverage>coverage2</coverage><creation_date>fake-date</creation_date><mydate>fake-date</mydate><publisher>publisher1</publisher></fields>")
|
13
|
-
|
13
|
+
@sample_raw_xml = "<foo><xmlelement/></foo>"
|
14
14
|
@solr_doc = {"id"=>"hydrange_article1","name_role_roleTerm_t"=>["creator","submitter","teacher"],"name_0_role_t"=>"\r\ncreator\r\nsubmitter\r\n","name_1_role_t"=>"\r\n teacher \r\n","name_0_role_0_roleTerm_t"=>"creator","name_0_role_1_roleTerm_t"=>"submitter","name_1_role_0_roleTerm_t"=>["teacher"]}
|
15
15
|
end
|
16
16
|
|
@@ -35,8 +35,8 @@ describe ActiveFedora::NokogiriDatastream do
|
|
35
35
|
test_ds1.ng_xml.to_xml.should == "<?xml version=\"1.0\"?>\n<xml>\n <foo/>\n</xml>\n"
|
36
36
|
end
|
37
37
|
it "should initialize from #xml_template if no xml is provided" do
|
38
|
-
ActiveFedora::NokogiriDatastream.expects(:xml_template).returns("fake template")
|
39
|
-
ActiveFedora::NokogiriDatastream.new.ng_xml.should
|
38
|
+
ActiveFedora::NokogiriDatastream.expects(:xml_template).returns("<fake template/>")
|
39
|
+
ActiveFedora::NokogiriDatastream.new.ng_xml.should be_equivalent_to("<fake template/>")
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -234,6 +234,32 @@ describe ActiveFedora::NokogiriDatastream do
|
|
234
234
|
end
|
235
235
|
end
|
236
236
|
|
237
|
+
describe '.content=' do
|
238
|
+
it "should update the content and ng_xml, marking the datastream as dirty" do
|
239
|
+
@test_ds.should_not be_dirty
|
240
|
+
@test_ds.blob.should_not be_equivalent_to(@sample_raw_xml)
|
241
|
+
@test_ds.ng_xml.to_xml.should_not be_equivalent_to(@sample_raw_xml)
|
242
|
+
@test_ds.content = @sample_raw_xml
|
243
|
+
@test_ds.should be_dirty
|
244
|
+
@test_ds.blob.should be_equivalent_to(@sample_raw_xml)
|
245
|
+
@test_ds.ng_xml.to_xml.should be_equivalent_to(@sample_raw_xml)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe 'ng_xml=' do
|
250
|
+
it "should parse raw xml for you" do
|
251
|
+
@test_ds.ng_xml.to_xml.should_not be_equivalent_to(@sample_raw_xml)
|
252
|
+
@test_ds.ng_xml = @sample_raw_xml
|
253
|
+
@test_ds.ng_xml.class.should == Nokogiri::XML::Document
|
254
|
+
@test_ds.ng_xml.to_xml.should be_equivalent_to(@sample_raw_xml)
|
255
|
+
end
|
256
|
+
it "should mark the datastream as dirty" do
|
257
|
+
@test_ds.should_not be_dirty
|
258
|
+
@test_ds.ng_xml = @sample_raw_xml
|
259
|
+
@test_ds.should be_dirty
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
237
263
|
describe '.to_xml' do
|
238
264
|
it "should provide .to_xml" do
|
239
265
|
@test_ds.should respond_to(:to_xml)
|
@@ -99,14 +99,14 @@ describe Fedora::Repository do
|
|
99
99
|
it "should post the provided xml or file to fedora" do
|
100
100
|
foxml = fixture("test_12.foxml.xml").read
|
101
101
|
connection = Fedora::Repository.instance.send(:connection)
|
102
|
-
connection.expects(:post).with("/fedora/objects/new"
|
102
|
+
connection.expects(:post).with("/fedora/objects/new",:body=>foxml)
|
103
103
|
Fedora::Repository.instance.ingest(foxml)
|
104
104
|
end
|
105
105
|
it "should accept a file as its input" do
|
106
106
|
foxml_file = fixture("test_12.foxml.xml")
|
107
107
|
foxml = fixture("test_12.foxml.xml").read
|
108
108
|
connection = Fedora::Repository.instance.send(:connection)
|
109
|
-
connection.expects(:post).with("/fedora/objects/new"
|
109
|
+
connection.expects(:post).with("/fedora/objects/new",:body=>foxml)
|
110
110
|
Fedora::Repository.instance.ingest(foxml_file)
|
111
111
|
end
|
112
112
|
end
|
@@ -84,4 +84,11 @@ describe ActiveFedora::SolrService do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
+
describe "escape_characters_for_query" do
|
88
|
+
it "should escape the Solr special characters" do
|
89
|
+
test_val = '# + - || ! ( ) { } [ ] ^ " ~ * ? : \\'
|
90
|
+
expected_result = '\\# \\+ \\- \\|\\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\" \\~ \\* \\? \\: \\\\'
|
91
|
+
ActiveFedora::SolrService.escape_characters_for_query(test_val).should == expected_result
|
92
|
+
end
|
93
|
+
end
|
87
94
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active-fedora
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 2.3.
|
9
|
+
- 8
|
10
|
+
version: 2.3.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matt Zumwalt
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-09-
|
19
|
+
date: 2011-09-23 00:00:00 -05:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -133,12 +133,14 @@ dependencies:
|
|
133
133
|
requirement: &id008 !ruby/object:Gem::Requirement
|
134
134
|
none: false
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - <
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
hash:
|
138
|
+
hash: 7
|
139
139
|
segments:
|
140
|
+
- 3
|
140
141
|
- 0
|
141
|
-
|
142
|
+
- 0
|
143
|
+
version: 3.0.0
|
142
144
|
type: :runtime
|
143
145
|
version_requirements: *id008
|
144
146
|
- !ruby/object:Gem::Dependency
|
@@ -184,7 +186,7 @@ dependencies:
|
|
184
186
|
type: :runtime
|
185
187
|
version_requirements: *id011
|
186
188
|
- !ruby/object:Gem::Dependency
|
187
|
-
name:
|
189
|
+
name: net-http-persistent
|
188
190
|
prerelease: false
|
189
191
|
requirement: &id012 !ruby/object:Gem::Requirement
|
190
192
|
none: false
|
@@ -195,10 +197,10 @@ dependencies:
|
|
195
197
|
segments:
|
196
198
|
- 0
|
197
199
|
version: "0"
|
198
|
-
type: :
|
200
|
+
type: :runtime
|
199
201
|
version_requirements: *id012
|
200
202
|
- !ruby/object:Gem::Dependency
|
201
|
-
name:
|
203
|
+
name: yard
|
202
204
|
prerelease: false
|
203
205
|
requirement: &id013 !ruby/object:Gem::Requirement
|
204
206
|
none: false
|
@@ -212,7 +214,7 @@ dependencies:
|
|
212
214
|
type: :development
|
213
215
|
version_requirements: *id013
|
214
216
|
- !ruby/object:Gem::Dependency
|
215
|
-
name:
|
217
|
+
name: RedCloth
|
216
218
|
prerelease: false
|
217
219
|
requirement: &id014 !ruby/object:Gem::Requirement
|
218
220
|
none: false
|
@@ -226,7 +228,7 @@ dependencies:
|
|
226
228
|
type: :development
|
227
229
|
version_requirements: *id014
|
228
230
|
- !ruby/object:Gem::Dependency
|
229
|
-
name:
|
231
|
+
name: rake
|
230
232
|
prerelease: false
|
231
233
|
requirement: &id015 !ruby/object:Gem::Requirement
|
232
234
|
none: false
|
@@ -240,7 +242,7 @@ dependencies:
|
|
240
242
|
type: :development
|
241
243
|
version_requirements: *id015
|
242
244
|
- !ruby/object:Gem::Dependency
|
243
|
-
name:
|
245
|
+
name: rcov
|
244
246
|
prerelease: false
|
245
247
|
requirement: &id016 !ruby/object:Gem::Requirement
|
246
248
|
none: false
|
@@ -254,7 +256,7 @@ dependencies:
|
|
254
256
|
type: :development
|
255
257
|
version_requirements: *id016
|
256
258
|
- !ruby/object:Gem::Dependency
|
257
|
-
name:
|
259
|
+
name: solrizer-fedora
|
258
260
|
prerelease: false
|
259
261
|
requirement: &id017 !ruby/object:Gem::Requirement
|
260
262
|
none: false
|
@@ -268,9 +270,23 @@ dependencies:
|
|
268
270
|
type: :development
|
269
271
|
version_requirements: *id017
|
270
272
|
- !ruby/object:Gem::Dependency
|
271
|
-
name:
|
273
|
+
name: jettywrapper
|
272
274
|
prerelease: false
|
273
275
|
requirement: &id018 !ruby/object:Gem::Requirement
|
276
|
+
none: false
|
277
|
+
requirements:
|
278
|
+
- - ">="
|
279
|
+
- !ruby/object:Gem::Version
|
280
|
+
hash: 3
|
281
|
+
segments:
|
282
|
+
- 0
|
283
|
+
version: "0"
|
284
|
+
type: :development
|
285
|
+
version_requirements: *id018
|
286
|
+
- !ruby/object:Gem::Dependency
|
287
|
+
name: rspec
|
288
|
+
prerelease: false
|
289
|
+
requirement: &id019 !ruby/object:Gem::Requirement
|
274
290
|
none: false
|
275
291
|
requirements:
|
276
292
|
- - <
|
@@ -282,11 +298,11 @@ dependencies:
|
|
282
298
|
- 0
|
283
299
|
version: 2.0.0
|
284
300
|
type: :development
|
285
|
-
version_requirements: *
|
301
|
+
version_requirements: *id019
|
286
302
|
- !ruby/object:Gem::Dependency
|
287
303
|
name: mocha
|
288
304
|
prerelease: false
|
289
|
-
requirement: &
|
305
|
+
requirement: &id020 !ruby/object:Gem::Requirement
|
290
306
|
none: false
|
291
307
|
requirements:
|
292
308
|
- - ">="
|
@@ -298,11 +314,11 @@ dependencies:
|
|
298
314
|
- 8
|
299
315
|
version: 0.9.8
|
300
316
|
type: :development
|
301
|
-
version_requirements: *
|
317
|
+
version_requirements: *id020
|
302
318
|
- !ruby/object:Gem::Dependency
|
303
319
|
name: ruby-debug
|
304
320
|
prerelease: false
|
305
|
-
requirement: &
|
321
|
+
requirement: &id021 !ruby/object:Gem::Requirement
|
306
322
|
none: false
|
307
323
|
requirements:
|
308
324
|
- - ">="
|
@@ -312,7 +328,7 @@ dependencies:
|
|
312
328
|
- 0
|
313
329
|
version: "0"
|
314
330
|
type: :development
|
315
|
-
version_requirements: *
|
331
|
+
version_requirements: *id021
|
316
332
|
description: ActiveFedora provides for creating and managing objects in the Fedora Repository Architecture.
|
317
333
|
email:
|
318
334
|
- matt.zumwalt@yourmediashelf.com
|