Class: OpenURL::Transport

Inherits:
Object
  • Object
show all
Defined in:
lib/openurl/transport.rb

Overview

The Transport class is intended to be used to deliver ContextObject objects to an OpenURL enabled host. Currently only HTTP is supported.

Usage: require ‘openurl’

include OpenURL context_object = ContextObject.new_from_kev(‘ctx_enc=info%3Aofi%2Fenc%3AUTF-8&ctx_ver=Z39.88-2004&rft.genre=article&rft_id=info%3Adoi%2F10.1016%2Fj.ipm.2005.03.024&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Aarticle&url_ctx_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Actx&url_ver=Z39.88-2004’) transport = Transport.new(‘demo.exlibrisgroup.com:9003/lr_3’, context_object) transport.get puts tranport.response

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target_base_url, contextobject = nil, http_arguments = {}) ⇒ Transport

Creates the transport object which can be used to initiate subsequent requests. The contextobject argument can be an OpenURL ContextObject object, and array of ContextObjects or nil. http_arguments set the Net::HTTP attributes: :read_timeout=>5, etc.



26
27
28
29
30
31
32
33
34
35
# File 'lib/openurl/transport.rb', line 26

def initialize(target_base_url, contextobject=nil, http_arguments={})      
	@uri = URI.parse(target_base_url)
	@context_objects = []
    self.add_context_object(contextobject) if contextobject
	@url_ver = "Z39.88-2004"			
	@extra_args = {}      
    @client = Net::HTTP.new(@uri.host, @uri.port)
    @client.open_timeout = (http_arguments[:open_timeout]||3)
    @client.read_timeout = (http_arguments[:read_timeout]||5)
end

Instance Attribute Details

#codeObject (readonly)

Returns the value of attribute code.



19
20
21
# File 'lib/openurl/transport.rb', line 19

def code
  @code
end

#context_objectsObject (readonly)

Returns the value of attribute context_objects.



19
20
21
# File 'lib/openurl/transport.rb', line 19

def context_objects
  @context_objects
end

#ctx_idObject

Returns the value of attribute ctx_id.



18
19
20
# File 'lib/openurl/transport.rb', line 18

def ctx_id
  @ctx_id
end

#extra_argsObject

Returns the value of attribute extra_args.



18
19
20
# File 'lib/openurl/transport.rb', line 18

def extra_args
  @extra_args
end

#messageObject (readonly)

Returns the value of attribute message.



19
20
21
# File 'lib/openurl/transport.rb', line 19

def message
  @message
end

#request_stringObject (readonly)

Returns the value of attribute request_string.



19
20
21
# File 'lib/openurl/transport.rb', line 19

def request_string
  @request_string
end

#responseObject (readonly)

Returns the value of attribute response.



19
20
21
# File 'lib/openurl/transport.rb', line 19

def response
  @response
end

Instance Method Details

#add_context_object(contextobject) ⇒ Object

Can take either an OpenURL::ContextObject or an array of ContextObjects to send to the Transport target



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/openurl/transport.rb', line 40

def add_context_object(contextobject)
    
    if contextobject.is_a?(OpenURL::ContextObject)
      @context_objects << contextobject
    elsif contextobject.is_a?(Array)
      contextobject.each do | co |
        raise ArgumentError, "Each element in array much be an OpenURL::ContextObject!" unless co.is_a?(OpenURL::ContextObject)          
        @context_objects << co
      end      
    else 
      raise ArgumentError, "Argument must be a ContextObject or array of ContextObjects!, #{contextobject.class} sent."        
    end      	
end

#get(idx = 0) ⇒ Object

Perform an inline HTTP GET request. Only one context object can be sent via GET, so pass the index of the desired context object (defaults to the first)



70
71
72
# File 'lib/openurl/transport.rb', line 70

def get(idx=0)           
  self.parse_response(@client.get( self.get_path(idx)  ))      
end

#get_path(idx = 0) ⇒ Object

useful for debugging to have this factored out



75
76
77
78
79
80
81
# File 'lib/openurl/transport.rb', line 75

def get_path(idx=0)
  extra = ""
  @extra_args.each do | key, val |        
    extra << "&#{key}=#{val}"
  end
  return "#{@uri.path}?#{@context_objects[idx].kev}#{extra}"
end

#merge_context_objectsObject

For a multiple context object request, takes the first context object in the context_objects attribute, and adds the other context objects to it, under /ctx:context-objects/ctx:context-object and serializes it all as XML. Returns a string of the XML document



132
133
134
135
136
137
138
139
140
141
142
# File 'lib/openurl/transport.rb', line 132

def merge_context_objects
  ctx_doc = REXML::Document.new(@context_objects[0].xml)
  root = ctx_doc.root
  @context_objects.each do | ctx |
    next if @context_objects.index(ctx) == 0
    c_doc = REXML::Document.new(ctx.xml)
    c_elm = c_doc.elements['ctx:context-objects/ctx:context-object']
    root.add_element(c_elm)
  end      
  return ctx_doc.to_s
end

#post(args = {}) ⇒ Object

POSTs an HTTP request to the transport target. To send an inline request, include a hash that looks like: :index=>n (:index defaults to 0. Transport.post must be used to send multiple context objects to a target.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/openurl/transport.rb', line 106

def post(args={})
  # Inline requests send the context object as a hash
  if args[:inline]
    self.parse_response(self.post_http(@context_objects[(args[:index]||0)].to_hash.merge(@extra_args.merge({"url_ctx_fmt"=>"info:ofi/fmt:kev:mtx:ctx"}))))        
    return
  end            
  ctx_hash = {"url_ctx_fmt" => "info:ofi/fmt:xml:xsd:ctx"}
  # If we're only sending one context object, use that, otherwise concatenate
  # them.
  if @context_objects.length == 1
    ctx_hash["url_ctx_val"] = @context_objects[0].xml
  else
    ctx_hash["url_ctx_val"] = self.merge_context_objects
  end
  @context_objects[0].admin.each do | key, hsh |
    ctx_hash[key] = hsh["value"]
  end         
  
  self.parse_response(self.post_http(ctx_hash.merge(@extra_args)))      
end

#remove_context_object(element) ⇒ Object

Accepts either a ContextObject or array index to remove from array being sent to the Transport target



57
58
59
60
61
62
63
64
# File 'lib/openurl/transport.rb', line 57

def remove_context_object(element)
   idx = case element.class
   when Fixnum then element
   when OpenURL::ContextObject then @context_objects.index(element)
   else raise ArgumentError, "Invalid argument for element"
   end
   @context_objects.delete_at(idx)
end

#transport_by_ref(fmt, ref, method = "GET") ⇒ Object

Deprecated. Set by-reference in OpenURL::ContextObject and use .get or .post



147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/openurl/transport.rb', line 147

def transport_by_ref(fmt, ref, method="GET")
	md = "url_ver=Z39.88-2004&url_ctx_fmt="+CGI.escape(fmt)+"&url_tim="+CGI.escape(DateTime.now().to_s)
	if method == "GET"  	
     parse.response(@client.get("#{@uri.path}?#{md}&url_ctx_ref="+CGI.escape(ref)))
	else
		args = {"url_ver"=>"Z39.88-2004",
       "url_ctx_fmt"=>fmt,
       "url_tim"=>DateTime.now().to_s,
       "url_ctx_ref" => ref}  			
		args = args.merge(@extra_args) unless @extra_args.empty?
			  			
		self.parse_response(self.post_http(args))
	end
end

#transport_by_val(method = "POST", idx = 0) ⇒ Object

Sends an by-value transport request. YOu can specify which HTTP method to use. Since a GET request is effectively the same as an inline request, the index of which context object must be specified (defaults to 0).



96
97
98
99
# File 'lib/openurl/transport.rb', line 96

def transport_by_val(method="POST", idx=0)
    return(self.get(idx)) if method=="GET"
    return(self.post) if method=="POST"	
end

#transport_inline(method = "GET", idx = 0) ⇒ Object

Sends an inline transport request. YOu can specify which HTTP method to use. Since you can only send one context object per inline request, the second argument is the index of the desired context object.



87
88
89
90
# File 'lib/openurl/transport.rb', line 87

def transport_inline(method="GET", idx=0)
  return(self.get(idx)) if method=="GET"
  return(self.post({:inline=>true, :index=>idx})) if method=="POST"
end