| Class | RSS::Element |
| In: |
lib/rss/rss.rb
|
| Parent: | Object |
| INDENT | = | " " |
| MUST_CALL_VALIDATORS | = | {} |
| MODELS | = | [] |
| GET_ATTRIBUTES | = | [] |
| HAVE_CHILDREN_ELEMENTS | = | [] |
| TO_ELEMENT_METHODS | = | [] |
| NEED_INITIALIZE_VARIABLES | = | [] |
| PLURAL_FORMS | = | {} |
| do_validate | [RW] | |
| parent | [RW] |
# 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
# File lib/rss/rss.rb, line 803
803: def add_need_initialize_variable(variable_name)
804: self::NEED_INITIALIZE_VARIABLES << variable_name
805: end
# File lib/rss/rss.rb, line 807
807: def add_plural_form(singular, plural)
808: self::PLURAL_FORMS[singular] = plural
809: end
# File lib/rss/rss.rb, line 799
799: def add_to_element_method(method_name)
800: self::TO_ELEMENT_METHODS << method_name
801: end
# 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
# 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
# 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
# File lib/rss/rss.rb, line 674
674: def get_attributes
675: inherited_array_reader("GET_ATTRIBUTES")
676: end
# File lib/rss/rss.rb, line 677
677: def have_children_elements
678: inherited_array_reader("HAVE_CHILDREN_ELEMENTS")
679: end
# 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
# 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
# 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
# File lib/rss/rss.rb, line 709
709: def install_must_call_validator(prefix, uri)
710: self::MUST_CALL_VALIDATORS[uri] = prefix
711: end
# 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
# File lib/rss/rss.rb, line 668
668: def must_call_validators
669: inherited_hash_reader("MUST_CALL_VALIDATORS")
670: end
# File lib/rss/rss.rb, line 683
683: def need_initialize_variables
684: inherited_array_reader("NEED_INITIALIZE_VARIABLES")
685: end
# 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
# File lib/rss/rss.rb, line 686
686: def plural_forms
687: inherited_hash_reader("PLURAL_FORMS")
688: end
# File lib/rss/rss.rb, line 680
680: def to_element_methods
681: inherited_array_reader("TO_ELEMENT_METHODS")
682: end
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# File lib/rss/rss.rb, line 1040
1040: def calc_indent
1041: ''
1042: end
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# File lib/rss/rss.rb, line 1035
1035: def tag_name_with_prefix(prefix)
1036: "#{prefix}:#{tag_name}"
1037: end
# 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