class Klient::Resource

Attributes

arguments[RW]
collection_accessor[R]
id[R]
identifier[R]
mapping[R]
resource_type[RW]
type[RW]
url_template[R]
collection_accessor[R]
header_proc[R]
headers[R]
id[R]
last_response[R]
parent[R]
root[R]
status[R]
url[R]
url_arguments[R]
url_template[R]

Public Class Methods

new(parent) click to toggle source
# File lib/klient/resource.rb, line 15
def initialize(parent)
  @root = parent.root
  @header_proc = parent.header_proc
  @regexp = /#{self.class.name.demodulize.underscore.gsub(/(_|-|\s+)/, "(_|-|\s*)")}/i
  @id = self.class.try(:id)
  @collection_accessor = @identifier = self.class.try(:identifier)

  if @id
    @url_arguments = {@id => @identifier}
  else
    @url_arguments = {}
  end

  @parent = parent
  @headers = {}

  @url_template = Addressable::Template.new(
    @parent.url + self.class.url_template.pattern
  )
end

Public Instance Methods

inspect() click to toggle source
# File lib/klient/resource.rb, line 36
def inspect
  "#<#{self.class.name}:#{object_id} @url=#{self.url.inspect} @status_code=#{self.last_response.try(:status) || 'nil'}>"
end

Private Instance Methods

method_missing(mth, *args, &block) click to toggle source
# File lib/klient/resource.rb, line 106
def method_missing(mth, *args, &block)
  if @parsed_body.respond_to?(mth)
    @parsed_body.send(mth, *args, &block)
  else
    @last_response.send(mth, *args, &block)
  end
end
process_doc(doc) click to toggle source

Assumes JSON for the moment.

# File lib/klient/resource.rb, line 96
def process_doc(doc)
  if doc.is_a?(Hash)
    doc.to_json
  elsif doc.empty?
    {}.to_json
  else
    doc
  end
end
process_response(resp) click to toggle source

EXPERIMENTAL (USING HASH MODS)

# File lib/klient/resource.rb, line 115
def process_response(resp)
  parsed = JSON.parse(resp.body)#.to_data

  klass_type = self.class.resource_type

  if klass_type == self.class
    klass = self.class.new(parent)
  else
    klass = self.class.resource_type.new(@root)
  end

  if klass_type != self.class
    if match = klass.url_template.match(resp.request.args[:url])
      klass.url_arguments[klass.id] = match.mapping.with_indifferent_access[klass.id]
    end
  else
    if match = self.url_template.match(resp.request.args[:url])
      klass.url_arguments[klass.id] = match.mapping.with_indifferent_access[klass.id]
    end
  end

  if klass.url_arguments[klass.id]
    klass.url_arguments[klass.id]= parsed[klass.id]
    klass.instance_variable_set(:@last_response, Response.new(resp))
    return klass
  elsif key = parsed.keys.find { |k| k.to_s =~ @regexp }
    if parsed[key].is_a?(Array)
      arr = parsed[key].map! do |res|
        tmp = klass_type.new(@root)
        # TODO: Ugly. Revisit after recursive lookup.
        tmp.url_arguments[klass.id]= res.send(klass.id) || res.send(klass.collection_accessor).try(klass.id)

        processed = Response.new(resp, res)
        tmp.instance_variable_set(:@last_response, processed)

        tmp.instance_variable_set(:@parsed_body, processed.parsed_body)
        tmp.instance_variable_set(:@status, processed.status)
        tmp
      end
      return Klient::ResourceCollection.new(arr)
    else
      klass.url_arguments[klass.id]= parsed.send(klass.id) if klass.id
      klass.instance_variable_set(:@last_response, Response.new(resp))
      return klass
    end
  elsif self.class.type == :resource
    klass.url_arguments[klass.id]= parsed.send(klass.id) if klass.id
    klass.instance_variable_set(:@last_response, Response.new(resp))
    return klass
  elsif klass.url_arguments[klass.id]
    klass.url_arguments[klass.id]= parsed.send(klass.id)
    klass.instance_variable_set(:@last_response, Response.new(resp))
    return klass
  else
    if parsed.is_a?(Array)
      arr = parsed
    elsif parsed.keys.length == 1 && parsed[parsed.keys.first].is_a?(Array)
      arr = parsed[parsed.keys.first]
    elsif x = parsed.keys.find { |k| parsed[k].is_a?(Array) && parsed[k].first && parsed[k].first.send(klass.id.to_sym) }
      arr = parsed[x]
    elsif %w(post put).include?(resp.request.method)
      klass.url_arguments[klass.id]= parsed[klass.id]
      klass.instance_variable_set(:@last_response, Response.new(resp))
      return klass
    else
      raise "Unhandled condition."
    end

    arr.map! do |res|
      tmp = klass_type.new(@root)
      # TODO: Ugly. Revisit after recursive lookup.
      tmp.url_arguments[klass.id]= res.send(klass.id) || res.send(klass.collection_accessor).try(klass.id)

      processed = Response.new(resp, res)
      tmp.instance_variable_set(:@last_response, processed)

      tmp.instance_variable_set(:@parsed_body, processed.parsed_body)
      tmp.instance_variable_set(:@status, processed.status)
      tmp
    end

    return Klient::ResourceCollection.new(arr)
  end
end