123456789_123456789_123456789_123456789_123456789_

Class: RSS::Element

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
self, SetupMaker, Utils
Inherits: Object
Defined in: lib/rss/rss.rb

Constant Summary

Class Attribute Summary

Class Method Summary

Utils::InheritedReader - Extended

BaseModel - Extended

Utils - Included

element_initialize_arguments?

This method is used inside of several different objects to determine if special behavior is needed in the constructor.

get_file_and_line_from_caller

Returns an array of two elements: the filename where the calling method is located, and the line number where it is defined.

h,
html_escape

Takes a string s with some HTML in it, and escapes ‘&’, ‘“’, ‘<’ and ‘>’, by replacing them with the appropriate entities.

new_with_value_if_need

If value is an instance of class klass, return it, else create a new instance of klass with value value.

to_class_name

Given a name in a name_with_underscores or a name-with-dashes format, returns the CamelCase version of name.

Instance Attribute Summary

Instance Method Summary

SetupMaker - Included

Utils - Included

#element_initialize_arguments?

This method is used inside of several different objects to determine if special behavior is needed in the constructor.

#get_file_and_line_from_caller

Returns an array of two elements: the filename where the calling method is located, and the line number where it is defined.

#h,
#html_escape

Takes a string s with some HTML in it, and escapes ‘&’, ‘“’, ‘<’ and ‘>’, by replacing them with the appropriate entities.

#new_with_value_if_need

If value is an instance of class klass, return it, else create a new instance of klass with value value.

#to_class_name

Given a name in a name_with_underscores or a name-with-dashes format, returns the CamelCase version of name.

Constructor Details

.new(do_validate = true, attrs = nil) ⇒ Element

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 850

def initialize(do_validate=true, attrs=nil)
  @parent = nil
  @converter = nil
  if attrs.nil? and (do_validate.is_a?(Hash) or do_validate.is_a?(Array))
    do_validate, attrs = true, do_validate
  end
  @do_validate = do_validate
  initialize_variables(attrs || {})
end

Class Attribute Details

.have_content?Boolean (readonly)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 804

def have_content?
  @have_content
end

.need_parent?Boolean (readonly)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 832

def need_parent?
  false
end

Class Method Details

.add_have_children_element(variable_name, plural_name)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 808

def add_have_children_element(variable_name, plural_name)
  self::HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]
end

.add_need_initialize_variable(variable_name)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 816

def add_need_initialize_variable(variable_name)
  self::NEED_INITIALIZE_VARIABLES << variable_name
end

.add_plural_form(singular, plural)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 820

def add_plural_form(singular, plural)
  self::PLURAL_FORMS[singular] = plural
end

.add_to_element_method(method_name)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 812

def add_to_element_method(method_name)
  self::TO_ELEMENT_METHODS << method_name
end

.content_setup(type = nil, disp_name = nil)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 797

def content_setup(type=nil, disp_name=nil)
  writer_type, reader_type = type
  def_corresponded_attr_writer :content, writer_type, disp_name
  def_corresponded_attr_reader :content, reader_type
  @have_content = true
end

.def_corresponded_attr_reader(name, type = nil)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 778

def def_corresponded_attr_reader(name, type=nil)
  case type
  when :inherit
    inherit_convert_attr_reader name
  when :uri
    uri_convert_attr_reader name
  when :explicit_clean_other
    explicit_clean_other_attr_reader name
  when :yes_other
    yes_other_attr_reader name
  when :csv
    csv_attr_reader name
  when :csv_integer
    csv_attr_reader name, :separator => ","
  else
    convert_attr_reader name
  end
end

.def_corresponded_attr_writer(name, type = nil, disp_name = nil)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 750

def def_corresponded_attr_writer(name, type=nil, disp_name=nil)
  disp_name ||= name
  case type
  when :integer
    integer_writer name, disp_name
  when :positive_integer
    positive_integer_writer name, disp_name
  when :boolean
    boolean_writer name, disp_name
  when :w3cdtf, :rfc822, :rfc2822
    date_writer name, type, disp_name
  when :text_type
    text_type_writer name, disp_name
  when :content
    content_writer name, disp_name
  when :explicit_clean_other
    explicit_clean_other_writer name, disp_name
  when :yes_other
    yes_other_writer name, disp_name
  when :csv
    csv_writer name
  when :csv_integer
    csv_integer_writer name
  else
    attr_writer name
  end
end

.get_attributes

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 687

def get_attributes
  inherited_array_reader("GET_ATTRIBUTES")
end

.have_children_elements

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 690

def have_children_elements
  inherited_array_reader("HAVE_CHILDREN_ELEMENTS")
end

.inherited(klass)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 707

def inherited(klass)
  klass.const_set(:MUST_CALL_VALIDATORS, {})
  klass.const_set(:MODELS, [])
  klass.const_set(:GET_ATTRIBUTES, [])
  klass.const_set(:HAVE_CHILDREN_ELEMENTS, [])
  klass.const_set(:TO_ELEMENT_METHODS, [])
  klass.const_set(:NEED_INITIALIZE_VARIABLES, [])
  klass.const_set(:PLURAL_FORMS, {})

  tag_name = klass.name.split(/::/).last
  tag_name[0, 1] = tag_name[0, 1].downcase
  klass.instance_variable_set(:@tag_name, tag_name)
  klass.instance_variable_set(:@have_content, false)
end

.inherited_base

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 703

def inherited_base
  ::RSS::Element
end

.install_get_attribute(name, uri, required = true, type = nil, disp_name = nil, element_name = nil)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 735

def install_get_attribute(name, uri, required=true,
                          type=nil, disp_name=nil,
                          element_name=nil)
  disp_name ||= name
  element_name ||= name
  writer_type, reader_type = type
  def_corresponded_attr_writer name, writer_type, disp_name
  def_corresponded_attr_reader name, reader_type
  if type == :boolean and /^is/ =~ name
    alias_method "#{$POSTMATCH}?", name
  end
  self::GET_ATTRIBUTES << [name, uri, required, element_name]
  add_need_initialize_variable(disp_name)
end

.install_model(tag, uri, occurs = nil, getter = nil, plural = false)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 726

def install_model(tag, uri, occurs=nil, getter=nil, plural=false)
  getter ||= tag
  if m = self::MODELS.find {|t, u, o, g, p| t == tag and u == uri}
    m[2] = occurs
  else
    self::MODELS << [tag, uri, occurs, getter, plural]
  end
end

.install_must_call_validator(prefix, uri)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 722

def install_must_call_validator(prefix, uri)
  self::MUST_CALL_VALIDATORS[uri] = prefix
end

.install_ns(prefix, uri)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 836

def install_ns(prefix, uri)
  if self::NSPOOL.has_key?(prefix)
    raise OverlappedPrefixError.new(prefix)
  end
  self::NSPOOL[prefix] = uri
end

.models

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 684

def models
  inherited_array_reader("MODELS")
end

.must_call_validators

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 681

def must_call_validators
  inherited_hash_reader("MUST_CALL_VALIDATORS")
end

.need_initialize_variables

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 696

def need_initialize_variables
  inherited_array_reader("NEED_INITIALIZE_VARIABLES")
end

.plural_forms

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 699

def plural_forms
  inherited_hash_reader("PLURAL_FORMS")
end

.required_prefix

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 824

def required_prefix
  nil
end

.required_uri

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 828

def required_uri
  ""
end

.tag_name

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 843

def tag_name
  @tag_name
end

.to_element_methods

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 693

def to_element_methods
  inherited_array_reader("TO_ELEMENT_METHODS")
end

Instance Attribute Details

#content_is_set?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1224

def content_is_set?
  if have_xml_content?
    __send__(self.class.xml_getter)
  else
    content
  end
end

#converter=(converter) (writeonly)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 868

def converter=(converter)
  @converter = converter
  targets = children.dup
  self.class.have_children_elements.each do |variable_name, plural_name|
    targets.concat(__send__(plural_name))
  end
  targets.each do |target|
    target.converter = converter unless target.nil?
  end
end

#do_validate (rw)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 848

attr_accessor :parent, :do_validate

#empty_content?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1220

def empty_content?
  false
end

#have_required_elements?Boolean (readonly, protected)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 951

def have_required_elements?
  self.class::MODELS.all? do |tag, uri, occurs, getter|
    if occurs.nil? or occurs == "+"
      child = __send__(getter)
      if child.is_a?(Array)
        children = child
        children.any? {|c| c.have_required_elements?}
      else
        not child.nil?
      end
    else
      true
    end
  end
end

#have_xml_content?Boolean (readonly)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 929

def have_xml_content?
  false
end

#need_base64_encode?Boolean (readonly)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 933

def need_base64_encode?
  false
end

#parent (rw)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 848

attr_accessor :parent, :do_validate

Instance Method Details

#__validate(ignore_unknown_element, tags = _tags, recursive = true) (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1090

def __validate(ignore_unknown_element, tags=_tags, recursive=true)
  if recursive
    children.compact.each do |child|
      child.validate
    end
  end
  must_call_validators = self.class.must_call_validators
  tags = tag_filter(tags.dup)
  p tags if DEBUG
  must_call_validators.each do |uri, prefix|
    _validate(ignore_unknown_element, tags[uri], uri)
    meth = "#{prefix}_validate"
    if !prefix.empty? and respond_to?(meth, true)
      __send__(meth, ignore_unknown_element, tags[uri], uri)
    end
  end
end

#_attrs (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1084

def _attrs
  self.class.get_attributes.collect do |name, uri, required, element_name|
    [element_name, required, name]
  end
end

#_tags (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1070

def _tags
  rv = []
  self.class.models.each do |name, uri, occurs, getter, plural|
    value = __send__(getter)
    next if value.nil?
    if plural and value.is_a?(Array)
      rv.concat([[uri, name]] * value.size)
    else
      rv << [uri, name]
    end
  end
  rv
end

#_validate(ignore_unknown_element, tags, uri, models = self.class.models) (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1118

def _validate(ignore_unknown_element, tags, uri, models=self.class.models)
  count = 1
  do_redo = false
  not_shift = false
  tag = nil
  models = models.find_all {|model| model[1] == uri}
  element_names = models.collect {|model| model[0]}
  if tags
    tags_size = tags.size
    tags = tags.sort_by {|x| element_names.index(x) || tags_size}
  end

  models.each_with_index do |model, i|
    name, _, occurs, = model

    if DEBUG
      p "before"
      p tags
      p model
    end

    if not_shift
      not_shift = false
    elsif tags
      tag = tags.shift
    end

    if DEBUG
      p "mid"
      p count
    end

    case occurs
    when '?'
      if count > 2
        raise TooMuchTagError.new(name, tag_name)
      else
        if name == tag
          do_redo = true
        else
          not_shift = true
        end
      end
    when '*'
      if name == tag
        do_redo = true
      else
        not_shift = true
      end
    when '+'
      if name == tag
        do_redo = true
      else
        if count > 1
          not_shift = true
        else
          raise MissingTagError.new(name, tag_name)
        end
      end
    else
      if name == tag
        if models[i+1] and models[i+1][0] != name and
            tags and tags.first == name
          raise TooMuchTagError.new(name, tag_name)
        end
      else
        raise MissingTagError.new(name, tag_name)
      end
    end

    if DEBUG
      p "after"
      p not_shift
      p do_redo
      p tag
    end

    if do_redo
      do_redo = false
      count += 1
      redo
    else
      count = 1
    end

  end

  if !ignore_unknown_element and !tags.nil? and !tags.empty?
    raise NotExpectedTagError.new(tags.first, uri, tag_name)
  end

end

#calc_indent (private)

For backward compatibility

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1053

def calc_indent
  ''
end

#children (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1057

def children
  rv = []
  self.class.models.each do |name, uri, occurs, getter|
    value = __send__(getter)
    next if value.nil?
    value = [value] unless value.is_a?(Array)
    value.each do |v|
      rv << v if v.is_a?(Element)
    end
  end
  rv
end

#collect_attrs (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1036

def collect_attrs
  attrs = {}
  _attrs.each do |name, required, alias_name|
    value = __send__(alias_name || name)
    return nil if required and value.nil?
    next if value.nil?
    return nil if attrs.has_key?(name)
    attrs[name] = value
  end
  attrs
end

#convert(value)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 879

def convert(value)
  if @converter
    @converter.convert(value)
  else
    value
  end
end

#full_name

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 864

def full_name
  tag_name
end

#initialize_have_children_elements (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 985

def initialize_have_children_elements
  self.class.have_children_elements.each do |variable_name, plural_name|
    instance_variable_set("@#{variable_name}", [])
  end
end

#initialize_variables(attrs) (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 968

def initialize_variables(attrs)
  normalized_attrs = {}
  attrs.each do |key, value|
    normalized_attrs[key.to_s] = value
  end
  self.class.need_initialize_variables.each do |variable_name|
    value = normalized_attrs[variable_name.to_s]
    if value
      __send__("#{variable_name}=", value)
    else
      instance_variable_set("@#{variable_name}", nil)
    end
  end
  initialize_have_children_elements
  @content = normalized_attrs["content"] if self.class.have_content?
end

#make_start_tag(indent, next_indent, attrs) (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1026

def make_start_tag(indent, next_indent, attrs)
  start_tag = ["#{indent}<#{full_name}"]
  unless attrs.empty?
    start_tag << attrs.collect do |key, value|
      %Q[#{h key}="#{h value}"]
    end.join("\n#{next_indent}")
  end
  start_tag.join(" ")
end

#set_next_element(tag_name, next_element)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 937

def set_next_element(tag_name, next_element)
  klass = next_element.class
  prefix = ""
  prefix << "#{klass.required_prefix}_" if klass.required_prefix
  key = "#{prefix}#{tag_name.gsub(/-/, '_')}"
  if self.class.plural_forms.has_key?(key)
    ary = __send__("#{self.class.plural_forms[key]}")
    ary << next_element
  else
    __send__("#{key}=", next_element)
  end
end

#tag(indent, additional_attrs = {}, &block) (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 991

def tag(indent, additional_attrs={}, &block)
  next_indent = indent + INDENT

  attrs = collect_attrs
  return "" if attrs.nil?

  return "" unless have_required_elements?

  attrs.update(additional_attrs)
  start_tag = make_start_tag(indent, next_indent, attrs.dup)

  if block
    content = block.call(next_indent)
  else
    content = []
  end

  if content.is_a?(String)
    content = [content]
    start_tag << ">"
    end_tag = "</#{full_name}>"
  else
    content = content.reject{|x| x.empty?}
    if content.empty?
      return "" if attrs.empty?
      end_tag = "/>"
    else
      start_tag << ">\n"
      end_tag = "\n#{indent}</#{full_name}>"
    end
  end

  start_tag + content.join("\n") + end_tag
end

#tag_filter(tags) (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1211

def tag_filter(tags)
  rv = {}
  tags.each do |tag|
    rv[tag[0]] = [] unless rv.has_key?(tag[0])
    rv[tag[0]].push(tag[1])
  end
  rv
end

#tag_name

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 860

def tag_name
  self.class.tag_name
end

#tag_name_with_prefix(prefix) (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1048

def tag_name_with_prefix(prefix)
  "#{prefix}:#{tag_name}"
end

#to_s(need_convert = true, indent = '')

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 908

def to_s(need_convert=true, indent='')
  if self.class.have_content?
    return "" if !empty_content? and !content_is_set?
    rv = tag(indent) do |next_indent|
      if empty_content?
        ""
      else
        xmled_content
      end
    end
  else
    rv = tag(indent) do |next_indent|
      self.class.to_element_methods.collect do |method_name|
        __send__(method_name, false, next_indent)
      end
    end
  end
  rv = convert(rv) if need_convert
  rv
end

#valid?(ignore_unknown_element = true) ⇒ Boolean

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 887

def valid?(ignore_unknown_element=true)
  validate(ignore_unknown_element)
  true
rescue RSS::Error
  false
end

#validate(ignore_unknown_element = true)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 894

def validate(ignore_unknown_element=true)
  do_validate = @do_validate
  @do_validate = true
  validate_attribute
  __validate(ignore_unknown_element)
ensure
  @do_validate = do_validate
end

#validate_attribute (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1108

def validate_attribute
  _attrs.each do |a_name, required, alias_name|
    value = instance_variable_get("@#{alias_name || a_name}")
    if required and value.nil?
      raise MissingAttributeError.new(tag_name, a_name)
    end
    __send__("#{alias_name || a_name}=", value)
  end
end

#validate_for_stream(tags, ignore_unknown_element = true)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 903

def validate_for_stream(tags, ignore_unknown_element=true)
  validate_attribute
  __validate(ignore_unknown_element, tags, false)
end

#xmled_content (private)

[ GitHub ]

  
# File 'lib/rss/rss.rb', line 1232

def xmled_content
  if have_xml_content?
    __send__(self.class.xml_getter).to_s
  else
    _content = content
    _content = [_content].pack("m0") if need_base64_encode?
    h(_content)
  end
end