# class RSS::Element

### Constants

GET_ATTRIBUTES
HAVE_CHILDREN_ELEMENTS
INDENT
MODELS
MUST_CALL_VALIDATORS
NEED_INITIALIZE_VARIABLES
PLURAL_FORMS
TO_ELEMENT_METHODS

### Attributes

do_validate[RW]
parent[RW]

### Public Class Methods

add_have_children_element(variable_name, plural_name) click to toggle source

    # 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) click to toggle source

    # 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) click to toggle source

    # 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) click to toggle source

    # 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) click to toggle source

    # 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) click to toggle source

    # 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) click to toggle source

    # 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() click to toggle source

    # File lib/rss/rss.rb, line 687
    def get_attributes
      inherited_array_reader("GET_ATTRIBUTES")
    end

have_children_elements() click to toggle source

    # File lib/rss/rss.rb, line 690
    def have_children_elements
      inherited_array_reader("HAVE_CHILDREN_ELEMENTS")
    end

have_content?() click to toggle source

    # File lib/rss/rss.rb, line 804
    def have_content?
      @have_content
    end

inherited(klass) click to toggle source

    # 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() click to toggle source

    # 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) click to toggle source

    # 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) click to toggle source

    # 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) click to toggle source

    # 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) click to toggle source

    # 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() click to toggle source

    # File lib/rss/rss.rb, line 684
    def models
      inherited_array_reader("MODELS")
    end

must_call_validators() click to toggle source

    # File lib/rss/rss.rb, line 681
    def must_call_validators
      inherited_hash_reader("MUST_CALL_VALIDATORS")
    end

need_initialize_variables() click to toggle source

    # File lib/rss/rss.rb, line 696
    def need_initialize_variables
      inherited_array_reader("NEED_INITIALIZE_VARIABLES")
    end

need_parent?() click to toggle source

    # File lib/rss/rss.rb, line 832
    def need_parent?
      false
    end

new(do_validate=true, attrs=nil) click to toggle source

    # 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

plural_forms() click to toggle source

    # File lib/rss/rss.rb, line 699
    def plural_forms
      inherited_hash_reader("PLURAL_FORMS")
    end

required_prefix() click to toggle source

    # File lib/rss/rss.rb, line 824
    def required_prefix
      nil
    end

required_uri() click to toggle source

    # File lib/rss/rss.rb, line 828
    def required_uri
      ""
    end

tag_name() click to toggle source

    # File lib/rss/rss.rb, line 843
    def tag_name
      @tag_name
    end

to_element_methods() click to toggle source

    # File lib/rss/rss.rb, line 693
    def to_element_methods
      inherited_array_reader("TO_ELEMENT_METHODS")
    end

### Public Instance Methods

convert(value) click to toggle source

    # File lib/rss/rss.rb, line 879
    def convert(value)
      if @converter
        @converter.convert(value)
      else
        value
      end
    end

converter=(converter) click to toggle source

    # 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

full_name() click to toggle source

    # File lib/rss/rss.rb, line 864
    def full_name
      tag_name
    end

have_xml_content?() click to toggle source

    # File lib/rss/rss.rb, line 929
    def have_xml_content?
      false
    end

need_base64_encode?() click to toggle source

    # File lib/rss/rss.rb, line 933
    def need_base64_encode?
      false
    end

set_next_element(tag_name, next_element) click to toggle source

    # 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_name() click to toggle source

    # File lib/rss/rss.rb, line 860
    def tag_name
      self.class.tag_name
    end

to_s(need_convert=true, indent='') click to toggle source

    # 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) click to toggle source

    # 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) click to toggle source

    # 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_for_stream(tags, ignore_unknown_element=true) click to toggle source

    # 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

### Protected Instance Methods

have_required_elements?() click to toggle source

    # 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

### Private Instance Methods

__validate(ignore_unknown_element, tags=_tags, recursive=true) click to toggle source

    # 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() click to toggle source

    # 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() click to toggle source

    # 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) click to toggle source

    # 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() click to toggle source

For backward compatibility

    # File lib/rss/rss.rb, line 1053
    def calc_indent
      ''
    end

children() click to toggle source

    # 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() click to toggle source

    # 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

content_is_set?() click to toggle source

    # File lib/rss/rss.rb, line 1224
    def content_is_set?
      if have_xml_content?
        __send__(self.class.xml_getter)
      else
        content
      end
    end

empty_content?() click to toggle source

    # File lib/rss/rss.rb, line 1220
    def empty_content?
      false
    end

initialize_have_children_elements() click to toggle source

    # 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) click to toggle source

    # 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) click to toggle source

    # 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

tag(indent, additional_attrs={}, &block) click to toggle source

    # 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) click to toggle source

    # 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_with_prefix(prefix) click to toggle source

    # File lib/rss/rss.rb, line 1048
    def tag_name_with_prefix(prefix)
      "#{prefix}:#{tag_name}"
    end

validate_attribute() click to toggle source

    # 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

xmled_content() click to toggle source

    # 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