| 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] |
# File lib/rss/rss.rb, line 434
434: def have_children_elements
435: HAVE_CHILDREN_ELEMENTS
436: end
# File lib/rss/rss.rb, line 448
448: def inherited(klass)
449: klass.const_set("MUST_CALL_VALIDATORS", {})
450: klass.const_set("MODELS", [])
451: klass.const_set("GET_ATTRIBUTES", [])
452: klass.const_set("HAVE_CHILDREN_ELEMENTS", [])
453: klass.const_set("TO_ELEMENT_METHODS", [])
454: klass.const_set("NEED_INITIALIZE_VARIABLES", [])
455: klass.const_set("PLURAL_FORMS", {})
456:
457: klass.module_eval("public\n\n@tag_name = name.split(/::/).last\n@tag_name[0,1] = @tag_name[0,1].downcase\n@have_content = false\n\ndef self.must_call_validators\nsuper.merge(MUST_CALL_VALIDATORS)\nend\ndef self.models\nMODELS + super\nend\ndef self.get_attributes\nGET_ATTRIBUTES + super\nend\ndef self.have_children_elements\nHAVE_CHILDREN_ELEMENTS + super\nend\ndef self.to_element_methods\nTO_ELEMENT_METHODS + super\nend\ndef self.need_initialize_variables\nNEED_INITIALIZE_VARIABLES + super\nend\ndef self.plural_forms\nsuper.merge(PLURAL_FORMS)\nend\n\n\ndef self.install_must_call_validator(prefix, uri)\nMUST_CALL_VALIDATORS[uri] = prefix\nend\n\ndef self.install_model(tag, uri, occurs=nil, getter=nil)\ngetter ||= tag\nif m = MODELS.find {|t, u, o, g| t == tag and u == uri}\nm[2] = occurs\nelse\nMODELS << [tag, uri, occurs, getter]\nend\nend\n\ndef self.install_get_attribute(name, uri, required=true,\ntype=nil, disp_name=nil,\nelement_name=nil)\ndisp_name ||= name\nelement_name ||= name\ndef_corresponded_attr_writer name, type, disp_name\nconvert_attr_reader name\nif type == :boolean and /^is/ =~ name\nalias_method \"\\\#{$POSTMATCH}?\", name\nend\nGET_ATTRIBUTES << [name, uri, required, element_name]\nadd_need_initialize_variable(disp_name)\nend\n\ndef self.def_corresponded_attr_writer(name, type=nil, disp_name=name)\ncase type\nwhen :integer\ninteger_writer name, disp_name\nwhen :positive_integer\npositive_integer_writer name, disp_name\nwhen :boolean\nboolean_writer name, disp_name\nwhen :w3cdtf, :rfc822, :rfc2822\ndate_writer name, type, disp_name\nelse\nattr_writer name\nend\nend\n\ndef self.content_setup(type=nil)\ndef_corresponded_attr_writer \"content\", type\nconvert_attr_reader :content\n@have_content = true\nend\n\ndef self.have_content?\n@have_content\nend\n\ndef self.add_have_children_element(variable_name, plural_name)\nHAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]\nend\n\ndef self.add_to_element_method(method_name)\nTO_ELEMENT_METHODS << method_name\nend\n\ndef self.add_need_initialize_variable(variable_name)\nNEED_INITIALIZE_VARIABLES << variable_name\nend\n\ndef self.add_plural_form(singular, plural)\nPLURAL_FORMS[singular] = plural\nend\n\n")
458: end
# File lib/rss/rss.rb, line 567
567: def install_ns(prefix, uri)
568: if self::NSPOOL.has_key?(prefix)
569: raise OverlappedPrefixError.new(prefix)
570: end
571: self::NSPOOL[prefix] = uri
572: end
# File lib/rss/rss.rb, line 440
440: def need_initialize_variables
441: NEED_INITIALIZE_VARIABLES
442: end
# File lib/rss/rss.rb, line 581
581: def initialize(do_validate=true, attrs={})
582: @converter = nil
583: @do_validate = do_validate
584: initialize_variables(attrs)
585: end
# File lib/rss/rss.rb, line 606
606: def convert(value)
607: if @converter
608: @converter.convert(value)
609: else
610: value
611: end
612: end
# File lib/rss/rss.rb, line 595
595: def converter=(converter)
596: @converter = converter
597: targets = children.dup
598: self.class.have_children_elements.each do |variable_name, plural_name|
599: targets.concat(__send__(plural_name))
600: end
601: targets.each do |target|
602: target.converter = converter unless target.nil?
603: end
604: end
# File lib/rss/rss.rb, line 624
624: def setup_maker(maker)
625: target = maker_target(maker)
626: unless target.nil?
627: setup_maker_attributes(target)
628: setup_maker_element(target)
629: setup_maker_elements(target)
630: end
631: end
# File lib/rss/rss.rb, line 633
633: def to_s(need_convert=true, indent='')
634: if self.class.have_content?
635: return "" unless @content
636: rv = tag(indent) do |next_indent|
637: h(@content)
638: end
639: else
640: rv = tag(indent) do |next_indent|
641: self.class.to_element_methods.collect do |method_name|
642: __send__(method_name, false, next_indent)
643: end
644: end
645: end
646: rv = convert(rv) if need_convert
647: rv
648: end
# File lib/rss/rss.rb, line 614
614: def validate(ignore_unknown_element=true)
615: validate_attribute
616: __validate(ignore_unknown_element)
617: end
# File lib/rss/rss.rb, line 619
619: def validate_for_stream(tags, ignore_unknown_element=true)
620: validate_attribute
621: __validate(ignore_unknown_element, tags, false)
622: end
# File lib/rss/rss.rb, line 820
820: def __validate(ignore_unknown_element, tags=_tags, recursive=true)
821: if recursive
822: children.compact.each do |child|
823: child.validate
824: end
825: end
826: must_call_validators = self.class.must_call_validators
827: tags = tag_filter(tags.dup)
828: p tags if DEBUG
829: must_call_validators.each do |uri, prefix|
830: _validate(ignore_unknown_element, tags[uri], uri)
831: meth = "#{prefix}_validate"
832: if respond_to?(meth, true)
833: __send__(meth, ignore_unknown_element, tags[uri], uri)
834: end
835: end
836: end
# File lib/rss/rss.rb, line 814
814: def _attrs
815: self.class.get_attributes.collect do |name, uri, required, element_name|
816: [element_name, required, name]
817: end
818: end
# File lib/rss/rss.rb, line 800
800: def _tags
801: rv = []
802: self.class.models.each do |name, uri, occurs, getter|
803: value = __send__(getter)
804: next if value.nil?
805: if value.is_a?(Array)
806: rv.concat([[uri, name]] * value.size)
807: else
808: rv << [uri, name]
809: end
810: end
811: rv
812: end
# File lib/rss/rss.rb, line 846
846: def _validate(ignore_unknown_element, tags, uri, models=self.class.models)
847: count = 1
848: do_redo = false
849: not_shift = false
850: tag = nil
851: models = models.find_all {|model| model[1] == uri}
852: element_names = models.collect {|model| model[0]}
853: if tags
854: tags_size = tags.size
855: tags = tags.sort_by {|x| element_names.index(x) || tags_size}
856: end
857:
858: models.each_with_index do |model, i|
859: name, model_uri, occurs, getter = model
860:
861: if DEBUG
862: p "before"
863: p tags
864: p model
865: end
866:
867: if not_shift
868: not_shift = false
869: elsif tags
870: tag = tags.shift
871: end
872:
873: if DEBUG
874: p "mid"
875: p count
876: end
877:
878: case occurs
879: when '?'
880: if count > 2
881: raise TooMuchTagError.new(name, tag_name)
882: else
883: if name == tag
884: do_redo = true
885: else
886: not_shift = true
887: end
888: end
889: when '*'
890: if name == tag
891: do_redo = true
892: else
893: not_shift = true
894: end
895: when '+'
896: if name == tag
897: do_redo = true
898: else
899: if count > 1
900: not_shift = true
901: else
902: raise MissingTagError.new(name, tag_name)
903: end
904: end
905: else
906: if name == tag
907: if models[i+1] and models[i+1][0] != name and
908: tags and tags.first == name
909: raise TooMuchTagError.new(name, tag_name)
910: end
911: else
912: raise MissingTagError.new(name, tag_name)
913: end
914: end
915:
916: if DEBUG
917: p "after"
918: p not_shift
919: p do_redo
920: p tag
921: end
922:
923: if do_redo
924: do_redo = false
925: count += 1
926: redo
927: else
928: count = 1
929: end
930:
931: end
932:
933: if !ignore_unknown_element and !tags.nil? and !tags.empty?
934: raise NotExpectedTagError.new(tags.first, uri, tag_name)
935: end
936:
937: end
# File lib/rss/rss.rb, line 787
787: def children
788: rv = []
789: self.class.models.each do |name, uri, occurs, getter|
790: value = __send__(getter)
791: next if value.nil?
792: value = [value] unless value.is_a?(Array)
793: value.each do |v|
794: rv << v if v.is_a?(Element)
795: end
796: end
797: rv
798: end
# File lib/rss/rss.rb, line 716
716: def collect_attrs
717: attrs = {}
718: _attrs.each do |name, required, alias_name|
719: value = __send__(alias_name || name)
720: return nil if required and value.nil?
721: next if value.nil?
722: return nil if attrs.has_key?(name)
723: attrs[name] = value
724: end
725: attrs
726: end
# File lib/rss/rss.rb, line 668
668: def initialize_have_children_elements
669: self.class.have_children_elements.each do |variable_name, plural_name|
670: instance_eval("@#{variable_name} = []")
671: end
672: end
# File lib/rss/rss.rb, line 651
651: def initialize_variables(attrs)
652: normalized_attrs = {}
653: attrs.each do |key, value|
654: normalized_attrs[key.to_s] = value
655: end
656: self.class.need_initialize_variables.each do |variable_name|
657: value = normalized_attrs[variable_name.to_s]
658: if value
659: __send__("#{variable_name}=", value)
660: else
661: instance_eval("@#{variable_name} = nil")
662: end
663: end
664: initialize_have_children_elements
665: @content = "" if self.class.have_content?
666: end
# File lib/rss/rss.rb, line 706
706: def make_start_tag(indent, next_indent, attrs)
707: start_tag = ["#{indent}<#{full_name}"]
708: unless attrs.empty?
709: start_tag << attrs.collect do |key, value|
710: %Q[#{h key}="#{h value}"]
711: end.join("\n#{next_indent}")
712: end
713: start_tag.join(" ")
714: end
# File lib/rss/rss.rb, line 774
774: def set_next_element(tag_name, next_element)
775: klass = next_element.class
776: prefix = ""
777: prefix << "#{klass.required_prefix}_" if klass.required_prefix
778: key = "#{prefix}#{tag_name}"
779: if self.class.plural_forms.has_key?(key)
780: ary = __send__("#{self.class.plural_forms[key]}")
781: ary << next_element
782: else
783: __send__("#{prefix}#{tag_name}=", next_element)
784: end
785: end
# File lib/rss/rss.rb, line 744
744: def setup_maker_element(target)
745: self.class.need_initialize_variables.each do |var|
746: value = __send__(var)
747: if value.respond_to?("setup_maker") and
748: !not_need_to_call_setup_maker_variables.include?(var)
749: value.setup_maker(target)
750: else
751: setter = "#{var}="
752: if target.respond_to?(setter)
753: target.__send__(setter, value)
754: end
755: end
756: end
757: end
# File lib/rss/rss.rb, line 763
763: def setup_maker_elements(parent)
764: self.class.have_children_elements.each do |name, plural_name|
765: if parent.respond_to?(plural_name)
766: target = parent.__send__(plural_name)
767: __send__(plural_name).each do |elem|
768: elem.setup_maker(target)
769: end
770: end
771: end
772: end
# File lib/rss/rss.rb, line 674
674: def tag(indent, additional_attrs={}, &block)
675: next_indent = indent + INDENT
676:
677: attrs = collect_attrs
678: return "" if attrs.nil?
679:
680: attrs.update(additional_attrs)
681: start_tag = make_start_tag(indent, next_indent, attrs)
682:
683: if block
684: content = block.call(next_indent)
685: else
686: content = []
687: end
688:
689: if content.is_a?(String)
690: content = [content]
691: start_tag << ">"
692: end_tag = "</#{full_name}>"
693: else
694: content = content.reject{|x| x.empty?}
695: if content.empty?
696: end_tag = "/>"
697: else
698: start_tag << ">\n"
699: end_tag = "\n#{indent}</#{full_name}>"
700: end
701: end
702:
703: start_tag + content.join("\n") + end_tag
704: end
# File lib/rss/rss.rb, line 939
939: def tag_filter(tags)
940: rv = {}
941: tags.each do |tag|
942: rv[tag[0]] = [] unless rv.has_key?(tag[0])
943: rv[tag[0]].push(tag[1])
944: end
945: rv
946: end
# File lib/rss/rss.rb, line 728
728: def tag_name_with_prefix(prefix)
729: "#{prefix}:#{tag_name}"
730: end