Class RSS::Element
In: lib/rss/rss.rb
Parent: Object

Methods

Included Modules

Utils SetupMaker

Constants

INDENT = " "
MUST_CALL_VALIDATORS = {}
MODELS = []
GET_ATTRIBUTES = []
HAVE_CHILDREN_ELEMENTS = []
TO_ELEMENT_METHODS = []
NEED_INITIALIZE_VARIABLES = []
PLURAL_FORMS = {}

Attributes

do_validate  [RW] 
parent  [RW] 

Public Class methods

[Source]

     # File lib/rss/rss.rb, line 795
795:       def add_have_children_element(variable_name, plural_name)
796:         self::HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]
797:       end

[Source]

     # File lib/rss/rss.rb, line 803
803:       def add_need_initialize_variable(variable_name)
804:         self::NEED_INITIALIZE_VARIABLES << variable_name
805:       end

[Source]

     # File lib/rss/rss.rb, line 807
807:       def add_plural_form(singular, plural)
808:         self::PLURAL_FORMS[singular] = plural
809:       end

[Source]

     # File lib/rss/rss.rb, line 799
799:       def add_to_element_method(method_name)
800:         self::TO_ELEMENT_METHODS << method_name
801:       end

[Source]

     # File lib/rss/rss.rb, line 784
784:       def content_setup(type=nil, disp_name=nil)
785:         writer_type, reader_type = type
786:         def_corresponded_attr_writer :content, writer_type, disp_name
787:         def_corresponded_attr_reader :content, reader_type
788:         @have_content = true
789:       end

[Source]

     # File lib/rss/rss.rb, line 765
765:       def def_corresponded_attr_reader(name, type=nil)
766:         case type
767:         when :inherit
768:           inherit_convert_attr_reader name
769:         when :uri
770:           uri_convert_attr_reader name
771:         when :yes_clean_other
772:           yes_clean_other_attr_reader name
773:         when :yes_other
774:           yes_other_attr_reader name
775:         when :csv
776:           csv_attr_reader name
777:         when :csv_integer
778:           csv_attr_reader name, :separator => ","
779:         else
780:           convert_attr_reader name
781:         end
782:       end

[Source]

     # File lib/rss/rss.rb, line 737
737:       def def_corresponded_attr_writer(name, type=nil, disp_name=nil)
738:         disp_name ||= name
739:         case type
740:         when :integer
741:           integer_writer name, disp_name
742:         when :positive_integer
743:           positive_integer_writer name, disp_name
744:         when :boolean
745:           boolean_writer name, disp_name
746:         when :w3cdtf, :rfc822, :rfc2822
747:           date_writer name, type, disp_name
748:         when :text_type
749:           text_type_writer name, disp_name
750:         when :content
751:           content_writer name, disp_name
752:         when :yes_clean_other
753:           yes_clean_other_writer name, disp_name
754:         when :yes_other
755:           yes_other_writer name, disp_name
756:         when :csv
757:           csv_writer name
758:         when :csv_integer
759:           csv_integer_writer name
760:         else
761:           attr_writer name
762:         end
763:       end

[Source]

     # File lib/rss/rss.rb, line 674
674:       def get_attributes
675:         inherited_array_reader("GET_ATTRIBUTES")
676:       end

[Source]

     # File lib/rss/rss.rb, line 677
677:       def have_children_elements
678:         inherited_array_reader("HAVE_CHILDREN_ELEMENTS")
679:       end

[Source]

     # File lib/rss/rss.rb, line 791
791:       def have_content?
792:         @have_content
793:       end

[Source]

     # File lib/rss/rss.rb, line 694
694:       def inherited(klass)
695:         klass.const_set("MUST_CALL_VALIDATORS", {})
696:         klass.const_set("MODELS", [])
697:         klass.const_set("GET_ATTRIBUTES", [])
698:         klass.const_set("HAVE_CHILDREN_ELEMENTS", [])
699:         klass.const_set("TO_ELEMENT_METHODS", [])
700:         klass.const_set("NEED_INITIALIZE_VARIABLES", [])
701:         klass.const_set("PLURAL_FORMS", {})
702: 
703:         tag_name = klass.name.split(/::/).last
704:         tag_name[0, 1] = tag_name[0, 1].downcase
705:         klass.instance_variable_set("@tag_name", tag_name)
706:         klass.instance_variable_set("@have_content", false)
707:       end

[Source]

     # File lib/rss/rss.rb, line 690
690:       def inherited_base
691:         ::RSS::Element
692:       end

[Source]

     # File lib/rss/rss.rb, line 722
722:       def install_get_attribute(name, uri, required=true,
723:                                 type=nil, disp_name=nil,
724:                                 element_name=nil)
725:         disp_name ||= name
726:         element_name ||= name
727:         writer_type, reader_type = type
728:         def_corresponded_attr_writer name, writer_type, disp_name
729:         def_corresponded_attr_reader name, reader_type
730:         if type == :boolean and /^is/ =~ name
731:           alias_method "#{$POSTMATCH}?", name
732:         end
733:         self::GET_ATTRIBUTES << [name, uri, required, element_name]
734:         add_need_initialize_variable(disp_name)
735:       end

[Source]

     # File lib/rss/rss.rb, line 713
713:       def install_model(tag, uri, occurs=nil, getter=nil, plural=false)
714:         getter ||= tag
715:         if m = self::MODELS.find {|t, u, o, g, p| t == tag and u == uri}
716:           m[2] = occurs
717:         else
718:           self::MODELS << [tag, uri, occurs, getter, plural]
719:         end
720:       end

[Source]

     # File lib/rss/rss.rb, line 709
709:       def install_must_call_validator(prefix, uri)
710:         self::MUST_CALL_VALIDATORS[uri] = prefix
711:       end

[Source]

     # File lib/rss/rss.rb, line 823
823:       def install_ns(prefix, uri)
824:         if self::NSPOOL.has_key?(prefix)
825:           raise OverlappedPrefixError.new(prefix)
826:         end
827:         self::NSPOOL[prefix] = uri
828:       end

[Source]

     # File lib/rss/rss.rb, line 671
671:       def models
672:         inherited_array_reader("MODELS")
673:       end

[Source]

     # File lib/rss/rss.rb, line 668
668:       def must_call_validators
669:         inherited_hash_reader("MUST_CALL_VALIDATORS")
670:       end

[Source]

     # File lib/rss/rss.rb, line 683
683:       def need_initialize_variables
684:         inherited_array_reader("NEED_INITIALIZE_VARIABLES")
685:       end

[Source]

     # File lib/rss/rss.rb, line 819
819:       def need_parent?
820:         false
821:       end

[Source]

     # File lib/rss/rss.rb, line 837
837:     def initialize(do_validate=true, attrs=nil)
838:       @parent = nil
839:       @converter = nil
840:       if attrs.nil? and (do_validate.is_a?(Hash) or do_validate.is_a?(Array))
841:         do_validate, attrs = true, do_validate
842:       end
843:       @do_validate = do_validate
844:       initialize_variables(attrs || {})
845:     end

[Source]

     # File lib/rss/rss.rb, line 686
686:       def plural_forms
687:         inherited_hash_reader("PLURAL_FORMS")
688:       end

[Source]

     # File lib/rss/rss.rb, line 811
811:       def required_prefix
812:         nil
813:       end

[Source]

     # File lib/rss/rss.rb, line 815
815:       def required_uri
816:         ""
817:       end

[Source]

     # File lib/rss/rss.rb, line 830
830:       def tag_name
831:         @tag_name
832:       end

[Source]

     # File lib/rss/rss.rb, line 680
680:       def to_element_methods
681:         inherited_array_reader("TO_ELEMENT_METHODS")
682:       end

Public Instance methods

[Source]

     # File lib/rss/rss.rb, line 866
866:     def convert(value)
867:       if @converter
868:         @converter.convert(value)
869:       else
870:         value
871:       end
872:     end

[Source]

     # File lib/rss/rss.rb, line 855
855:     def converter=(converter)
856:       @converter = converter
857:       targets = children.dup
858:       self.class.have_children_elements.each do |variable_name, plural_name|
859:         targets.concat(__send__(plural_name))
860:       end
861:       targets.each do |target|
862:         target.converter = converter unless target.nil?
863:       end
864:     end

[Source]

     # File lib/rss/rss.rb, line 851
851:     def full_name
852:       tag_name
853:     end

[Source]

     # File lib/rss/rss.rb, line 916
916:     def have_xml_content?
917:       false
918:     end

[Source]

     # File lib/rss/rss.rb, line 920
920:     def need_base64_encode?
921:       false
922:     end

[Source]

     # File lib/rss/rss.rb, line 924
924:     def set_next_element(tag_name, next_element)
925:       klass = next_element.class
926:       prefix = ""
927:       prefix << "#{klass.required_prefix}_" if klass.required_prefix
928:       key = "#{prefix}#{tag_name.gsub(/-/, '_')}"
929:       if self.class.plural_forms.has_key?(key)
930:         ary = __send__("#{self.class.plural_forms[key]}")
931:         ary << next_element
932:       else
933:         __send__("#{key}=", next_element)
934:       end
935:     end

[Source]

     # File lib/rss/rss.rb, line 847
847:     def tag_name
848:       self.class.tag_name
849:     end

[Source]

     # File lib/rss/rss.rb, line 895
895:     def to_s(need_convert=true, indent='')
896:       if self.class.have_content?
897:         return "" if !empty_content? and !content_is_set?
898:         rv = tag(indent) do |next_indent|
899:           if empty_content?
900:             ""
901:           else
902:             xmled_content
903:           end
904:         end
905:       else
906:         rv = tag(indent) do |next_indent|
907:           self.class.to_element_methods.collect do |method_name|
908:             __send__(method_name, false, next_indent)
909:           end
910:         end
911:       end
912:       rv = convert(rv) if need_convert
913:       rv
914:     end

[Source]

     # File lib/rss/rss.rb, line 874
874:     def valid?(ignore_unknown_element=true)
875:       validate(ignore_unknown_element)
876:       true
877:     rescue RSS::Error
878:       false
879:     end

[Source]

     # File lib/rss/rss.rb, line 881
881:     def validate(ignore_unknown_element=true)
882:       do_validate = @do_validate
883:       @do_validate = true
884:       validate_attribute
885:       __validate(ignore_unknown_element)
886:     ensure
887:       @do_validate = do_validate
888:     end

[Source]

     # File lib/rss/rss.rb, line 890
890:     def validate_for_stream(tags, ignore_unknown_element=true)
891:       validate_attribute
892:       __validate(ignore_unknown_element, tags, false)
893:     end

Protected Instance methods

[Source]

     # File lib/rss/rss.rb, line 938
938:     def have_required_elements?
939:       self.class::MODELS.all? do |tag, uri, occurs, getter|
940:         if occurs.nil? or occurs == "+"
941:           child = __send__(getter)
942:           if child.is_a?(Array)
943:             children = child
944:             children.any? {|c| c.have_required_elements?}
945:           else
946:             !child.to_s.empty?
947:           end
948:         else
949:           true
950:         end
951:       end
952:     end

Private Instance methods

[Source]

      # File lib/rss/rss.rb, line 1077
1077:     def __validate(ignore_unknown_element, tags=_tags, recursive=true)
1078:       if recursive
1079:         children.compact.each do |child|
1080:           child.validate
1081:         end
1082:       end
1083:       must_call_validators = self.class.must_call_validators
1084:       tags = tag_filter(tags.dup)
1085:       p tags if DEBUG
1086:       must_call_validators.each do |uri, prefix|
1087:         _validate(ignore_unknown_element, tags[uri], uri)
1088:         meth = "#{prefix}_validate"
1089:         if !prefix.empty? and respond_to?(meth, true)
1090:           __send__(meth, ignore_unknown_element, tags[uri], uri)
1091:         end
1092:       end
1093:     end

[Source]

      # File lib/rss/rss.rb, line 1071
1071:     def _attrs
1072:       self.class.get_attributes.collect do |name, uri, required, element_name|
1073:         [element_name, required, name]
1074:       end
1075:     end

[Source]

      # File lib/rss/rss.rb, line 1057
1057:     def _tags
1058:       rv = []
1059:       self.class.models.each do |name, uri, occurs, getter, plural|
1060:         value = __send__(getter)
1061:         next if value.nil?
1062:         if plural and value.is_a?(Array)
1063:           rv.concat([[uri, name]] * value.size)
1064:         else
1065:           rv << [uri, name]
1066:         end
1067:       end
1068:       rv
1069:     end

[Source]

      # File lib/rss/rss.rb, line 1105
1105:     def _validate(ignore_unknown_element, tags, uri, models=self.class.models)
1106:       count = 1
1107:       do_redo = false
1108:       not_shift = false
1109:       tag = nil
1110:       models = models.find_all {|model| model[1] == uri}
1111:       element_names = models.collect {|model| model[0]}
1112:       if tags
1113:         tags_size = tags.size
1114:         tags = tags.sort_by {|x| element_names.index(x) || tags_size}
1115:       end
1116: 
1117:       _tags = tags.dup if tags
1118:       models.each_with_index do |model, i|
1119:         name, model_uri, occurs, getter = model
1120: 
1121:         if DEBUG
1122:           p "before"
1123:           p tags
1124:           p model
1125:         end
1126: 
1127:         if not_shift
1128:           not_shift = false
1129:         elsif tags
1130:           tag = tags.shift
1131:         end
1132: 
1133:         if DEBUG
1134:           p "mid"
1135:           p count
1136:         end
1137: 
1138:         case occurs
1139:         when '?'
1140:           if count > 2
1141:             raise TooMuchTagError.new(name, tag_name)
1142:           else
1143:             if name == tag
1144:               do_redo = true
1145:             else
1146:               not_shift = true
1147:             end
1148:           end
1149:         when '*'
1150:           if name == tag
1151:             do_redo = true
1152:           else
1153:             not_shift = true
1154:           end
1155:         when '+'
1156:           if name == tag
1157:             do_redo = true
1158:           else
1159:             if count > 1
1160:               not_shift = true
1161:             else
1162:               raise MissingTagError.new(name, tag_name)
1163:             end
1164:           end
1165:         else
1166:           if name == tag
1167:             if models[i+1] and models[i+1][0] != name and
1168:                 tags and tags.first == name
1169:               raise TooMuchTagError.new(name, tag_name)
1170:             end
1171:           else
1172:             raise MissingTagError.new(name, tag_name)
1173:           end
1174:         end
1175: 
1176:         if DEBUG
1177:           p "after"
1178:           p not_shift
1179:           p do_redo
1180:           p tag
1181:         end
1182: 
1183:         if do_redo
1184:           do_redo = false
1185:           count += 1
1186:           redo
1187:         else
1188:           count = 1
1189:         end
1190: 
1191:       end
1192: 
1193:       if !ignore_unknown_element and !tags.nil? and !tags.empty?
1194:         raise NotExpectedTagError.new(tags.first, uri, tag_name)
1195:       end
1196: 
1197:     end

For backward compatibility

[Source]

      # File lib/rss/rss.rb, line 1040
1040:     def calc_indent
1041:       ''
1042:     end

[Source]

      # File lib/rss/rss.rb, line 1044
1044:     def children
1045:       rv = []
1046:       self.class.models.each do |name, uri, occurs, getter|
1047:         value = __send__(getter)
1048:         next if value.nil?
1049:         value = [value] unless value.is_a?(Array)
1050:         value.each do |v|
1051:           rv << v if v.is_a?(Element)
1052:         end
1053:       end
1054:       rv
1055:     end

[Source]

      # File lib/rss/rss.rb, line 1023
1023:     def collect_attrs
1024:       attrs = {}
1025:       _attrs.each do |name, required, alias_name|
1026:         value = __send__(alias_name || name)
1027:         return nil if required and value.nil?
1028:         next if value.nil?
1029:         return nil if attrs.has_key?(name)
1030:         attrs[name] = value
1031:       end
1032:       attrs
1033:     end

[Source]

      # File lib/rss/rss.rb, line 1212
1212:     def content_is_set?
1213:       if have_xml_content?
1214:         __send__(self.class.xml_getter)
1215:       else
1216:         content
1217:       end
1218:     end

[Source]

      # File lib/rss/rss.rb, line 1208
1208:     def empty_content?
1209:       false
1210:     end

[Source]

     # File lib/rss/rss.rb, line 972
972:     def initialize_have_children_elements
973:       self.class.have_children_elements.each do |variable_name, plural_name|
974:         instance_variable_set("@#{variable_name}", [])
975:       end
976:     end

[Source]

     # File lib/rss/rss.rb, line 955
955:     def initialize_variables(attrs)
956:       normalized_attrs = {}
957:       attrs.each do |key, value|
958:         normalized_attrs[key.to_s] = value
959:       end
960:       self.class.need_initialize_variables.each do |variable_name|
961:         value = normalized_attrs[variable_name.to_s]
962:         if value
963:           __send__("#{variable_name}=", value)
964:         else
965:           instance_variable_set("@#{variable_name}", nil)
966:         end
967:       end
968:       initialize_have_children_elements
969:       @content = normalized_attrs["content"] if self.class.have_content?
970:     end

[Source]

      # File lib/rss/rss.rb, line 1013
1013:     def make_start_tag(indent, next_indent, attrs)
1014:       start_tag = ["#{indent}<#{full_name}"]
1015:       unless attrs.empty?
1016:         start_tag << attrs.collect do |key, value|
1017:           %Q[#{h key}="#{h value}"]
1018:         end.join("\n#{next_indent}")
1019:       end
1020:       start_tag.join(" ")
1021:     end

[Source]

      # File lib/rss/rss.rb, line 978
 978:     def tag(indent, additional_attrs={}, &block)
 979:       next_indent = indent + INDENT
 980: 
 981:       attrs = collect_attrs
 982:       return "" if attrs.nil?
 983: 
 984:       return "" unless have_required_elements?
 985: 
 986:       attrs.update(additional_attrs)
 987:       start_tag = make_start_tag(indent, next_indent, attrs.dup)
 988: 
 989:       if block
 990:         content = block.call(next_indent)
 991:       else
 992:         content = []
 993:       end
 994: 
 995:       if content.is_a?(String)
 996:         content = [content]
 997:         start_tag << ">"
 998:         end_tag = "</#{full_name}>"
 999:       else
1000:         content = content.reject{|x| x.empty?}
1001:         if content.empty?
1002:           return "" if attrs.empty?
1003:           end_tag = "/>"
1004:         else
1005:           start_tag << ">\n"
1006:           end_tag = "\n#{indent}</#{full_name}>"
1007:         end
1008:       end
1009:       
1010:       start_tag + content.join("\n") + end_tag
1011:     end

[Source]

      # File lib/rss/rss.rb, line 1199
1199:     def tag_filter(tags)
1200:       rv = {}
1201:       tags.each do |tag|
1202:         rv[tag[0]] = [] unless rv.has_key?(tag[0])
1203:         rv[tag[0]].push(tag[1])
1204:       end
1205:       rv
1206:     end

[Source]

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

[Source]

      # File lib/rss/rss.rb, line 1095
1095:     def validate_attribute
1096:       _attrs.each do |a_name, required, alias_name|
1097:         value = instance_variable_get("@#{alias_name || a_name}")
1098:         if required and value.nil?
1099:           raise MissingAttributeError.new(tag_name, a_name)
1100:         end
1101:         __send__("#{alias_name || a_name}=", value)
1102:       end
1103:     end

[Source]

      # File lib/rss/rss.rb, line 1220
1220:     def xmled_content
1221:       if have_xml_content?
1222:         __send__(self.class.xml_getter).to_s
1223:       else
1224:         _content = content
1225:         _content = Base64.encode64(_content) if need_base64_encode?
1226:         h(_content)
1227:       end
1228:     end

[Validate]