ruby-fedora 0.1.2 → 0.9.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.
Files changed (48) hide show
  1. data/COPYING.LESSER.txt +165 -0
  2. data/COPYING.txt +674 -0
  3. data/Manifest.txt +19 -20
  4. data/README.txt +6 -1
  5. data/Rakefile +4 -0
  6. data/config/hoe.rb +2 -2
  7. data/config/requirements.rb +9 -2
  8. data/lib/active_fedora.rb +41 -0
  9. data/lib/active_fedora/base.rb +278 -8
  10. data/lib/active_fedora/content_model.rb +22 -0
  11. data/lib/active_fedora/datastream.rb +95 -0
  12. data/lib/active_fedora/fedora_object.rb +84 -0
  13. data/lib/active_fedora/metadata_datastream.rb +97 -0
  14. data/lib/active_fedora/model.rb +94 -0
  15. data/lib/active_fedora/property.rb +15 -0
  16. data/lib/active_fedora/qualified_dublin_core_datastream.rb +72 -0
  17. data/lib/active_fedora/relationship.rb +43 -0
  18. data/lib/active_fedora/rels_ext_datastream.rb +43 -0
  19. data/lib/active_fedora/semantic_node.rb +221 -0
  20. data/lib/active_fedora/solr_service.rb +20 -0
  21. data/lib/fedora/base.rb +2 -1
  22. data/lib/fedora/connection.rb +104 -134
  23. data/lib/fedora/datastream.rb +10 -1
  24. data/lib/fedora/fedora_object.rb +28 -24
  25. data/lib/fedora/generic_search.rb +71 -0
  26. data/lib/fedora/repository.rb +47 -3
  27. data/lib/ruby-fedora.rb +9 -8
  28. data/lib/util/class_level_inheritable_attributes.rb +23 -0
  29. data/solr/config/schema.xml +229 -0
  30. metadata +37 -24
  31. data/lib/active-fedora.rb +0 -1
  32. data/lib/ambition/adapters/active_fedora.rb +0 -10
  33. data/lib/ambition/adapters/active_fedora/base.rb +0 -14
  34. data/lib/ambition/adapters/active_fedora/query.rb +0 -48
  35. data/lib/ambition/adapters/active_fedora/select.rb +0 -104
  36. data/lib/ambition/adapters/active_fedora/slice.rb +0 -19
  37. data/lib/ambition/adapters/active_fedora/sort.rb +0 -43
  38. data/script/destroy +0 -14
  39. data/script/generate +0 -14
  40. data/script/txt2html +0 -74
  41. data/tasks/deployment.rake +0 -34
  42. data/tasks/environment.rake +0 -7
  43. data/tasks/website.rake +0 -17
  44. data/website/index.html +0 -93
  45. data/website/index.txt +0 -39
  46. data/website/javascripts/rounded_corners_lite.inc.js +0 -285
  47. data/website/stylesheets/screen.css +0 -138
  48. data/website/template.rhtml +0 -48
@@ -0,0 +1,43 @@
1
+ module ActiveFedora
2
+
3
+ class Relationship
4
+
5
+ attr_accessor :subject, :predicate, :object, :is_literal, :data_type
6
+ def initialize(attr={})
7
+ attr.merge!({:is_literal => false})
8
+ self.subject = attr[:subject]
9
+ @predicate = attr[:predicate]
10
+ self.object = attr[:object]
11
+ @is_literal = attr[:is_literal]
12
+ @data_type = attr[:data_type]
13
+ end
14
+
15
+ def subject=(subject)
16
+ @subject = generate_uri(subject)
17
+ end
18
+
19
+ def subject_pid=(pid)
20
+ @subject = "info:fedora/#{pid}"
21
+ end
22
+
23
+ def object=(object)
24
+ @object = generate_uri(object)
25
+ end
26
+
27
+ def object_pid=(pid)
28
+ @object = "info:fedora/#{pid}"
29
+ end
30
+
31
+ def generate_uri(input)
32
+ if input.class == Symbol || input == nil
33
+ return input
34
+ elsif input.respond_to?(:pid)
35
+ return "info:fedora/#{input.pid}"
36
+ else
37
+ input.include?("info:fedora") ? input : "info:fedora/#{input}"
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,43 @@
1
+ require 'active_fedora/semantic_node'
2
+
3
+ module ActiveFedora
4
+ class RelsExtDatastream < Datastream
5
+
6
+ include ActiveFedora::SemanticNode
7
+
8
+ def initialize(attrs=nil)
9
+ super
10
+ self.dsid = "RELS-EXT"
11
+ end
12
+
13
+ def save
14
+ if @dirty == true
15
+ self.content = to_rels_ext(self.pid)
16
+ end
17
+ super
18
+ end
19
+
20
+ def pid=(pid)
21
+ super
22
+ self.blob = <<-EOL
23
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
24
+ <rdf:Description rdf:about="info:fedora/#{pid}">
25
+ </rdf:Description>
26
+ </rdf:RDF>
27
+ EOL
28
+ end
29
+
30
+ def to_solr(solr_doc = Solr::Document.new)
31
+ self.relationships.each_pair do |subject, predicates|
32
+ if subject == :self || subject == "info:fedora/#{self.pid}"
33
+ predicates.each_pair do |predicate, values|
34
+ values.each do |val|
35
+ solr_doc << Solr::Field.new("#{predicate}_field" => val)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ return solr_doc
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,221 @@
1
+ module ActiveFedora
2
+ module SemanticNode
3
+ include MediaShelfClassLevelInheritableAttributes
4
+ ms_inheritable_attributes :class_relationships, :internal_uri
5
+ include Extlib::Assertions
6
+
7
+ attr_accessor :internal_uri, :relationships
8
+
9
+ PREDICATE_MAPPINGS = Hash[:is_member_of => "isMemberOf",
10
+ :is_part_of => "isPartOf",
11
+ :has_part => "hasPart",
12
+ :conforms_to => "conformsTo"]
13
+
14
+ def self.included(klass)
15
+ klass.extend(ClassMethods)
16
+ end
17
+
18
+ def add_relationship(relationship)
19
+ # Only accept ActiveFedora::Relationships as input arguments
20
+ assert_kind_of 'relationship', relationship, ActiveFedora::Relationship
21
+ register_triple(relationship.subject, relationship.predicate, relationship.object)
22
+ end
23
+
24
+ def register_triple(subject, predicate, object)
25
+ register_subject(subject)
26
+ register_predicate(subject, predicate)
27
+ relationships[subject][predicate] << object
28
+ end
29
+
30
+ def register_subject(subject)
31
+ if !relationships.has_key?(subject)
32
+ relationships[subject] = {}
33
+ end
34
+ end
35
+
36
+ def register_predicate(subject, predicate)
37
+ register_subject(subject)
38
+ if !relationships[subject].has_key?(predicate)
39
+ relationships[subject][predicate] = []
40
+ end
41
+ end
42
+
43
+ def outbound_relationships()
44
+ if !internal_uri.nil? && !relationships[internal_uri].nil?
45
+ return relationships[:self].merge(relationships[internal_uri])
46
+ else
47
+ return relationships[:self]
48
+ end
49
+ end
50
+
51
+ def relationships
52
+ @relationships ||= relationships_from_class
53
+ end
54
+
55
+ def relationships_from_class
56
+ rels = {}
57
+ self.class.relationships.each_pair do |subj, pred|
58
+ rels[subj] = {}
59
+ pred.each_key do |pred_key|
60
+ rels[subj][pred_key] = []
61
+ end
62
+ end
63
+ #puts "rels from class: #{rels.inspect}"
64
+ return rels
65
+ end
66
+
67
+ # Creates a RELS-EXT datastream for insertion into a Fedora Object
68
+ # @pid
69
+ # Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array
70
+ def to_rels_ext(pid, relationships=self.relationships)
71
+ starter_xml = <<-EOL
72
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
73
+ <rdf:Description rdf:about="info:fedora/#{pid}">
74
+ </rdf:Description>
75
+ </rdf:RDF>
76
+ EOL
77
+ xml = REXML::Document.new(starter_xml)
78
+
79
+ # Iterate through the hash of predicates, adding an element to the RELS-EXT for each "object" in the predicate's corresponding array.
80
+ # puts ""
81
+ # puts "Iterating through a(n) #{self.class}"
82
+ # puts "=> whose relationships are #{self.relationships.inspect}"
83
+ # puts "=> and whose outbound relationships are #{self.outbound_relationships.inspect}"
84
+ self.outbound_relationships.each do |predicate, targets_array|
85
+ targets_array.each do |target|
86
+ # puts ". #{predicate} #{target}"
87
+ xml.root.elements["rdf:Description"].add_element(self.class.predicate_lookup(predicate), {"xmlns" => "info:fedora/fedora-system:def/relations-external#", "rdf:resource"=>target})
88
+ end
89
+ end
90
+ xml.to_s
91
+ end
92
+
93
+ module ClassMethods
94
+
95
+ # Anticipates usage of a relationship in classes that include this module
96
+ # Creates a key in the @relationships array for the predicate provided. Assumes
97
+ # :self as the subject of the relationship unless :inbound => true, in which case the
98
+ # predicate is registered under @relationships[:inbound][#{predicate}]
99
+ #
100
+ # TODO:
101
+ # Custom Methods:
102
+ # A custom finder method will be appended based on the relationship name.
103
+ # ie.
104
+ # class Foo
105
+ # relationship "container", :is_member_of
106
+ # end
107
+ # foo = Foo.new
108
+ # foo.parts
109
+ #
110
+ # Special Predicate Short Hand:
111
+ # These symbols map to the uris of corresponding Fedora RDF predicates
112
+ # :is_member_of, :has_member, :is_part_of, :has_part
113
+ def has_relationship(name, predicate, opts = {})
114
+ opts = {:singular => nil, :inbound => false}.merge(opts)
115
+ opts[:inbound] == true ? register_predicate(:inbound, predicate) : register_predicate(:self, predicate)
116
+
117
+ if opts[:inbound] == true
118
+ create_inbound_relationship_finders(name, predicate, opts)
119
+ else
120
+ create_outbound_relationship_finders(name, predicate, opts)
121
+ end
122
+
123
+ end
124
+
125
+ def create_inbound_relationship_finders(name, predicate, opts = {})
126
+ class_eval <<-END
127
+ def #{name}
128
+ escaped_uri = self.internal_uri.gsub(/(:)/, '\\:')
129
+ hits = SolrService.instance.conn.query("#{predicate}_field:\#{escaped_uri}").hits
130
+ results = []
131
+ hits.each do |hit|
132
+ classname = Kernel.const_get(hit["active_fedora_model_field"].first)
133
+ results << Fedora::Repository.instance.find_model(hit["id"], classname)
134
+ end
135
+ return results
136
+ end
137
+ def #{name}_ids
138
+ escaped_uri = self.internal_uri.gsub(/(:)/, '\\:')
139
+ SolrService.instance.conn.query("#{predicate}_field:\#{escaped_uri}")
140
+ end
141
+ END
142
+ end
143
+
144
+ def create_outbound_relationship_finders(name, predicate, opts = {})
145
+ class_eval <<-END
146
+ def #{name}
147
+ results = []
148
+ outbound_relationships[#{predicate.inspect}].each do |rel|
149
+ uri_as_pid = rel.gsub("info:fedora/", "")
150
+ results << Fedora::Repository.instance.find_model(uri_as_pid, ActiveFedora::Base)
151
+ end
152
+ return results
153
+ end
154
+ def #{name}_ids
155
+ results = []
156
+ outbound_relationships[#{predicate.inspect}].each do |rel|
157
+ results << rel
158
+ end
159
+ end
160
+ END
161
+ end
162
+
163
+ # relationships are tracked as a hash of structure {subject => {predicate => [object]}}
164
+ def relationships
165
+ @class_relationships ||= Hash[:self => {}]
166
+ end
167
+
168
+
169
+ def register_subject(subject)
170
+ if !relationships.has_key?(subject)
171
+ relationships[subject] = {}
172
+ end
173
+ end
174
+
175
+ def register_predicate(subject, predicate)
176
+ register_subject(subject)
177
+ if !relationships[subject].has_key?(predicate)
178
+ relationships[subject][predicate] = []
179
+ end
180
+ end
181
+
182
+ #alias_method :register_target, :register_object
183
+
184
+ # Creates a RELS-EXT datastream for insertion into a Fedora Object
185
+ # @pid
186
+ # Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array
187
+ def relationships_to_rels_ext(pid, relationships=self.relationships)
188
+ starter_xml = <<-EOL
189
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
190
+ <rdf:Description rdf:about="info:fedora/#{pid}">
191
+ </rdf:Description>
192
+ </rdf:RDF>
193
+ EOL
194
+ xml = REXML::Document.new(starter_xml)
195
+
196
+ # Iterate through the hash of predicates, adding an element to the RELS-EXT for each "object" in the predicate's corresponding array.
197
+ self.outbound_relationships.each do |predicate, targets_array|
198
+ targets_array.each do |target|
199
+ #puts ". #{predicate} #{target}"
200
+ xml.root.elements["rdf:Description"].add_element(predicate_lookup(predicate), {"xmlns" => "info:fedora/fedora-system:def/relations-external#", "rdf:resource"=>target})
201
+ end
202
+ end
203
+ xml.to_s
204
+ end
205
+
206
+ # If predicate is a symbol, looks up the predicate in the PREDICATE_MAPPINGS
207
+ # If predicate is not a Symbol, returns the predicate untouched
208
+ # @throws UnregisteredPredicateError if the predicate is a symbol but is not found in the PREDICATE_MAPPINGS
209
+ def predicate_lookup(predicate)
210
+ if predicate.class == Symbol
211
+ if PREDICATE_MAPPINGS.has_key?(predicate)
212
+ return PREDICATE_MAPPINGS[predicate]
213
+ else
214
+ throw UnregisteredPredicateError
215
+ end
216
+ end
217
+ return predicate
218
+ end
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,20 @@
1
+ require 'solr'
2
+ module ActiveFedora
3
+ class SolrService
4
+ attr_reader :conn
5
+ def self.register(host=nil, args={})
6
+ Thread.current[:solr_service]=self.new(host, args)
7
+
8
+ end
9
+ def initialize(host, args)
10
+ host = 'http://localhost:8080/solr' unless host
11
+ opts = {:autocommit=>:on}.merge(args)
12
+ @conn = Solr::Connection.new(host, opts)
13
+ end
14
+ def self.instance
15
+ raise SolrNotInitialized unless Thread.current[:solr_service]
16
+ Thread.current[:solr_service]
17
+ end
18
+ end
19
+ class SolrNotInitialized < StandardError;end
20
+ end
data/lib/fedora/base.rb CHANGED
@@ -12,7 +12,7 @@ class Hash
12
12
  end
13
13
 
14
14
  class Fedora::BaseObject
15
- attr_accessor :attributes, :blob, :uri, :url
15
+ attr_accessor :attributes, :blob, :uri
16
16
  attr_reader :errors, :uri
17
17
  attr_writer :new_object
18
18
 
@@ -24,6 +24,7 @@ class Fedora::BaseObject
24
24
  @attributes = attrs || {}
25
25
  @errors = []
26
26
  @blob = attributes.delete(:blob)
27
+ @repository = Fedora::Repository.instance
27
28
  end
28
29
 
29
30
  def [](key)
@@ -1,64 +1,14 @@
1
1
  require "base64"
2
+ gem 'multipart-post'
3
+ require 'net/http/post/multipart'
2
4
  require 'cgi'
3
5
  require "mime/types"
4
6
  require 'net/http'
5
7
  require 'net/https'
6
8
 
7
- # Add multipart/form-data support to net/http
8
- #
9
- # ==== Usage
10
- # File.open(File.expand_path('script/test.png'), 'r') do |file|
11
- # http = Net::HTTP.new('localhost', 3000)
12
- # begin
13
- # http.start do |http|
14
- # request = Net::HTTP::Post.new('/your/url/here')
15
- # request.set_multipart_data(:file => file, :title => 'test.png')
16
- # response = http.request(request)
17
- # puts response
18
- # end
19
- # rescue Net::HTTPServerException => e
20
- # p e
21
- # end
22
- # end
23
- module Fedora::Multipart
24
- def set_multipart_data(param_hash={})
25
- mime_type = param_hash.delete(:content_type)
26
- boundary_token = [Array.new(8) {rand(256)}].join
27
- self.content_type = "multipart/form-data; boundary=#{boundary_token}"
28
- boundary_marker = "--#{boundary_token}\r\n"
29
- self.body = param_hash.map { |param_name, param_value|
30
- boundary_marker + case param_value
31
- when File then file_to_multipart(param_name, param_value, mime_type)
32
- when String then text_to_multipart(param_name, param_value, mime_type)
33
- else ""
34
- end
35
- }.join('') + "--#{boundary_token}--\r\n"
36
- end
37
-
38
- private
39
- def file_to_multipart(key,file, mime_type = nil)
40
- filename = File.basename(file.path)
41
- mime_types = MIME::Types.of(filename)
42
- mime_type ||= mime_types.empty? ? "application/octet-stream" : mime_types.first.content_type
43
- part = %Q{Content-Disposition: form-data; name="#{key}"; filename="#{filename}"\r\n}
44
- part += "Content-Transfer-Encoding: binary\r\n"
45
- part += "Content-Type: #{mime_type}\r\n\r\n#{file.read}"
46
- end
47
-
48
- def text_to_multipart(key,value)
49
- "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n#{value}\r\n"
50
- end
51
- end
52
9
 
53
- class Net::HTTP::Post
54
- include Fedora::Multipart
55
- end
56
-
57
- class Net::HTTP::Put
58
- include Fedora::Multipart
59
- end
60
10
 
61
- module RubyFedora
11
+ module Fedora
62
12
  # This class is based on ActiveResource::Connection so MIT license applies.
63
13
  class ConnectionError < StandardError # :nodoc:
64
14
  attr_reader :response
@@ -110,7 +60,7 @@ module RubyFedora
110
60
  # This class is used by ActiveResource::Base to interface with REST
111
61
  # services.
112
62
  class Connection
113
- attr_reader :site
63
+ attr_reader :site, :surrogate
114
64
  attr_accessor :format
115
65
 
116
66
  class << self
@@ -121,10 +71,11 @@ module RubyFedora
121
71
 
122
72
  # The +site+ parameter is required and will set the +site+
123
73
  # attribute to the URI for the remote resource service.
124
- def initialize(site, format = ActiveResource::Formats[:xml])
74
+ def initialize(site, format = ActiveResource::Formats[:xml], surrogate=nil)
125
75
  raise ArgumentError, 'Missing site URI' unless site
126
76
  self.site = site
127
77
  self.format = format
78
+ @surrogate=surrogate
128
79
  end
129
80
 
130
81
  # Set URI for remote service.
@@ -144,97 +95,116 @@ module RubyFedora
144
95
  request(:delete, path, build_request_headers(headers))
145
96
  end
146
97
 
147
- # Execute a PUT request (see HTTP protocol documentation if unfamiliar).
148
- # Used to update resources.
149
- def put(path, body = '', headers = {})
150
- if body.is_a?(File)
151
- multipart_request(Net::HTTP::Put.new(path, build_request_headers(headers)), body, headers)
152
- else
153
- request(:put, path, body.to_s, build_request_headers(headers))
154
- end
155
- end
156
-
157
- # Execute a POST request.
158
- # Used to create new resources.
159
- def post(path, body = '', headers = {})
160
- if body.is_a?(File)
161
- multipart_request(Net::HTTP::Post.new(path, build_request_headers(headers)), body, headers)
162
- else
163
- request(:post, path, body.to_s, build_request_headers(headers))
164
- end
165
- end
98
+
166
99
 
167
100
  def raw_get(path, headers = {})
168
101
  request(:get, path, build_request_headers(headers))
169
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)
108
+ end
170
109
 
171
110
  private
172
- def multipart_request(req, file, headers = {})
173
- result = nil
174
- http.start do |conn|
175
- req.set_multipart_data(:file => file, :content_type => headers['Content-Type'])
176
- result = conn.request(req)
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"
177
123
  end
178
- handle_response(result)
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
+
134
+ req = meth_map[method].new(path, {:file=>io}, headers)
135
+ multipart_request(req)
136
+ else
137
+ request(method, path, body.to_s, headers)
179
138
  end
180
-
181
- # Makes request to remote service.
182
- def request(method, path, *arguments)
183
- result = http.send(method, path, *arguments)
184
- handle_response(result)
139
+ end
140
+ def multipart_request(req)
141
+ result = nil
142
+ result = http.start do |conn|
143
+ conn.read_timeout=60600 #these can take a while
144
+ conn.request(req)
185
145
  end
146
+ handle_response(result)
186
147
 
187
- # Handles response and error codes from remote service.
188
- def handle_response(response)
189
- case response.code.to_i
190
- when 301,302
191
- raise(Redirection.new(response))
192
- when 200...400
193
- response
194
- when 400
195
- raise(BadRequest.new(response))
196
- when 401
197
- raise(UnauthorizedAccess.new(response))
198
- when 403
199
- raise(ForbiddenAccess.new(response))
200
- when 404
201
- raise(ResourceNotFound.new(response))
202
- when 405
203
- raise(MethodNotAllowed.new(response))
204
- when 409
205
- raise(ResourceConflict.new(response))
206
- when 422
207
- raise(ResourceInvalid.new(response))
208
- when 401...500
209
- raise(ClientError.new(response))
210
- when 500...600
211
- raise(ServerError.new(response))
212
- else
213
- raise(ConnectionError.new(response, "Unknown response code: #{response.code}"))
214
- end
215
- end
148
+ end
216
149
 
217
- # Creates new Net::HTTP instance for communication with
218
- # remote service and resources.
219
- def http
220
- http = Net::HTTP.new(@site.host, @site.port)
221
- http.use_ssl = @site.is_a?(URI::HTTPS)
222
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl
223
- http
224
- end
150
+ # Makes request to remote service.
151
+ def request(method, path, *arguments)
152
+ result = http.send(method, path, *arguments)
153
+ handle_response(result)
154
+ end
225
155
 
226
- def default_header
227
- @default_header ||= { 'Content-Type' => format.mime_type }
228
- end
229
-
230
- # Builds headers for request to remote service.
231
- def build_request_headers(headers)
232
- authorization_header.update(default_header).update(headers)
233
- end
234
-
235
- # Sets authorization header; authentication information is pulled from credentials provided with site URI.
236
- def authorization_header
237
- (@site.user || @site.password ? { 'Authorization' => 'Basic ' + ["#{@site.user}:#{ @site.password}"].pack('m').delete("\r\n") } : {})
156
+ # Handles response and error codes from remote service.
157
+ def handle_response(response)
158
+ case response.code.to_i
159
+ when 301,302
160
+ raise(Redirection.new(response))
161
+ when 200...400
162
+ response
163
+ when 400
164
+ raise(BadRequest.new(response))
165
+ when 401
166
+ raise(UnauthorizedAccess.new(response))
167
+ when 403
168
+ raise(ForbiddenAccess.new(response))
169
+ when 404
170
+ raise(ResourceNotFound.new(response))
171
+ when 405
172
+ raise(MethodNotAllowed.new(response))
173
+ when 409
174
+ raise(ResourceConflict.new(response))
175
+ when 422
176
+ raise(ResourceInvalid.new(response))
177
+ when 401...500
178
+ raise(ClientError.new(response))
179
+ when 500...600
180
+ raise(ServerError.new(response))
181
+ else
182
+ raise(ConnectionError.new(response, "Unknown response code: #{response.code}"))
238
183
  end
184
+ end
185
+
186
+ # Creates new Net::HTTP instance for communication with
187
+ # remote service and resources.
188
+ def http
189
+ http = Net::HTTP.new(@site.host, @site.port)
190
+ http.use_ssl = @site.is_a?(URI::HTTPS)
191
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl
192
+ http
193
+ end
194
+
195
+ def default_header
196
+ @default_header ||= { 'Content-Type' => format.mime_type }
197
+ end
198
+
199
+ # Builds headers for request to remote service.
200
+ def build_request_headers(headers)
201
+ headers.merge!({"From"=>surrogate}) if @surrogate
202
+ authorization_header.update(default_header).update(headers)
203
+ end
204
+
205
+ # Sets authorization header; authentication information is pulled from credentials provided with site URI.
206
+ def authorization_header
207
+ (@site.user || @site.password ? { 'Authorization' => 'Basic ' + ["#{@site.user}:#{ @site.password}"].pack('m').delete("\r\n") } : {})
208
+ end
239
209
  end
240
210
  end