diff options
Diffstat (limited to 'jni/ruby/lib/rss/maker')
-rw-r--r-- | jni/ruby/lib/rss/maker/0.9.rb | 508 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/1.0.rb | 435 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/2.0.rb | 223 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/atom.rb | 172 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/base.rb | 944 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/content.rb | 21 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/dublincore.rb | 121 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/entry.rb | 163 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/feed.rb | 426 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/image.rb | 111 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/itunes.rb | 242 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/slash.rb | 33 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/syndication.rb | 18 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/taxonomy.rb | 118 | ||||
-rw-r--r-- | jni/ruby/lib/rss/maker/trackback.rb | 61 |
15 files changed, 3596 insertions, 0 deletions
diff --git a/jni/ruby/lib/rss/maker/0.9.rb b/jni/ruby/lib/rss/maker/0.9.rb new file mode 100644 index 0000000..c398343 --- /dev/null +++ b/jni/ruby/lib/rss/maker/0.9.rb @@ -0,0 +1,508 @@ +require "rss/0.9" + +require "rss/maker/base" + +module RSS + module Maker + + class RSS09 < RSSBase + + def initialize(feed_version) + super + @feed_type = "rss" + end + + private + def make_feed + Rss.new(@feed_version, @version, @encoding, @standalone) + end + + def setup_elements(rss) + setup_channel(rss) + end + + class Channel < ChannelBase + def to_feed(rss) + channel = Rss::Channel.new + setup_values(channel) + _not_set_required_variables = not_set_required_variables + if _not_set_required_variables.empty? + rss.channel = channel + set_parent(channel, rss) + setup_items(rss) + setup_image(rss) + setup_textinput(rss) + setup_other_elements(rss, channel) + rss + else + raise NotSetError.new("maker.channel", _not_set_required_variables) + end + end + + private + def setup_items(rss) + @maker.items.to_feed(rss) + end + + def setup_image(rss) + @maker.image.to_feed(rss) + end + + def setup_textinput(rss) + @maker.textinput.to_feed(rss) + end + + def variables + super + ["pubDate"] + end + + def required_variable_names + %w(link language) + end + + def not_set_required_variables + vars = super + vars << "description" unless description {|d| d.have_required_values?} + vars << "title" unless title {|t| t.have_required_values?} + vars + end + + class SkipDays < SkipDaysBase + def to_feed(rss, channel) + unless @days.empty? + skipDays = Rss::Channel::SkipDays.new + channel.skipDays = skipDays + set_parent(skipDays, channel) + @days.each do |day| + day.to_feed(rss, skipDays.days) + end + end + end + + class Day < DayBase + def to_feed(rss, days) + day = Rss::Channel::SkipDays::Day.new + set = setup_values(day) + if set + days << day + set_parent(day, days) + setup_other_elements(rss, day) + end + end + + private + def required_variable_names + %w(content) + end + end + end + + class SkipHours < SkipHoursBase + def to_feed(rss, channel) + unless @hours.empty? + skipHours = Rss::Channel::SkipHours.new + channel.skipHours = skipHours + set_parent(skipHours, channel) + @hours.each do |hour| + hour.to_feed(rss, skipHours.hours) + end + end + end + + class Hour < HourBase + def to_feed(rss, hours) + hour = Rss::Channel::SkipHours::Hour.new + set = setup_values(hour) + if set + hours << hour + set_parent(hour, hours) + setup_other_elements(rss, hour) + end + end + + private + def required_variable_names + %w(content) + end + end + end + + class Cloud < CloudBase + def to_feed(*args) + end + end + + class Categories < CategoriesBase + def to_feed(*args) + end + + class Category < CategoryBase + end + end + + class Links < LinksBase + def to_feed(rss, channel) + return if @links.empty? + @links.first.to_feed(rss, channel) + end + + class Link < LinkBase + def to_feed(rss, channel) + if have_required_values? + channel.link = href + else + raise NotSetError.new("maker.channel.link", + not_set_required_variables) + end + end + + private + def required_variable_names + %w(href) + end + end + end + + class Authors < AuthorsBase + def to_feed(rss, channel) + end + + class Author < AuthorBase + def to_feed(rss, channel) + end + end + end + + class Contributors < ContributorsBase + def to_feed(rss, channel) + end + + class Contributor < ContributorBase + end + end + + class Generator < GeneratorBase + def to_feed(rss, channel) + end + end + + class Copyright < CopyrightBase + def to_feed(rss, channel) + channel.copyright = content if have_required_values? + end + + private + def required_variable_names + %w(content) + end + end + + class Description < DescriptionBase + def to_feed(rss, channel) + channel.description = content if have_required_values? + end + + private + def required_variable_names + %w(content) + end + end + + class Title < TitleBase + def to_feed(rss, channel) + channel.title = content if have_required_values? + end + + private + def required_variable_names + %w(content) + end + end + end + + class Image < ImageBase + def to_feed(rss) + image = Rss::Channel::Image.new + set = setup_values(image) + if set + image.link = link + rss.channel.image = image + set_parent(image, rss.channel) + setup_other_elements(rss, image) + elsif required_element? + raise NotSetError.new("maker.image", not_set_required_variables) + end + end + + private + def required_variable_names + %w(url title link) + end + + def required_element? + true + end + end + + class Items < ItemsBase + def to_feed(rss) + if rss.channel + normalize.each do |item| + item.to_feed(rss) + end + setup_other_elements(rss, rss.items) + end + end + + class Item < ItemBase + def to_feed(rss) + item = Rss::Channel::Item.new + setup_values(item) + _not_set_required_variables = not_set_required_variables + if _not_set_required_variables.empty? + rss.items << item + set_parent(item, rss.channel) + setup_other_elements(rss, item) + elsif variable_is_set? + raise NotSetError.new("maker.items", _not_set_required_variables) + end + end + + private + def required_variable_names + [] + end + + def not_set_required_variables + vars = super + if @maker.feed_version == "0.91" + vars << "title" unless title {|t| t.have_required_values?} + vars << "link" unless link {|l| l.have_required_values?} + end + vars + end + + class Guid < GuidBase + def to_feed(*args) + end + end + + class Enclosure < EnclosureBase + def to_feed(*args) + end + end + + class Source < SourceBase + def to_feed(*args) + end + + class Authors < AuthorsBase + def to_feed(*args) + end + + class Author < AuthorBase + end + end + + class Categories < CategoriesBase + def to_feed(*args) + end + + class Category < CategoryBase + end + end + + class Contributors < ContributorsBase + def to_feed(*args) + end + + class Contributor < ContributorBase + end + end + + class Generator < GeneratorBase + def to_feed(*args) + end + end + + class Icon < IconBase + def to_feed(*args) + end + end + + class Links < LinksBase + def to_feed(*args) + end + + class Link < LinkBase + end + end + + class Logo < LogoBase + def to_feed(*args) + end + end + + class Rights < RightsBase + def to_feed(*args) + end + end + + class Subtitle < SubtitleBase + def to_feed(*args) + end + end + + class Title < TitleBase + def to_feed(*args) + end + end + end + + class Categories < CategoriesBase + def to_feed(*args) + end + + class Category < CategoryBase + end + end + + class Authors < AuthorsBase + def to_feed(*args) + end + + class Author < AuthorBase + end + end + + class Links < LinksBase + def to_feed(rss, item) + return if @links.empty? + @links.first.to_feed(rss, item) + end + + class Link < LinkBase + def to_feed(rss, item) + if have_required_values? + item.link = href + else + raise NotSetError.new("maker.link", + not_set_required_variables) + end + end + + private + def required_variable_names + %w(href) + end + end + end + + class Contributors < ContributorsBase + def to_feed(rss, item) + end + + class Contributor < ContributorBase + end + end + + class Rights < RightsBase + def to_feed(rss, item) + end + end + + class Description < DescriptionBase + def to_feed(rss, item) + item.description = content if have_required_values? + end + + private + def required_variable_names + %w(content) + end + end + + class Content < ContentBase + def to_feed(rss, item) + end + end + + class Title < TitleBase + def to_feed(rss, item) + item.title = content if have_required_values? + end + + private + def required_variable_names + %w(content) + end + end + end + end + + class Textinput < TextinputBase + def to_feed(rss) + textInput = Rss::Channel::TextInput.new + set = setup_values(textInput) + if set + rss.channel.textInput = textInput + set_parent(textInput, rss.channel) + setup_other_elements(rss, textInput) + end + end + + private + def required_variable_names + %w(title description name link) + end + end + end + + class RSS091 < RSS09 + def initialize(feed_version="0.91") + super + end + + class Channel < RSS09::Channel + end + + class Items < RSS09::Items + class Item < RSS09::Items::Item + end + end + + class Image < RSS09::Image + end + + class Textinput < RSS09::Textinput + end + end + + class RSS092 < RSS09 + def initialize(feed_version="0.92") + super + end + + class Channel < RSS09::Channel + end + + class Items < RSS09::Items + class Item < RSS09::Items::Item + end + end + + class Image < RSS09::Image + end + + class Textinput < RSS09::Textinput + end + end + + add_maker("0.9", "0.92", RSS092) + add_maker("0.91", "0.91", RSS091) + add_maker("0.92", "0.92", RSS092) + add_maker("rss0.9", "0.92", RSS092) + add_maker("rss0.91", "0.91", RSS091) + add_maker("rss0.92", "0.92", RSS092) + end +end diff --git a/jni/ruby/lib/rss/maker/1.0.rb b/jni/ruby/lib/rss/maker/1.0.rb new file mode 100644 index 0000000..1b9f7c3 --- /dev/null +++ b/jni/ruby/lib/rss/maker/1.0.rb @@ -0,0 +1,435 @@ +require "rss/1.0" + +require "rss/maker/base" + +module RSS + module Maker + + class RSS10 < RSSBase + + def initialize(feed_version="1.0") + super + @feed_type = "rss" + end + + private + def make_feed + RDF.new(@version, @encoding, @standalone) + end + + def setup_elements(rss) + setup_channel(rss) + setup_image(rss) + setup_items(rss) + setup_textinput(rss) + end + + class Channel < ChannelBase + include SetupDefaultLanguage + + def to_feed(rss) + set_default_values do + _not_set_required_variables = not_set_required_variables + if _not_set_required_variables.empty? + channel = RDF::Channel.new(@about) + setup_values(channel) + channel.dc_dates.clear + rss.channel = channel + set_parent(channel, rss) + setup_items(rss) + setup_image(rss) + setup_textinput(rss) + setup_other_elements(rss, channel) + else + raise NotSetError.new("maker.channel", _not_set_required_variables) + end + end + end + + private + def setup_items(rss) + items = RDF::Channel::Items.new + seq = items.Seq + set_parent(items, seq) + target_items = @maker.items.normalize + raise NotSetError.new("maker", ["items"]) if target_items.empty? + target_items.each do |item| + li = RDF::Channel::Items::Seq::Li.new(item.link) + seq.lis << li + set_parent(li, seq) + end + rss.channel.items = items + set_parent(rss.channel, items) + end + + def setup_image(rss) + if @maker.image.have_required_values? + image = RDF::Channel::Image.new(@maker.image.url) + rss.channel.image = image + set_parent(image, rss.channel) + end + end + + def setup_textinput(rss) + if @maker.textinput.have_required_values? + textinput = RDF::Channel::Textinput.new(@maker.textinput.link) + rss.channel.textinput = textinput + set_parent(textinput, rss.channel) + end + end + + def required_variable_names + %w(about link) + end + + def not_set_required_variables + vars = super + vars << "description" unless description {|d| d.have_required_values?} + vars << "title" unless title {|t| t.have_required_values?} + vars + end + + class SkipDays < SkipDaysBase + def to_feed(*args) + end + + class Day < DayBase + end + end + + class SkipHours < SkipHoursBase + def to_feed(*args) + end + + class Hour < HourBase + end + end + + class Cloud < CloudBase + def to_feed(*args) + end + end + + class Categories < CategoriesBase + def to_feed(*args) + end + + class Category < CategoryBase + end + end + + class Links < LinksBase + def to_feed(rss, channel) + return if @links.empty? + @links.first.to_feed(rss, channel) + end + + class Link < LinkBase + def to_feed(rss, channel) + if have_required_values? + channel.link = href + else + raise NotSetError.new("maker.channel.link", + not_set_required_variables) + end + end + + private + def required_variable_names + %w(href) + end + end + end + + class Authors < AuthorsBase + def to_feed(rss, channel) + end + + class Author < AuthorBase + def to_feed(rss, channel) + end + end + end + + class Contributors < ContributorsBase + def to_feed(rss, channel) + end + + class Contributor < ContributorBase + end + end + + class Generator < GeneratorBase + def to_feed(rss, channel) + end + end + + class Copyright < CopyrightBase + def to_feed(rss, channel) + end + end + + class Description < DescriptionBase + def to_feed(rss, channel) + channel.description = content if have_required_values? + end + + private + def required_variable_names + %w(content) + end + end + + class Title < TitleBase + def to_feed(rss, channel) + channel.title = content if have_required_values? + end + + private + def required_variable_names + %w(content) + end + end + end + + class Image < ImageBase + def to_feed(rss) + if @url + image = RDF::Image.new(@url) + set = setup_values(image) + if set + rss.image = image + set_parent(image, rss) + setup_other_elements(rss, image) + end + end + end + + def have_required_values? + super and @maker.channel.have_required_values? + end + + private + def variables + super + ["link"] + end + + def required_variable_names + %w(url title link) + end + end + + class Items < ItemsBase + def to_feed(rss) + if rss.channel + normalize.each do |item| + item.to_feed(rss) + end + setup_other_elements(rss, rss.items) + end + end + + class Item < ItemBase + def to_feed(rss) + set_default_values do + item = RDF::Item.new(link) + set = setup_values(item) + if set + item.dc_dates.clear + rss.items << item + set_parent(item, rss) + setup_other_elements(rss, item) + elsif !have_required_values? + raise NotSetError.new("maker.item", not_set_required_variables) + end + end + end + + private + def required_variable_names + %w(link) + end + + def variables + super + %w(link) + end + + def not_set_required_variables + set_default_values do + vars = super + vars << "title" unless title {|t| t.have_required_values?} + vars + end + end + + class Guid < GuidBase + def to_feed(*args) + end + end + + class Enclosure < EnclosureBase + def to_feed(*args) + end + end + + class Source < SourceBase + def to_feed(*args) + end + + class Authors < AuthorsBase + def to_feed(*args) + end + + class Author < AuthorBase + end + end + + class Categories < CategoriesBase + def to_feed(*args) + end + + class Category < CategoryBase + end + end + + class Contributors < ContributorsBase + def to_feed(*args) + end + + class Contributor < ContributorBase + end + end + + class Generator < GeneratorBase + def to_feed(*args) + end + end + + class Icon < IconBase + def to_feed(*args) + end + end + + class Links < LinksBase + def to_feed(*args) + end + + class Link < LinkBase + end + end + + class Logo < LogoBase + def to_feed(*args) + end + end + + class Rights < RightsBase + def to_feed(*args) + end + end + + class Subtitle < SubtitleBase + def to_feed(*args) + end + end + + class Title < TitleBase + def to_feed(*args) + end + end + end + + class Categories < CategoriesBase + def to_feed(*args) + end + + class Category < CategoryBase + end + end + + class Authors < AuthorsBase + def to_feed(*args) + end + + class Author < AuthorBase + end + end + + class Links < LinksBase + def to_feed(*args) + end + + class Link < LinkBase + end + end + + class Contributors < ContributorsBase + def to_feed(rss, item) + end + + class Contributor < ContributorBase + end + end + + class Rights < RightsBase + def to_feed(rss, item) + end + end + + class Description < DescriptionBase + def to_feed(rss, item) + item.description = content if have_required_values? + end + + private + def required_variable_names + %w(content) + end + end + + class Content < ContentBase + def to_feed(rss, item) + end + end + + class Title < TitleBase + def to_feed(rss, item) + item.title = content if have_required_values? + end + + private + def required_variable_names + %w(content) + end + end + end + end + + class Textinput < TextinputBase + def to_feed(rss) + if @link + textinput = RDF::Textinput.new(@link) + set = setup_values(textinput) + if set + rss.textinput = textinput + set_parent(textinput, rss) + setup_other_elements(rss, textinput) + end + end + end + + def have_required_values? + super and @maker.channel.have_required_values? + end + + private + def required_variable_names + %w(title description name link) + end + end + end + + add_maker("1.0", "1.0", RSS10) + add_maker("rss1.0", "1.0", RSS10) + end +end diff --git a/jni/ruby/lib/rss/maker/2.0.rb b/jni/ruby/lib/rss/maker/2.0.rb new file mode 100644 index 0000000..15b1349 --- /dev/null +++ b/jni/ruby/lib/rss/maker/2.0.rb @@ -0,0 +1,223 @@ +require "rss/2.0" + +require "rss/maker/0.9" + +module RSS + module Maker + + class RSS20 < RSS09 + + def initialize(feed_version="2.0") + super + end + + class Channel < RSS09::Channel + + private + def required_variable_names + %w(link) + end + + class SkipDays < RSS09::Channel::SkipDays + class Day < RSS09::Channel::SkipDays::Day + end + end + + class SkipHours < RSS09::Channel::SkipHours + class Hour < RSS09::Channel::SkipHours::Hour + end + end + + class Cloud < RSS09::Channel::Cloud + def to_feed(rss, channel) + cloud = Rss::Channel::Cloud.new + set = setup_values(cloud) + if set + channel.cloud = cloud + set_parent(cloud, channel) + setup_other_elements(rss, cloud) + end + end + + private + def required_variable_names + %w(domain port path registerProcedure protocol) + end + end + + class Categories < RSS09::Channel::Categories + def to_feed(rss, channel) + @categories.each do |category| + category.to_feed(rss, channel) + end + end + + class Category < RSS09::Channel::Categories::Category + def to_feed(rss, channel) + category = Rss::Channel::Category.new + set = setup_values(category) + if set + channel.categories << category + set_parent(category, channel) + setup_other_elements(rss, category) + end + end + + private + def required_variable_names + %w(content) + end + end + end + + class Generator < GeneratorBase + def to_feed(rss, channel) + channel.generator = content + end + + private + def required_variable_names + %w(content) + end + end + end + + class Image < RSS09::Image + private + def required_element? + false + end + end + + class Items < RSS09::Items + class Item < RSS09::Items::Item + private + def required_variable_names + [] + end + + def not_set_required_variables + vars = super + if !title {|t| t.have_required_values?} and + !description {|d| d.have_required_values?} + vars << "title or description" + end + vars + end + + def variables + super + ["pubDate"] + end + + class Guid < RSS09::Items::Item::Guid + def to_feed(rss, item) + guid = Rss::Channel::Item::Guid.new + set = setup_values(guid) + if set + item.guid = guid + set_parent(guid, item) + setup_other_elements(rss, guid) + end + end + + private + def required_variable_names + %w(content) + end + end + + class Enclosure < RSS09::Items::Item::Enclosure + def to_feed(rss, item) + enclosure = Rss::Channel::Item::Enclosure.new + set = setup_values(enclosure) + if set + item.enclosure = enclosure + set_parent(enclosure, item) + setup_other_elements(rss, enclosure) + end + end + + private + def required_variable_names + %w(url length type) + end + end + + class Source < RSS09::Items::Item::Source + def to_feed(rss, item) + source = Rss::Channel::Item::Source.new + set = setup_values(source) + if set + item.source = source + set_parent(source, item) + setup_other_elements(rss, source) + end + end + + private + def required_variable_names + %w(url content) + end + + class Links < RSS09::Items::Item::Source::Links + def to_feed(rss, source) + return if @links.empty? + @links.first.to_feed(rss, source) + end + + class Link < RSS09::Items::Item::Source::Links::Link + def to_feed(rss, source) + source.url = href + end + end + end + end + + class Categories < RSS09::Items::Item::Categories + def to_feed(rss, item) + @categories.each do |category| + category.to_feed(rss, item) + end + end + + class Category < RSS09::Items::Item::Categories::Category + def to_feed(rss, item) + category = Rss::Channel::Item::Category.new + set = setup_values(category) + if set + item.categories << category + set_parent(category, item) + setup_other_elements(rss) + end + end + + private + def required_variable_names + %w(content) + end + end + end + + class Authors < RSS09::Items::Item::Authors + def to_feed(rss, item) + return if @authors.empty? + @authors.first.to_feed(rss, item) + end + + class Author < RSS09::Items::Item::Authors::Author + def to_feed(rss, item) + item.author = name + end + end + end + end + end + + class Textinput < RSS09::Textinput + end + end + + add_maker("2.0", "2.0", RSS20) + add_maker("rss2.0", "2.0", RSS20) + end +end diff --git a/jni/ruby/lib/rss/maker/atom.rb b/jni/ruby/lib/rss/maker/atom.rb new file mode 100644 index 0000000..fd3198c --- /dev/null +++ b/jni/ruby/lib/rss/maker/atom.rb @@ -0,0 +1,172 @@ +require "rss/atom" + +require "rss/maker/base" + +module RSS + module Maker + module AtomPersons + module_function + def def_atom_persons(klass, name, maker_name, plural=nil) + plural ||= "#{name}s" + klass_name = Utils.to_class_name(name) + plural_klass_name = Utils.to_class_name(plural) + + klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1) + class #{plural_klass_name} < #{plural_klass_name}Base + class #{klass_name} < #{klass_name}Base + def to_feed(feed, current) + #{name} = feed.class::#{klass_name}.new + set = setup_values(#{name}) + unless set + raise NotSetError.new(#{maker_name.dump}, + not_set_required_variables) + end + current.#{plural} << #{name} + set_parent(#{name}, current) + setup_other_elements(#{name}) + end + + private + def required_variable_names + %w(name) + end + end + end +EOC + end + end + + module AtomTextConstruct + class << self + def def_atom_text_construct(klass, name, maker_name, klass_name=nil, + atom_klass_name=nil) + klass_name ||= Utils.to_class_name(name) + atom_klass_name ||= Utils.to_class_name(name) + + klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1) + class #{klass_name} < #{klass_name}Base + include #{self.name} + def to_feed(feed, current) + #{name} = current.class::#{atom_klass_name}.new + if setup_values(#{name}) + current.#{name} = #{name} + set_parent(#{name}, current) + setup_other_elements(feed) + elsif variable_is_set? + raise NotSetError.new(#{maker_name.dump}, + not_set_required_variables) + end + end + end + EOC + end + end + + private + def required_variable_names + if type == "xhtml" + %w(xml_content) + else + %w(content) + end + end + + def variables + if type == "xhtml" + super + %w(xhtml) + else + super + end + end + end + + module AtomCategory + def to_feed(feed, current) + category = feed.class::Category.new + set = setup_values(category) + if set + current.categories << category + set_parent(category, current) + setup_other_elements(feed) + else + raise NotSetError.new(self.class.not_set_name, + not_set_required_variables) + end + end + + private + def required_variable_names + %w(term) + end + + def variables + super + ["term", "scheme"] + end + end + + module AtomLink + def to_feed(feed, current) + link = feed.class::Link.new + set = setup_values(link) + if set + current.links << link + set_parent(link, current) + setup_other_elements(feed) + else + raise NotSetError.new(self.class.not_set_name, + not_set_required_variables) + end + end + + private + def required_variable_names + %w(href) + end + end + + module AtomGenerator + def to_feed(feed, current) + generator = current.class::Generator.new + if setup_values(generator) + current.generator = generator + set_parent(generator, current) + setup_other_elements(feed) + elsif variable_is_set? + raise NotSetError.new(self.class.not_set_name, + not_set_required_variables) + end + end + + private + def required_variable_names + %w(content) + end + end + + module AtomLogo + def to_feed(feed, current) + logo = current.class::Logo.new + class << logo + alias_method(:uri=, :content=) + end + set = setup_values(logo) + class << logo + remove_method(:uri=) + end + if set + current.logo = logo + set_parent(logo, current) + setup_other_elements(feed) + elsif variable_is_set? + raise NotSetError.new(self.class.not_set_name, + not_set_required_variables) + end + end + + private + def required_variable_names + %w(uri) + end + end + end +end diff --git a/jni/ruby/lib/rss/maker/base.rb b/jni/ruby/lib/rss/maker/base.rb new file mode 100644 index 0000000..0f2fc11 --- /dev/null +++ b/jni/ruby/lib/rss/maker/base.rb @@ -0,0 +1,944 @@ +require 'forwardable' + +require 'rss/rss' + +module RSS + module Maker + class Base + extend Utils::InheritedReader + + OTHER_ELEMENTS = [] + NEED_INITIALIZE_VARIABLES = [] + + class << self + def other_elements + inherited_array_reader("OTHER_ELEMENTS") + end + def need_initialize_variables + inherited_array_reader("NEED_INITIALIZE_VARIABLES") + end + + def inherited_base + ::RSS::Maker::Base + end + + def inherited(subclass) + subclass.const_set(:OTHER_ELEMENTS, []) + subclass.const_set(:NEED_INITIALIZE_VARIABLES, []) + end + + def add_other_element(variable_name) + self::OTHER_ELEMENTS << variable_name + end + + def add_need_initialize_variable(variable_name, init_value=nil, + &init_block) + init_value ||= init_block + self::NEED_INITIALIZE_VARIABLES << [variable_name, init_value] + end + + def def_array_element(name, plural=nil, klass_name=nil) + include Enumerable + extend Forwardable + + plural ||= "#{name}s" + klass_name ||= Utils.to_class_name(name) + def_delegators("@#{plural}", :<<, :[], :[]=, :first, :last) + def_delegators("@#{plural}", :push, :pop, :shift, :unshift) + def_delegators("@#{plural}", :each, :size, :empty?, :clear) + + add_need_initialize_variable(plural) {[]} + + module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def new_#{name} + #{name} = self.class::#{klass_name}.new(@maker) + @#{plural} << #{name} + if block_given? + yield #{name} + else + #{name} + end + end + alias new_child new_#{name} + + def to_feed(*args) + @#{plural}.each do |#{name}| + #{name}.to_feed(*args) + end + end + + def replace(elements) + @#{plural}.replace(elements.to_a) + end + EOC + end + + def def_classed_element_without_accessor(name, class_name=nil) + class_name ||= Utils.to_class_name(name) + add_other_element(name) + add_need_initialize_variable(name) do |object| + object.send("make_#{name}") + end + module_eval(<<-EOC, __FILE__, __LINE__ + 1) + private + def setup_#{name}(feed, current) + @#{name}.to_feed(feed, current) + end + + def make_#{name} + self.class::#{class_name}.new(@maker) + end + EOC + end + + def def_classed_element(name, class_name=nil, attribute_name=nil) + def_classed_element_without_accessor(name, class_name) + if attribute_name + module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def #{name} + if block_given? + yield(@#{name}) + else + @#{name}.#{attribute_name} + end + end + + def #{name}=(new_value) + @#{name}.#{attribute_name} = new_value + end + EOC + else + attr_reader name + end + end + + def def_classed_elements(name, attribute, plural_class_name=nil, + plural_name=nil, new_name=nil) + plural_name ||= "#{name}s" + new_name ||= name + def_classed_element(plural_name, plural_class_name) + local_variable_name = "_#{name}" + new_value_variable_name = "new_value" + additional_setup_code = nil + if block_given? + additional_setup_code = yield(local_variable_name, + new_value_variable_name) + end + module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def #{name} + #{local_variable_name} = #{plural_name}.first + #{local_variable_name} ? #{local_variable_name}.#{attribute} : nil + end + + def #{name}=(#{new_value_variable_name}) + #{local_variable_name} = + #{plural_name}.first || #{plural_name}.new_#{new_name} + #{additional_setup_code} + #{local_variable_name}.#{attribute} = #{new_value_variable_name} + end + EOC + end + + def def_other_element(name) + attr_accessor name + def_other_element_without_accessor(name) + end + + def def_other_element_without_accessor(name) + add_need_initialize_variable(name) + add_other_element(name) + module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def setup_#{name}(feed, current) + if !@#{name}.nil? and current.respond_to?(:#{name}=) + current.#{name} = @#{name} + end + end + EOC + end + + def def_csv_element(name, type=nil) + def_other_element_without_accessor(name) + attr_reader(name) + converter = "" + if type == :integer + converter = "{|v| Integer(v)}" + end + module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def #{name}=(value) + @#{name} = Utils::CSV.parse(value)#{converter} + end + EOC + end + end + + attr_reader :maker + def initialize(maker) + @maker = maker + @default_values_are_set = false + initialize_variables + end + + def have_required_values? + not_set_required_variables.empty? + end + + def variable_is_set? + variables.any? {|var| not __send__(var).nil?} + end + + private + def initialize_variables + self.class.need_initialize_variables.each do |variable_name, init_value| + if init_value.nil? + value = nil + else + if init_value.respond_to?(:call) + value = init_value.call(self) + elsif init_value.is_a?(String) + # just for backward compatibility + value = instance_eval(init_value, __FILE__, __LINE__) + else + value = init_value + end + end + instance_variable_set("@#{variable_name}", value) + end + end + + def setup_other_elements(feed, current=nil) + current ||= current_element(feed) + self.class.other_elements.each do |element| + __send__("setup_#{element}", feed, current) + end + end + + def current_element(feed) + feed + end + + def set_default_values(&block) + return yield if @default_values_are_set + + begin + @default_values_are_set = true + _set_default_values(&block) + ensure + @default_values_are_set = false + end + end + + def _set_default_values(&block) + yield + end + + def setup_values(target) + set = false + if have_required_values? + variables.each do |var| + setter = "#{var}=" + if target.respond_to?(setter) + value = __send__(var) + unless value.nil? + target.__send__(setter, value) + set = true + end + end + end + end + set + end + + def set_parent(target, parent) + target.parent = parent if target.class.need_parent? + end + + def variables + self.class.need_initialize_variables.find_all do |name, init| + # init == "nil" is just for backward compatibility + init.nil? or init == "nil" + end.collect do |name, init| + name + end + end + + def not_set_required_variables + required_variable_names.find_all do |var| + __send__(var).nil? + end + end + + def required_variables_are_set? + required_variable_names.each do |var| + return false if __send__(var).nil? + end + true + end + end + + module AtomPersonConstructBase + def self.append_features(klass) + super + + klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1) + %w(name uri email).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + EOC + end + end + + module AtomTextConstructBase + module EnsureXMLContent + class << self + def included(base) + super + base.class_eval do + %w(type content xml_content).each do |element| + attr_reader element + attr_writer element if element != "xml_content" + add_need_initialize_variable(element) + end + + alias_method(:xhtml, :xml_content) + end + end + end + + def ensure_xml_content(content) + xhtml_uri = ::RSS::Atom::XHTML_URI + unless content.is_a?(RSS::XML::Element) and + ["div", xhtml_uri] == [content.name, content.uri] + children = content + children = [children] unless content.is_a?(Array) + children = set_xhtml_uri_as_default_uri(children) + content = RSS::XML::Element.new("div", nil, xhtml_uri, + {"xmlns" => xhtml_uri}, + children) + end + content + end + + def xml_content=(content) + @xml_content = ensure_xml_content(content) + end + + def xhtml=(content) + self.xml_content = content + end + + private + def set_xhtml_uri_as_default_uri(children) + children.collect do |child| + if child.is_a?(RSS::XML::Element) and + child.prefix.nil? and child.uri.nil? + RSS::XML::Element.new(child.name, nil, ::RSS::Atom::XHTML_URI, + child.attributes.dup, + set_xhtml_uri_as_default_uri(child.children)) + else + child + end + end + end + end + + def self.append_features(klass) + super + + klass.class_eval do + include EnsureXMLContent + end + end + end + + module SetupDefaultDate + private + def _set_default_values + keep = { + :date => date, + :dc_dates => dc_dates.to_a.dup, + } + _date = _parse_date_if_needed(date) + if _date and !dc_dates.any? {|dc_date| dc_date.value == _date} + dc_date = self.class::DublinCoreDates::DublinCoreDate.new(self) + dc_date.value = _date.dup + dc_dates.unshift(dc_date) + end + self.date ||= self.dc_date + super + ensure + self.date = keep[:date] + dc_dates.replace(keep[:dc_dates]) + end + + def _parse_date_if_needed(date_value) + date_value = Time.parse(date_value) if date_value.is_a?(String) + date_value + end + end + + module SetupDefaultLanguage + private + def _set_default_values + keep = { + :dc_languages => dc_languages.to_a.dup, + } + _language = language + if _language and + !dc_languages.any? {|dc_language| dc_language.value == _language} + dc_language = self.class::DublinCoreLanguages::DublinCoreLanguage.new(self) + dc_language.value = _language.dup + dc_languages.unshift(dc_language) + end + super + ensure + dc_languages.replace(keep[:dc_languages]) + end + end + + class RSSBase < Base + class << self + def make(*args, &block) + new(*args).make(&block) + end + end + + %w(xml_stylesheets channel image items textinput).each do |element| + attr_reader element + add_need_initialize_variable(element) do |object| + object.send("make_#{element}") + end + module_eval(<<-EOC, __FILE__, __LINE__ + 1) + private + def setup_#{element}(feed) + @#{element}.to_feed(feed) + end + + def make_#{element} + self.class::#{Utils.to_class_name(element)}.new(self) + end + EOC + end + + attr_reader :feed_version + alias_method(:rss_version, :feed_version) + attr_accessor :version, :encoding, :standalone + + def initialize(feed_version) + super(self) + @feed_type = nil + @feed_subtype = nil + @feed_version = feed_version + @version = "1.0" + @encoding = "UTF-8" + @standalone = nil + end + + def make + yield(self) + to_feed + end + + def to_feed + feed = make_feed + setup_xml_stylesheets(feed) + setup_elements(feed) + setup_other_elements(feed) + feed.validate + feed + end + + private + remove_method :make_xml_stylesheets + def make_xml_stylesheets + XMLStyleSheets.new(self) + end + end + + class XMLStyleSheets < Base + def_array_element("xml_stylesheet", nil, "XMLStyleSheet") + + class XMLStyleSheet < Base + + ::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute| + attr_accessor attribute + add_need_initialize_variable(attribute) + end + + def to_feed(feed) + xss = ::RSS::XMLStyleSheet.new + guess_type_if_need(xss) + set = setup_values(xss) + if set + feed.xml_stylesheets << xss + end + end + + private + def guess_type_if_need(xss) + if @type.nil? + xss.href = @href + @type = xss.type + end + end + + def required_variable_names + %w(href type) + end + end + end + + class ChannelBase < Base + include SetupDefaultDate + + %w(cloud categories skipDays skipHours).each do |name| + def_classed_element(name) + end + + %w(generator copyright description title).each do |name| + def_classed_element(name, nil, "content") + end + + [ + ["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}], + ["author", "name"], + ["contributor", "name"], + ].each do |name, attribute, additional_setup_maker| + def_classed_elements(name, attribute, &additional_setup_maker) + end + + %w(id about language + managingEditor webMaster rating docs ttl).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + %w(date lastBuildDate).each do |date_element| + attr_reader date_element + add_need_initialize_variable(date_element) + end + + def date=(_date) + @date = _parse_date_if_needed(_date) + end + + def lastBuildDate=(_date) + @lastBuildDate = _parse_date_if_needed(_date) + end + + def pubDate + date + end + + def pubDate=(date) + self.date = date + end + + def updated + date + end + + def updated=(date) + self.date = date + end + + alias_method(:rights, :copyright) + alias_method(:rights=, :copyright=) + + alias_method(:subtitle, :description) + alias_method(:subtitle=, :description=) + + def icon + image_favicon.about + end + + def icon=(url) + image_favicon.about = url + end + + def logo + maker.image.url + end + + def logo=(url) + maker.image.url = url + end + + class SkipDaysBase < Base + def_array_element("day") + + class DayBase < Base + %w(content).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + end + + class SkipHoursBase < Base + def_array_element("hour") + + class HourBase < Base + %w(content).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + end + + class CloudBase < Base + %w(domain port path registerProcedure protocol).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + + class CategoriesBase < Base + def_array_element("category", "categories") + + class CategoryBase < Base + %w(domain content label).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + alias_method(:term, :domain) + alias_method(:term=, :domain=) + alias_method(:scheme, :content) + alias_method(:scheme=, :content=) + end + end + + class LinksBase < Base + def_array_element("link") + + class LinkBase < Base + %w(href rel type hreflang title length).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + end + + class AuthorsBase < Base + def_array_element("author") + + class AuthorBase < Base + include AtomPersonConstructBase + end + end + + class ContributorsBase < Base + def_array_element("contributor") + + class ContributorBase < Base + include AtomPersonConstructBase + end + end + + class GeneratorBase < Base + %w(uri version content).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + + class CopyrightBase < Base + include AtomTextConstructBase + end + + class DescriptionBase < Base + include AtomTextConstructBase + end + + class TitleBase < Base + include AtomTextConstructBase + end + end + + class ImageBase < Base + %w(title url width height description).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + def link + @maker.channel.link + end + end + + class ItemsBase < Base + def_array_element("item") + + attr_accessor :do_sort, :max_size + + def initialize(maker) + super + @do_sort = false + @max_size = -1 + end + + def normalize + if @max_size >= 0 + sort_if_need[0...@max_size] + else + sort_if_need[0..@max_size] + end + end + + private + def sort_if_need + if @do_sort.respond_to?(:call) + @items.sort do |x, y| + @do_sort.call(x, y) + end + elsif @do_sort + @items.sort do |x, y| + y <=> x + end + else + @items + end + end + + class ItemBase < Base + include SetupDefaultDate + + %w(guid enclosure source categories content).each do |name| + def_classed_element(name) + end + + %w(rights description title).each do |name| + def_classed_element(name, nil, "content") + end + + [ + ["author", "name"], + ["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}], + ["contributor", "name"], + ].each do |name, attribute| + def_classed_elements(name, attribute) + end + + %w(comments id published).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + %w(date).each do |date_element| + attr_reader date_element + add_need_initialize_variable(date_element) + end + + def date=(_date) + @date = _parse_date_if_needed(_date) + end + + def pubDate + date + end + + def pubDate=(date) + self.date = date + end + + def updated + date + end + + def updated=(date) + self.date = date + end + + alias_method(:summary, :description) + alias_method(:summary=, :description=) + + def <=>(other) + _date = date || dc_date + _other_date = other.date || other.dc_date + if _date and _other_date + _date <=> _other_date + elsif _date + 1 + elsif _other_date + -1 + else + 0 + end + end + + class GuidBase < Base + %w(isPermaLink content).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + def permanent_link? + isPermaLink + end + + def permanent_link=(bool) + self.isPermaLink = bool + end + end + + class EnclosureBase < Base + %w(url length type).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + + class SourceBase < Base + include SetupDefaultDate + + %w(authors categories contributors generator icon + logo rights subtitle title).each do |name| + def_classed_element(name) + end + + [ + ["link", "href"], + ].each do |name, attribute| + def_classed_elements(name, attribute) + end + + %w(id content).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + alias_method(:url, :link) + alias_method(:url=, :link=) + + %w(date).each do |date_element| + attr_reader date_element + add_need_initialize_variable(date_element) + end + + def date=(_date) + @date = _parse_date_if_needed(_date) + end + + def updated + date + end + + def updated=(date) + self.date = date + end + + private + AuthorsBase = ChannelBase::AuthorsBase + CategoriesBase = ChannelBase::CategoriesBase + ContributorsBase = ChannelBase::ContributorsBase + GeneratorBase = ChannelBase::GeneratorBase + + class IconBase < Base + %w(url).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + + LinksBase = ChannelBase::LinksBase + + class LogoBase < Base + %w(uri).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + + class RightsBase < Base + include AtomTextConstructBase + end + + class SubtitleBase < Base + include AtomTextConstructBase + end + + class TitleBase < Base + include AtomTextConstructBase + end + end + + CategoriesBase = ChannelBase::CategoriesBase + AuthorsBase = ChannelBase::AuthorsBase + LinksBase = ChannelBase::LinksBase + ContributorsBase = ChannelBase::ContributorsBase + + class RightsBase < Base + include AtomTextConstructBase + end + + class DescriptionBase < Base + include AtomTextConstructBase + end + + class ContentBase < Base + include AtomTextConstructBase::EnsureXMLContent + + %w(src).each do |element| + attr_accessor(element) + add_need_initialize_variable(element) + end + + def xml_content=(content) + content = ensure_xml_content(content) if inline_xhtml? + @xml_content = content + end + + alias_method(:xml, :xml_content) + alias_method(:xml=, :xml_content=) + + def inline_text? + [nil, "text", "html"].include?(@type) + end + + def inline_html? + @type == "html" + end + + def inline_xhtml? + @type == "xhtml" + end + + def inline_other? + !out_of_line? and ![nil, "text", "html", "xhtml"].include?(@type) + end + + def inline_other_text? + return false if @type.nil? or out_of_line? + /\Atext\//i.match(@type) ? true : false + end + + def inline_other_xml? + return false if @type.nil? or out_of_line? + /[\+\/]xml\z/i.match(@type) ? true : false + end + + def inline_other_base64? + return false if @type.nil? or out_of_line? + @type.include?("/") and !inline_other_text? and !inline_other_xml? + end + + def out_of_line? + not @src.nil? and @content.nil? + end + end + + class TitleBase < Base + include AtomTextConstructBase + end + end + end + + class TextinputBase < Base + %w(title description name link).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + end +end diff --git a/jni/ruby/lib/rss/maker/content.rb b/jni/ruby/lib/rss/maker/content.rb new file mode 100644 index 0000000..46c4911 --- /dev/null +++ b/jni/ruby/lib/rss/maker/content.rb @@ -0,0 +1,21 @@ +require 'rss/content' +require 'rss/maker/1.0' +require 'rss/maker/2.0' + +module RSS + module Maker + module ContentModel + def self.append_features(klass) + super + + ::RSS::ContentModel::ELEMENTS.each do |name| + klass.def_other_element(name) + end + end + end + + class ItemsBase + class ItemBase; include ContentModel; end + end + end +end diff --git a/jni/ruby/lib/rss/maker/dublincore.rb b/jni/ruby/lib/rss/maker/dublincore.rb new file mode 100644 index 0000000..717b074 --- /dev/null +++ b/jni/ruby/lib/rss/maker/dublincore.rb @@ -0,0 +1,121 @@ +require 'rss/dublincore' +require 'rss/maker/1.0' + +module RSS + module Maker + module DublinCoreModel + def self.append_features(klass) + super + + ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| + plural_name ||= "#{name}s" + full_name = "#{RSS::DC_PREFIX}_#{name}" + full_plural_name = "#{RSS::DC_PREFIX}_#{plural_name}" + plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" + klass.def_classed_elements(full_name, "value", plural_klass_name, + full_plural_name, name) + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def new_#{full_name}(value=nil) + _#{full_name} = #{full_plural_name}.new_#{name} + _#{full_name}.value = value + if block_given? + yield _#{full_name} + else + _#{full_name} + end + end + EOC + end + + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + # For backward compatibility + alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list + EOC + end + + ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| + plural_name ||= "#{name}s" + full_name ||= "#{DC_PREFIX}_#{name}" + full_plural_name ||= "#{DC_PREFIX}_#{plural_name}" + klass_name = Utils.to_class_name(name) + full_klass_name = "DublinCore#{klass_name}" + plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" + module_eval(<<-EOC, __FILE__, __LINE__ + 1) + class #{plural_klass_name}Base < Base + def_array_element(#{name.dump}, #{full_plural_name.dump}, + #{full_klass_name.dump}) + + class #{full_klass_name}Base < Base + attr_accessor :value + add_need_initialize_variable("value") + alias_method(:content, :value) + alias_method(:content=, :value=) + + def have_required_values? + @value + end + + def to_feed(feed, current) + if value and current.respond_to?(:#{full_name}) + new_item = current.class::#{full_klass_name}.new(value) + current.#{full_plural_name} << new_item + end + end + end + #{klass_name}Base = #{full_klass_name}Base + end + EOC + end + + def self.install_dublin_core(klass) + ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| + plural_name ||= "#{name}s" + klass_name = Utils.to_class_name(name) + full_klass_name = "DublinCore#{klass_name}" + plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + class #{plural_klass_name} < #{plural_klass_name}Base + class #{full_klass_name} < #{full_klass_name}Base + end + #{klass_name} = #{full_klass_name} + end +EOC + end + end + end + + class ChannelBase + include DublinCoreModel + end + + class ImageBase; include DublinCoreModel; end + class ItemsBase + class ItemBase + include DublinCoreModel + end + end + class TextinputBase; include DublinCoreModel; end + + makers.each do |maker| + maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + class Channel + DublinCoreModel.install_dublin_core(self) + end + + class Image + DublinCoreModel.install_dublin_core(self) + end + + class Items + class Item + DublinCoreModel.install_dublin_core(self) + end + end + + class Textinput + DublinCoreModel.install_dublin_core(self) + end + EOC + end + end +end diff --git a/jni/ruby/lib/rss/maker/entry.rb b/jni/ruby/lib/rss/maker/entry.rb new file mode 100644 index 0000000..f8f5469 --- /dev/null +++ b/jni/ruby/lib/rss/maker/entry.rb @@ -0,0 +1,163 @@ +require "rss/maker/atom" +require "rss/maker/feed" + +module RSS + module Maker + module Atom + class Entry < RSSBase + def initialize(feed_version="1.0") + super + @feed_type = "atom" + @feed_subtype = "entry" + end + + private + def make_feed + ::RSS::Atom::Entry.new(@version, @encoding, @standalone) + end + + def setup_elements(entry) + setup_items(entry) + end + + class Channel < ChannelBase + class SkipDays < SkipDaysBase + class Day < DayBase + end + end + + class SkipHours < SkipHoursBase + class Hour < HourBase + end + end + + class Cloud < CloudBase + end + + Categories = Feed::Channel::Categories + Links = Feed::Channel::Links + Authors = Feed::Channel::Authors + Contributors = Feed::Channel::Contributors + + class Generator < GeneratorBase + include AtomGenerator + + def self.not_set_name + "maker.channel.generator" + end + end + + Copyright = Feed::Channel::Copyright + + class Description < DescriptionBase + end + + Title = Feed::Channel::Title + end + + class Image < ImageBase + end + + class Items < ItemsBase + def to_feed(entry) + (normalize.first || Item.new(@maker)).to_feed(entry) + end + + class Item < ItemBase + def to_feed(entry) + set_default_values do + setup_values(entry) + entry.dc_dates.clear + setup_other_elements(entry) + unless have_required_values? + raise NotSetError.new("maker.item", not_set_required_variables) + end + end + end + + private + def required_variable_names + %w(id updated) + end + + def variables + super + ["updated"] + end + + def variable_is_set? + super or !authors.empty? + end + + def not_set_required_variables + set_default_values do + vars = super + if authors.all? {|author| !author.have_required_values?} + vars << "author" + end + vars << "title" unless title {|t| t.have_required_values?} + vars + end + end + + def _set_default_values + keep = { + :authors => authors.to_a.dup, + :contributors => contributors.to_a.dup, + :categories => categories.to_a.dup, + :id => id, + :links => links.to_a.dup, + :rights => @rights, + :title => @title, + :updated => updated, + } + authors.replace(@maker.channel.authors) if keep[:authors].empty? + if keep[:contributors].empty? + contributors.replace(@maker.channel.contributors) + end + if keep[:categories].empty? + categories.replace(@maker.channel.categories) + end + self.id ||= link || @maker.channel.id + links.replace(@maker.channel.links) if keep[:links].empty? + unless keep[:rights].variable_is_set? + @maker.channel.rights {|r| @rights = r} + end + unless keep[:title].variable_is_set? + @maker.channel.title {|t| @title = t} + end + self.updated ||= @maker.channel.updated + super + ensure + authors.replace(keep[:authors]) + contributors.replace(keep[:contributors]) + categories.replace(keep[:categories]) + links.replace(keep[:links]) + self.id = keep[:id] + @rights = keep[:rights] + @title = keep[:title] + self.updated = keep[:updated] + end + + Guid = Feed::Items::Item::Guid + Enclosure = Feed::Items::Item::Enclosure + Source = Feed::Items::Item::Source + Categories = Feed::Items::Item::Categories + Authors = Feed::Items::Item::Authors + Contributors = Feed::Items::Item::Contributors + Links = Feed::Items::Item::Links + Rights = Feed::Items::Item::Rights + Description = Feed::Items::Item::Description + Title = Feed::Items::Item::Title + Content = Feed::Items::Item::Content + end + end + + class Textinput < TextinputBase + end + end + end + + add_maker("atom:entry", "1.0", Atom::Entry) + add_maker("atom1.0:entry", "1.0", Atom::Entry) + end +end diff --git a/jni/ruby/lib/rss/maker/feed.rb b/jni/ruby/lib/rss/maker/feed.rb new file mode 100644 index 0000000..0129218 --- /dev/null +++ b/jni/ruby/lib/rss/maker/feed.rb @@ -0,0 +1,426 @@ +require "rss/maker/atom" + +module RSS + module Maker + module Atom + class Feed < RSSBase + def initialize(feed_version="1.0") + super + @feed_type = "atom" + @feed_subtype = "feed" + end + + private + def make_feed + ::RSS::Atom::Feed.new(@version, @encoding, @standalone) + end + + def setup_elements(feed) + setup_channel(feed) + setup_image(feed) + setup_items(feed) + end + + class Channel < ChannelBase + include SetupDefaultLanguage + + def to_feed(feed) + set_default_values do + setup_values(feed) + feed.dc_dates.clear + setup_other_elements(feed) + if image_favicon.about + icon = feed.class::Icon.new + icon.content = image_favicon.about + feed.icon = icon + end + unless have_required_values? + raise NotSetError.new("maker.channel", + not_set_required_variables) + end + end + end + + def have_required_values? + super and + (!authors.empty? or + @maker.items.any? {|item| !item.authors.empty?}) + end + + private + def required_variable_names + %w(id updated) + end + + def variables + super + %w(id updated) + end + + def variable_is_set? + super or !authors.empty? + end + + def not_set_required_variables + vars = super + if authors.empty? and + @maker.items.all? {|item| item.author.to_s.empty?} + vars << "author" + end + vars << "title" unless title {|t| t.have_required_values?} + vars + end + + def _set_default_values(&block) + keep = { + :id => id, + } + self.id ||= about + super(&block) + ensure + self.id = keep[:id] + end + + class SkipDays < SkipDaysBase + def to_feed(*args) + end + + class Day < DayBase + end + end + + class SkipHours < SkipHoursBase + def to_feed(*args) + end + + class Hour < HourBase + end + end + + class Cloud < CloudBase + def to_feed(*args) + end + end + + class Categories < CategoriesBase + class Category < CategoryBase + include AtomCategory + + def self.not_set_name + "maker.channel.category" + end + end + end + + class Links < LinksBase + class Link < LinkBase + include AtomLink + + def self.not_set_name + "maker.channel.link" + end + end + end + + AtomPersons.def_atom_persons(self, "author", "maker.channel.author") + AtomPersons.def_atom_persons(self, "contributor", + "maker.channel.contributor") + + class Generator < GeneratorBase + include AtomGenerator + + def self.not_set_name + "maker.channel.generator" + end + end + + AtomTextConstruct.def_atom_text_construct(self, "rights", + "maker.channel.copyright", + "Copyright") + AtomTextConstruct.def_atom_text_construct(self, "subtitle", + "maker.channel.description", + "Description") + AtomTextConstruct.def_atom_text_construct(self, "title", + "maker.channel.title") + end + + class Image < ImageBase + def to_feed(feed) + logo = feed.class::Logo.new + class << logo + alias_method(:url=, :content=) + end + set = setup_values(logo) + class << logo + remove_method(:url=) + end + if set + feed.logo = logo + set_parent(logo, feed) + setup_other_elements(feed, logo) + elsif variable_is_set? + raise NotSetError.new("maker.image", not_set_required_variables) + end + end + + private + def required_variable_names + %w(url) + end + end + + class Items < ItemsBase + def to_feed(feed) + normalize.each do |item| + item.to_feed(feed) + end + setup_other_elements(feed, feed.entries) + end + + class Item < ItemBase + def to_feed(feed) + set_default_values do + entry = feed.class::Entry.new + set = setup_values(entry) + entry.dc_dates.clear + setup_other_elements(feed, entry) + if set + feed.entries << entry + set_parent(entry, feed) + elsif variable_is_set? + raise NotSetError.new("maker.item", not_set_required_variables) + end + end + end + + def have_required_values? + set_default_values do + super and title {|t| t.have_required_values?} + end + end + + private + def required_variable_names + %w(id updated) + end + + def variables + super + ["updated"] + end + + def not_set_required_variables + vars = super + vars << "title" unless title {|t| t.have_required_values?} + vars + end + + def _set_default_values(&block) + keep = { + :id => id, + } + self.id ||= link + super(&block) + ensure + self.id = keep[:id] + end + + class Guid < GuidBase + def to_feed(feed, current) + end + end + + class Enclosure < EnclosureBase + def to_feed(feed, current) + end + end + + class Source < SourceBase + def to_feed(feed, current) + source = current.class::Source.new + setup_values(source) + current.source = source + set_parent(source, current) + setup_other_elements(feed, source) + current.source = nil if source.to_s == "<source/>" + end + + private + def required_variable_names + [] + end + + def variables + super + ["updated"] + end + + AtomPersons.def_atom_persons(self, "author", + "maker.item.source.author") + AtomPersons.def_atom_persons(self, "contributor", + "maker.item.source.contributor") + + class Categories < CategoriesBase + class Category < CategoryBase + include AtomCategory + + def self.not_set_name + "maker.item.source.category" + end + end + end + + class Generator < GeneratorBase + include AtomGenerator + + def self.not_set_name + "maker.item.source.generator" + end + end + + class Icon < IconBase + def to_feed(feed, current) + icon = current.class::Icon.new + class << icon + alias_method(:url=, :content=) + end + set = setup_values(icon) + class << icon + remove_method(:url=) + end + if set + current.icon = icon + set_parent(icon, current) + setup_other_elements(feed, icon) + elsif variable_is_set? + raise NotSetError.new("maker.item.source.icon", + not_set_required_variables) + end + end + + private + def required_variable_names + %w(url) + end + end + + class Links < LinksBase + class Link < LinkBase + include AtomLink + + def self.not_set_name + "maker.item.source.link" + end + end + end + + class Logo < LogoBase + include AtomLogo + + def self.not_set_name + "maker.item.source.logo" + end + end + + maker_name_base = "maker.item.source." + maker_name = "#{maker_name_base}rights" + AtomTextConstruct.def_atom_text_construct(self, "rights", + maker_name) + maker_name = "#{maker_name_base}subtitle" + AtomTextConstruct.def_atom_text_construct(self, "subtitle", + maker_name) + maker_name = "#{maker_name_base}title" + AtomTextConstruct.def_atom_text_construct(self, "title", + maker_name) + end + + class Categories < CategoriesBase + class Category < CategoryBase + include AtomCategory + + def self.not_set_name + "maker.item.category" + end + end + end + + AtomPersons.def_atom_persons(self, "author", "maker.item.author") + AtomPersons.def_atom_persons(self, "contributor", + "maker.item.contributor") + + class Links < LinksBase + class Link < LinkBase + include AtomLink + + def self.not_set_name + "maker.item.link" + end + end + end + + AtomTextConstruct.def_atom_text_construct(self, "rights", + "maker.item.rights") + AtomTextConstruct.def_atom_text_construct(self, "summary", + "maker.item.description", + "Description") + AtomTextConstruct.def_atom_text_construct(self, "title", + "maker.item.title") + + class Content < ContentBase + def to_feed(feed, current) + content = current.class::Content.new + if setup_values(content) + content.src = nil if content.src and content.content + current.content = content + set_parent(content, current) + setup_other_elements(feed, content) + elsif variable_is_set? + raise NotSetError.new("maker.item.content", + not_set_required_variables) + end + end + + alias_method(:xml, :xml_content) + + private + def required_variable_names + if out_of_line? + %w(type) + elsif xml_type? + %w(xml_content) + else + %w(content) + end + end + + def variables + if out_of_line? + super + elsif xml_type? + super + %w(xml) + else + super + end + end + + def xml_type? + _type = type + return false if _type.nil? + _type == "xhtml" or + /(?:\+xml|\/xml)$/i =~ _type or + %w(text/xml-external-parsed-entity + application/xml-external-parsed-entity + application/xml-dtd).include?(_type.downcase) + end + end + end + end + + class Textinput < TextinputBase + end + end + end + + add_maker("atom", "1.0", Atom::Feed) + add_maker("atom:feed", "1.0", Atom::Feed) + add_maker("atom1.0", "1.0", Atom::Feed) + add_maker("atom1.0:feed", "1.0", Atom::Feed) + end +end diff --git a/jni/ruby/lib/rss/maker/image.rb b/jni/ruby/lib/rss/maker/image.rb new file mode 100644 index 0000000..06084b4 --- /dev/null +++ b/jni/ruby/lib/rss/maker/image.rb @@ -0,0 +1,111 @@ +require 'rss/image' +require 'rss/maker/1.0' +require 'rss/maker/dublincore' + +module RSS + module Maker + module ImageItemModel + def self.append_features(klass) + super + + name = "#{RSS::IMAGE_PREFIX}_item" + klass.def_classed_element(name) + end + + def self.install_image_item(klass) + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + class ImageItem < ImageItemBase + DublinCoreModel.install_dublin_core(self) + end +EOC + end + + class ImageItemBase < Base + include Maker::DublinCoreModel + + attr_accessor :about, :resource, :image_width, :image_height + add_need_initialize_variable("about") + add_need_initialize_variable("resource") + add_need_initialize_variable("image_width") + add_need_initialize_variable("image_height") + alias width= image_width= + alias width image_width + alias height= image_height= + alias height image_height + + def have_required_values? + @about + end + + def to_feed(feed, current) + if current.respond_to?(:image_item=) and have_required_values? + item = current.class::ImageItem.new + setup_values(item) + setup_other_elements(item) + current.image_item = item + end + end + end + end + + module ImageFaviconModel + def self.append_features(klass) + super + + name = "#{RSS::IMAGE_PREFIX}_favicon" + klass.def_classed_element(name) + end + + def self.install_image_favicon(klass) + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + class ImageFavicon < ImageFaviconBase + DublinCoreModel.install_dublin_core(self) + end + EOC + end + + class ImageFaviconBase < Base + include Maker::DublinCoreModel + + attr_accessor :about, :image_size + add_need_initialize_variable("about") + add_need_initialize_variable("image_size") + alias size image_size + alias size= image_size= + + def have_required_values? + @about and @image_size + end + + def to_feed(feed, current) + if current.respond_to?(:image_favicon=) and have_required_values? + favicon = current.class::ImageFavicon.new + setup_values(favicon) + setup_other_elements(favicon) + current.image_favicon = favicon + end + end + end + end + + class ChannelBase; include Maker::ImageFaviconModel; end + + class ItemsBase + class ItemBase; include Maker::ImageItemModel; end + end + + makers.each do |maker| + maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + class Channel + ImageFaviconModel.install_image_favicon(self) + end + + class Items + class Item + ImageItemModel.install_image_item(self) + end + end + EOC + end + end +end diff --git a/jni/ruby/lib/rss/maker/itunes.rb b/jni/ruby/lib/rss/maker/itunes.rb new file mode 100644 index 0000000..8b7420d --- /dev/null +++ b/jni/ruby/lib/rss/maker/itunes.rb @@ -0,0 +1,242 @@ +require 'rss/itunes' +require 'rss/maker/2.0' + +module RSS + module Maker + module ITunesBaseModel + def def_class_accessor(klass, name, type, *args) + name = name.gsub(/-/, "_").gsub(/^itunes_/, '') + full_name = "#{RSS::ITUNES_PREFIX}_#{name}" + case type + when nil + klass.def_other_element(full_name) + when :yes_other + def_yes_other_accessor(klass, full_name) + when :yes_clean_other + def_yes_clean_other_accessor(klass, full_name) + when :csv + def_csv_accessor(klass, full_name) + when :element, :attribute + recommended_attribute_name, = *args + klass_name = "ITunes#{Utils.to_class_name(name)}" + klass.def_classed_element(full_name, klass_name, + recommended_attribute_name) + when :elements + plural_name, recommended_attribute_name = args + plural_name ||= "#{name}s" + full_plural_name = "#{RSS::ITUNES_PREFIX}_#{plural_name}" + klass_name = "ITunes#{Utils.to_class_name(name)}" + plural_klass_name = "ITunes#{Utils.to_class_name(plural_name)}" + def_elements_class_accessor(klass, name, full_name, full_plural_name, + klass_name, plural_klass_name, + recommended_attribute_name) + end + end + + def def_yes_other_accessor(klass, full_name) + klass.def_other_element(full_name) + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def #{full_name}? + Utils::YesOther.parse(@#{full_name}) + end + EOC + end + + def def_yes_clean_other_accessor(klass, full_name) + klass.def_other_element(full_name) + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def #{full_name}? + Utils::YesCleanOther.parse(#{full_name}) + end + EOC + end + + def def_csv_accessor(klass, full_name) + klass.def_csv_element(full_name) + end + + def def_elements_class_accessor(klass, name, full_name, full_plural_name, + klass_name, plural_klass_name, + recommended_attribute_name=nil) + if recommended_attribute_name + klass.def_classed_elements(full_name, recommended_attribute_name, + plural_klass_name, full_plural_name) + else + klass.def_classed_element(full_plural_name, plural_klass_name) + end + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + def new_#{full_name}(text=nil) + #{full_name} = @#{full_plural_name}.new_#{name} + #{full_name}.text = text + if block_given? + yield #{full_name} + else + #{full_name} + end + end + EOC + end + end + + module ITunesChannelModel + extend ITunesBaseModel + + class << self + def append_features(klass) + super + + ::RSS::ITunesChannelModel::ELEMENT_INFOS.each do |name, type, *args| + def_class_accessor(klass, name, type, *args) + end + end + end + + class ITunesCategoriesBase < Base + def_array_element("category", "itunes_categories", + "ITunesCategory") + class ITunesCategoryBase < Base + attr_accessor :text + add_need_initialize_variable("text") + def_array_element("category", "itunes_categories", + "ITunesCategory") + + def have_required_values? + text + end + + alias_method :to_feed_for_categories, :to_feed + def to_feed(feed, current) + if text and current.respond_to?(:itunes_category) + new_item = current.class::ITunesCategory.new(text) + to_feed_for_categories(feed, new_item) + current.itunes_categories << new_item + end + end + end + end + + class ITunesImageBase < Base + add_need_initialize_variable("href") + attr_accessor("href") + + def to_feed(feed, current) + if @href and current.respond_to?(:itunes_image) + current.itunes_image ||= current.class::ITunesImage.new + current.itunes_image.href = @href + end + end + end + + class ITunesOwnerBase < Base + %w(itunes_name itunes_email).each do |name| + add_need_initialize_variable(name) + attr_accessor(name) + end + + def to_feed(feed, current) + if current.respond_to?(:itunes_owner=) + _not_set_required_variables = not_set_required_variables + if (required_variable_names - _not_set_required_variables).empty? + return + end + + unless have_required_values? + raise NotSetError.new("maker.channel.itunes_owner", + _not_set_required_variables) + end + current.itunes_owner ||= current.class::ITunesOwner.new + current.itunes_owner.itunes_name = @itunes_name + current.itunes_owner.itunes_email = @itunes_email + end + end + + private + def required_variable_names + %w(itunes_name itunes_email) + end + end + end + + module ITunesItemModel + extend ITunesBaseModel + + class << self + def append_features(klass) + super + + ::RSS::ITunesItemModel::ELEMENT_INFOS.each do |name, type, *args| + def_class_accessor(klass, name, type, *args) + end + end + end + + class ITunesDurationBase < Base + attr_reader :content + add_need_initialize_variable("content") + + %w(hour minute second).each do |name| + attr_reader(name) + add_need_initialize_variable(name, 0) + end + + def content=(content) + if content.nil? + @hour, @minute, @second, @content = nil + else + @hour, @minute, @second = + ::RSS::ITunesItemModel::ITunesDuration.parse(content) + @content = content + end + end + + def hour=(hour) + @hour = Integer(hour) + update_content + end + + def minute=(minute) + @minute = Integer(minute) + update_content + end + + def second=(second) + @second = Integer(second) + update_content + end + + def to_feed(feed, current) + if @content and current.respond_to?(:itunes_duration=) + current.itunes_duration ||= current.class::ITunesDuration.new + current.itunes_duration.content = @content + end + end + + private + def update_content + components = [@hour, @minute, @second] + @content = + ::RSS::ITunesItemModel::ITunesDuration.construct(*components) + end + end + end + + class ChannelBase + include Maker::ITunesChannelModel + class ITunesCategories < ITunesCategoriesBase + class ITunesCategory < ITunesCategoryBase + ITunesCategory = self + end + end + + class ITunesImage < ITunesImageBase; end + class ITunesOwner < ITunesOwnerBase; end + end + + class ItemsBase + class ItemBase + include Maker::ITunesItemModel + class ITunesDuration < ITunesDurationBase; end + end + end + end +end diff --git a/jni/ruby/lib/rss/maker/slash.rb b/jni/ruby/lib/rss/maker/slash.rb new file mode 100644 index 0000000..27adef3 --- /dev/null +++ b/jni/ruby/lib/rss/maker/slash.rb @@ -0,0 +1,33 @@ +require 'rss/slash' +require 'rss/maker/1.0' + +module RSS + module Maker + module SlashModel + def self.append_features(klass) + super + + ::RSS::SlashModel::ELEMENT_INFOS.each do |name, type| + full_name = "#{RSS::SLASH_PREFIX}_#{name}" + case type + when :csv_integer + klass.def_csv_element(full_name, :integer) + else + klass.def_other_element(full_name) + end + end + + klass.module_eval do + alias_method(:slash_hit_parades, :slash_hit_parade) + alias_method(:slash_hit_parades=, :slash_hit_parade=) + end + end + end + + class ItemsBase + class ItemBase + include SlashModel + end + end + end +end diff --git a/jni/ruby/lib/rss/maker/syndication.rb b/jni/ruby/lib/rss/maker/syndication.rb new file mode 100644 index 0000000..b812304 --- /dev/null +++ b/jni/ruby/lib/rss/maker/syndication.rb @@ -0,0 +1,18 @@ +require 'rss/syndication' +require 'rss/maker/1.0' + +module RSS + module Maker + module SyndicationModel + def self.append_features(klass) + super + + ::RSS::SyndicationModel::ELEMENTS.each do |name| + klass.def_other_element(name) + end + end + end + + class ChannelBase; include SyndicationModel; end + end +end diff --git a/jni/ruby/lib/rss/maker/taxonomy.rb b/jni/ruby/lib/rss/maker/taxonomy.rb new file mode 100644 index 0000000..13ae9aa --- /dev/null +++ b/jni/ruby/lib/rss/maker/taxonomy.rb @@ -0,0 +1,118 @@ +require 'rss/taxonomy' +require 'rss/maker/1.0' +require 'rss/maker/dublincore' + +module RSS + module Maker + module TaxonomyTopicsModel + def self.append_features(klass) + super + + klass.def_classed_element("#{RSS::TAXO_PREFIX}_topics", + "TaxonomyTopics") + end + + def self.install_taxo_topics(klass) + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + class TaxonomyTopics < TaxonomyTopicsBase + def to_feed(feed, current) + if current.respond_to?(:taxo_topics) + topics = current.class::TaxonomyTopics.new + bag = topics.Bag + @resources.each do |resource| + bag.lis << RDF::Bag::Li.new(resource) + end + current.taxo_topics = topics + end + end + end +EOC + end + + class TaxonomyTopicsBase < Base + attr_reader :resources + def_array_element("resource") + remove_method :new_resource + end + end + + module TaxonomyTopicModel + def self.append_features(klass) + super + + class_name = "TaxonomyTopics" + klass.def_classed_elements("#{TAXO_PREFIX}_topic", "value", class_name) + end + + def self.install_taxo_topic(klass) + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + class TaxonomyTopics < TaxonomyTopicsBase + class TaxonomyTopic < TaxonomyTopicBase + DublinCoreModel.install_dublin_core(self) + TaxonomyTopicsModel.install_taxo_topics(self) + + def to_feed(feed, current) + if current.respond_to?(:taxo_topics) + topic = current.class::TaxonomyTopic.new(value) + topic.taxo_link = value + taxo_topics.to_feed(feed, topic) if taxo_topics + current.taxo_topics << topic + setup_other_elements(feed, topic) + end + end + end + end +EOC + end + + class TaxonomyTopicsBase < Base + def_array_element("topic", nil, "TaxonomyTopic") + alias_method(:new_taxo_topic, :new_topic) # For backward compatibility + + class TaxonomyTopicBase < Base + include DublinCoreModel + include TaxonomyTopicsModel + + attr_accessor :value + add_need_initialize_variable("value") + alias_method(:taxo_link, :value) + alias_method(:taxo_link=, :value=) + + def have_required_values? + @value + end + end + end + end + + class RSSBase + include TaxonomyTopicModel + end + + class ChannelBase + include TaxonomyTopicsModel + end + + class ItemsBase + class ItemBase + include TaxonomyTopicsModel + end + end + + makers.each do |maker| + maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + TaxonomyTopicModel.install_taxo_topic(self) + + class Channel + TaxonomyTopicsModel.install_taxo_topics(self) + end + + class Items + class Item + TaxonomyTopicsModel.install_taxo_topics(self) + end + end + EOC + end + end +end diff --git a/jni/ruby/lib/rss/maker/trackback.rb b/jni/ruby/lib/rss/maker/trackback.rb new file mode 100644 index 0000000..00f001c --- /dev/null +++ b/jni/ruby/lib/rss/maker/trackback.rb @@ -0,0 +1,61 @@ +require 'rss/trackback' +require 'rss/maker/1.0' +require 'rss/maker/2.0' + +module RSS + module Maker + module TrackBackModel + def self.append_features(klass) + super + + klass.def_other_element("#{RSS::TRACKBACK_PREFIX}_ping") + klass.def_classed_elements("#{RSS::TRACKBACK_PREFIX}_about", "value", + "TrackBackAbouts") + end + + class TrackBackAboutsBase < Base + def_array_element("about", nil, "TrackBackAbout") + + class TrackBackAboutBase < Base + attr_accessor :value + add_need_initialize_variable("value") + + alias_method(:resource, :value) + alias_method(:resource=, :value=) + alias_method(:content, :value) + alias_method(:content=, :value=) + + def have_required_values? + @value + end + + def to_feed(feed, current) + if current.respond_to?(:trackback_abouts) and have_required_values? + about = current.class::TrackBackAbout.new + setup_values(about) + setup_other_elements(about) + current.trackback_abouts << about + end + end + end + end + end + + class ItemsBase + class ItemBase; include TrackBackModel; end + end + + makers.each do |maker| + maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + class Items + class Item + class TrackBackAbouts < TrackBackAboutsBase + class TrackBackAbout < TrackBackAboutBase + end + end + end + end + EOC + end + end +end |