ruby-fedora 0.1.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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