class Sinatra::Soap::Param

Attributes

map[RW]
multiplied[RW]
name[RW]
raw_name[RW]
source_class[RW]
type[RW]
value[RW]

Public Class Methods

new(name, type, multiplied = false) click to toggle source
# File lib/sinatra/soap/param.rb, line 12
def initialize(name, type, multiplied = false)
  type ||= {}
  @name       = name.to_s
  @raw_name   = name.to_s
  @map        = {}
  @multiplied = multiplied

  if type.is_a?(Symbol)
    @type = type.to_s
  elsif type.is_a?(Class)
    @type         = 'struct'
    @source_class = type
    @map          = type
  else
    @type = 'struct'
    @map  = type 
  end
end
parse_def(soap_config, definition) click to toggle source

Parses a definition. The format of the definition is best described by the following BNF-like grammar.

simple_type := :string | :integer | :double | :boolean
nested_type := type_hash | simple_type | WashOut::Param instance
type_hash   := { :parameter_name => nested_type, ... }
definition  := [ WashOut::Param, ... ] |
               type_hash |
               simple_type

If a simple type is passed as the definition, a single Param is returned with the name set to “value”. If a WashOut::Param instance is passed as a nested_type, the corresponding :parameter_name is ignored.

This function returns an array of WashOut::Param objects.

# File lib/sinatra/soap/param.rb, line 125
def self.parse_def(soap_config, definition)
  raise RuntimeError, "[] should not be used in your params. Use nil if you want to mark empty set." if definition == []
  return [] if definition == nil

  if definition.is_a?(Class) && definition.ancestors.include?(WashOut::Type)
    definition = definition.wash_out_param_map
  end

  if [Array, Symbol].include?(definition.class)
    definition = { :value => definition }
  end

  if definition.is_a? Hash
    definition.map do |name, opt|
      if opt.is_a? WashOut::Param
        opt
      elsif opt.is_a? Array
        WashOut::Param.new(soap_config, name, opt[0], true)
      else
        WashOut::Param.new(soap_config, name, opt)
      end
    end
  else
    raise RuntimeError, "Wrong definition: #{definition.inspect}"
  end
end

Public Instance Methods

basic_type() click to toggle source
# File lib/sinatra/soap/param.rb, line 93
def basic_type
  return name unless classified?
  return source_class.wash_out_param_name(@soap_config)
end
classified?() click to toggle source
# File lib/sinatra/soap/param.rb, line 89
def classified?
  !source_class.nil?
end
flat_copy() click to toggle source
# File lib/sinatra/soap/param.rb, line 152
def flat_copy
  copy = self.class.new(@soap_config, @name, @type.to_sym, @multiplied)
  copy.raw_name = raw_name
  copy.source_class = copy.source_class
  copy
end
load(data, key) click to toggle source

Converts a generic externally derived Ruby value, such as String or Hash, to a native Ruby object according to the definition of this type.

# File lib/sinatra/soap/param.rb, line 33
def load(data, key)
  if !data.has_key? key
    raise Error, "Required SOAP parameter '#{key}' is missing"
  end

  data = data[key]
  data = [data] if @multiplied && !data.is_a?(Array)

  if struct?
    data ||= {}
    if @multiplied
      data.map do |x|
        map_struct x do |param, dat, elem|
          param.load(dat, elem)
        end
      end
    else
      map_struct data do |param, dat, elem|
        param.load(dat, elem)
      end
    end
  else
    operation = case type
      when 'string';       :to_s
      when 'integer';      :to_i
      when 'double';       :to_f
      when 'boolean';      lambda{|dat| dat === "0" ? false : !!dat}
      when 'date';         :to_date
      when 'datetime';     :to_datetime
      when 'time';         :to_time
      when 'base64Binary'; lambda{|dat| Base64.decode64(dat)}
      else raise RuntimeError, "Invalid WashOut simple type: #{type}"
    end

    begin
      if data.nil?
        data
      elsif @multiplied
        return data.map{|x| x.send(operation)} if operation.is_a?(Symbol)
        return data.map{|x| operation.call(x)} if operation.is_a?(Proc)
      elsif operation.is_a? Symbol
        data.send(operation)
      else
        operation.call(data)
      end
    rescue
      raise Error, "Invalid SOAP parameter '#{key}' format"
    end
  end
end
namespaced_type() click to toggle source

Returns a WSDL namespaced identifier for this type.

# File lib/sinatra/soap/param.rb, line 105
def namespaced_type
  struct? ? "tns:#{basic_type}" : "xsd:#{xsd_type}"
end
struct?() click to toggle source

Checks if this Param defines a complex type.

# File lib/sinatra/soap/param.rb, line 85
def struct?
  type == 'struct'
end
xsd_type() click to toggle source
# File lib/sinatra/soap/param.rb, line 98
def xsd_type
  return 'int' if type.to_s == 'integer'
  return 'dateTime' if type.to_s == 'datetime'
  return type
end

Private Instance Methods

map_struct(data) { |param, data, raw_name| ... } click to toggle source

Used to load an entire structure.

# File lib/sinatra/soap/param.rb, line 162
def map_struct(data)
  unless data.is_a?(Hash)
    raise Error, "SOAP message structure is broken"
  end

  data   = data.with_indifferent_access
  struct = {}.with_indifferent_access

  # RUBY18 Enumerable#each_with_object is better, but 1.9 only.
  @map.map do |param|
    if data.has_key? param.raw_name
      struct[param.raw_name] = yield param, data, param.raw_name
    end
  end

  struct
end