class AWS::Core::XmlGrammar

@private

Constants

DATE_PUNCTUATION
EASY_FORMAT
TRANSLATE_DIGITS

Public Class Methods

add_method(method_name, &block) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 162
      def add_method method_name, &block
        format_value do |value|
          MetaUtils.extend_method(value = super(value), method_name, &block)
          value
        end
#           different strategey, slightly different behavior
#           element(method_name.to_s) do
#             format_value(&block)
#             force
#           end
      end
blob() click to toggle source
Alias for: blob_value
blob_value() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 266
def blob_value
  format_value do |value|
    value = super(value)
    Base64.decode64(value) if value
  end
end
Also aliased as: blob
boolean() click to toggle source

required by the hash configuration method

Alias for: boolean_value
boolean_value() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 199
def boolean_value
  @current[:boolean] = true
  format_value {|value| super(value) == 'true' }
end
Also aliased as: boolean
collect_values() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 186
def collect_values
  @current[:collected] = true
  @current[:initial_collection] = lambda { [] }
  @current[:add_to_collection] =
    lambda { |ary, val| ary << val }
  force
end
construct_value(&block) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 333
def construct_value &block
  @current[:construct_value] = block
end
customize(config = nil, &block) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 150
def customize config = nil, &block
  grammar = Class.new(self)
  grammar.customizations = customizations.deep_copy
  grammar.config_eval(config) if config
  grammar.module_eval(&block) if block_given?
  grammar
end
datetime_like_value(klass, parts_constructor) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 219
def datetime_like_value(klass, parts_constructor)
  format_value do |value|
    value = super(value)
    if value and value.tr(*TRANSLATE_DIGITS) == EASY_FORMAT
  
      # it's way faster to parse this specific format manually
      # vs. DateTime#parse, and this happens to be the format
      # that AWS uses almost (??) everywhere.
  
      parts = value.tr(*DATE_PUNCTUATION).
        chop.split.map { |elem| elem.to_i }
      klass.send(parts_constructor, *parts)
    elsif value
      # fallback in case we have to handle another date format
      klass.parse(value)
    else
      nil
    end
  end
end
datetime_value() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 210
def datetime_value
  datetime_like_value(DateTime, :civil)
end
element(element_name, &block) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 158
def element element_name, &block
  eval_customization_context(element_name, &block)
end
eql?(other) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 337
def eql? other
  self.customizations == other.customizations
end
float() click to toggle source
Alias for: float_value
float_value() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 250
def float_value
  format_value do |value|
    value = super(value)
    value.nil? ? nil : value.to_f
  end
end
Also aliased as: float
force() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 182
def force
  @current[:forced] = true
end
format_value(&block) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 274
def format_value &block
  @current[:value_formatter] ||= ValueFormatter.new
  @current[:value_formatter].extend_format_value(&block)
end
ignore() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 174
def ignore
  @current[:ignored] = true
end
index(name, &block) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 194
def index(name, &block)
  (@customizations[:index_names] ||= []) << name
  @current[:indexed] = [name, block]
end
integer() click to toggle source

required by the hash configuration method

Alias for: integer_value
integer_value() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 240
def integer_value
  format_value do |value|
    value = super(value)
    value.nil? ? nil : value.to_i
  end
end
Also aliased as: integer, long
list(child_element_name = nil) { || ... } click to toggle source
# File lib/aws/core/xml_grammar.rb, line 279
def list child_element_name = nil, &block
  if child_element_name
    ignore
    parent_element_name = @current_name
    element(child_element_name) do
      rename(parent_element_name)
      collect_values
      yield if block_given?
    end
  else
    collect_values
  end
end
long() click to toggle source
Alias for: integer_value
map(entry_name, key, value) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 303
def map entry_name, key, value
  parent_element_name = @current_name
  ignore
  element(entry_name) do
    rename(parent_element_name)
    map_entry(key, value)
  end
end
map_entry(key, value) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 293
def map_entry(key, value)
  collect_values
  element(key) { rename :key }
  element(value) { rename :value }
  @current[:initial_collection] = lambda { {} }
  @current[:add_to_collection] = lambda do |hash, entry|
    hash[entry.key] = entry.value
  end
end
parse(xml, options = {}) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 127
def parse xml, options = {}
  
  context = options[:context] || Context.new
  
  if defined? Nokogiri
    parser = Parser.new(context, customizations)
    parser.extend(NokogiriAdapter)
    xml = "<foo/>" if xml.empty?
    Nokogiri::XML::SAX::Parser.new(parser).parse(xml.strip)
  else
    parser = Parser.new(context, customizations)
    parser.extend(REXMLSaxParserAdapter)
    REXML::Parsers::StreamParser.new(REXML::Source.new(xml), parser).parse
  end
  
  context
  
end
rename(new_name) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 178
def rename new_name
  @current[:renamed] = new_name.to_s
end
simulate(context = nil) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 146
def simulate context = nil
  StubResponse.new(customizations, context)
end
symbol_value() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 259
def symbol_value
  format_value do |value|
    value = super(value)
    ['', nil].include?(value) ? nil : Inflection.ruby_name(value).to_sym
  end
end
time_value() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 214
def time_value
  datetime_like_value(Time, :utc)
end
Also aliased as: timestamp
timestamp() click to toggle source
Alias for: time_value
wrapper(method_name, options = {}) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 312
def wrapper method_name, options = {}, &blk
  if block_given?
    customizations =
      eval_customization_context(method_name,
                                 CustomizationContext.new(method_name),
                                 &blk)
    raise NotImplementedError.new("can't customize wrapped " +
                                  "elements within the wrapper") unless
      customizations[:children].empty?
    @current[:wrapper_frames] ||= {}
    @current[:wrapper_frames][method_name] = customizations
  end
  
  (options[:for] || []).each do |element_name|
    element element_name do
      @current[:wrapper] ||= []
      @current[:wrapper] << method_name
    end
  end
end

Protected Class Methods

config_eval(config) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 369
def config_eval(config)
  config.each do |item|
    (type, identifier, args) = parse_config_item(item)
    case type
    when :method
      validate_config_method(identifier)
      validate_args(identifier, args)
      send(identifier, *args)
    when :element
      element(identifier) do
        config_eval(args)
      end
    end
  end
end
customizations() click to toggle source
# File lib/aws/core/xml_grammar.rb, line 425
def customizations
  @customizations ||= CustomizationContext.new
end
customizations=(customizations) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 441
def customizations= customizations
  @customizations = customizations
  @current = customizations
end
customizations_for(element_name) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 430
def customizations_for element_name
  if @parent
    @parent[:children][element_name] ||=
      CustomizationContext.new(element_name)
  else
    customizations[:children][element_name] ||=
      CustomizationContext.new(element_name)
  end
end
eval_customization_context(name, initial = nil) { || ... } click to toggle source
# File lib/aws/core/xml_grammar.rb, line 347
def eval_customization_context name, initial = nil, &block
  current_name = @current_name
  current = @current
  parent = @parent
  begin
    @current_name = name
    @parent = @current
    initial ||= customizations_for(name)
    @current = initial
    yield if block_given?
  ensure
    @current_name = current_name
    @current = current
    @parent = parent
  end
  
  # will be modified to include the customizations defined in
  # the block
  initial
end
initial_customizations(element_name = nil) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 342
def initial_customizations(element_name = nil)
  CustomizationContext.new(element_name)
end
parse_config_item(item) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 398
def parse_config_item(item)
  case item
  when Symbol
    [:method, item, []]
  when Hash
    (method, arg) = item.to_a.first
    if method.kind_of?(Symbol)
      [:method, method, [arg].flatten]
    else
      [:element, method, arg]
    end
  end
end
validate_args(identifier, args) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 386
def validate_args(identifier, args)
  arity = method(identifier).arity
  if args.length > 0
    raise "#{identifier} does not accept an argument" if
      arity == 0
  else
    raise "#{identifier} requires an argument" unless
      arity == 0 || arity == -1
  end
end
validate_config_method(method) click to toggle source
# File lib/aws/core/xml_grammar.rb, line 413
def validate_config_method(method)
  allow_methods = %w(
    rename attribute_name boolean integer long float list force
    ignore collect_values symbol_value timestamp map_entry map
    blob
  )
  unless allow_methods.include?(method.to_s)
    raise "#{method} cannot be used in configuration"
  end
end