1require 'rss/1.0' 2require 'rss/2.0' 3 4module RSS 5 6 TRACKBACK_PREFIX = 'trackback' 7 TRACKBACK_URI = 'http://madskills.com/public/xml/rss/module/trackback/' 8 9 RDF.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI) 10 Rss.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI) 11 12 module TrackBackUtils 13 private 14 def trackback_validate(ignore_unknown_element, tags, uri) 15 return if tags.nil? 16 if tags.find {|tag| tag == "about"} and 17 !tags.find {|tag| tag == "ping"} 18 raise MissingTagError.new("#{TRACKBACK_PREFIX}:ping", tag_name) 19 end 20 end 21 end 22 23 module BaseTrackBackModel 24 25 ELEMENTS = %w(ping about) 26 27 def append_features(klass) 28 super 29 30 unless klass.class == Module 31 klass.module_eval {include TrackBackUtils} 32 33 klass.install_must_call_validator(TRACKBACK_PREFIX, TRACKBACK_URI) 34 %w(ping).each do |name| 35 var_name = "#{TRACKBACK_PREFIX}_#{name}" 36 klass_name = "TrackBack#{Utils.to_class_name(name)}" 37 klass.install_have_child_element(name, TRACKBACK_URI, "?", var_name) 38 klass.module_eval(<<-EOC, __FILE__, __LINE__) 39 remove_method :#{var_name} 40 def #{var_name} 41 @#{var_name} and @#{var_name}.value 42 end 43 44 remove_method :#{var_name}= 45 def #{var_name}=(value) 46 @#{var_name} = Utils.new_with_value_if_need(#{klass_name}, value) 47 end 48 EOC 49 end 50 51 [%w(about s)].each do |name, postfix| 52 var_name = "#{TRACKBACK_PREFIX}_#{name}" 53 klass_name = "TrackBack#{Utils.to_class_name(name)}" 54 klass.install_have_children_element(name, TRACKBACK_URI, "*", 55 var_name) 56 klass.module_eval(<<-EOC, __FILE__, __LINE__) 57 remove_method :#{var_name} 58 def #{var_name}(*args) 59 if args.empty? 60 @#{var_name}.first and @#{var_name}.first.value 61 else 62 ret = @#{var_name}.__send__("[]", *args) 63 if ret.is_a?(Array) 64 ret.collect {|x| x.value} 65 else 66 ret.value 67 end 68 end 69 end 70 71 remove_method :#{var_name}= 72 remove_method :set_#{var_name} 73 def #{var_name}=(*args) 74 if args.size == 1 75 item = Utils.new_with_value_if_need(#{klass_name}, args[0]) 76 @#{var_name}.push(item) 77 else 78 new_val = args.last 79 if new_val.is_a?(Array) 80 new_val = new_value.collect do |val| 81 Utils.new_with_value_if_need(#{klass_name}, val) 82 end 83 else 84 new_val = Utils.new_with_value_if_need(#{klass_name}, new_val) 85 end 86 @#{var_name}.__send__("[]=", *(args[0..-2] + [new_val])) 87 end 88 end 89 alias set_#{var_name} #{var_name}= 90 EOC 91 end 92 end 93 end 94 end 95 96 module TrackBackModel10 97 extend BaseModel 98 extend BaseTrackBackModel 99 100 class TrackBackPing < Element 101 include RSS10 102 103 class << self 104 105 def required_prefix 106 TRACKBACK_PREFIX 107 end 108 109 def required_uri 110 TRACKBACK_URI 111 end 112 113 end 114 115 @tag_name = "ping" 116 117 [ 118 ["resource", ::RSS::RDF::URI, true] 119 ].each do |name, uri, required| 120 install_get_attribute(name, uri, required, nil, nil, 121 "#{::RSS::RDF::PREFIX}:#{name}") 122 end 123 124 alias_method(:value, :resource) 125 alias_method(:value=, :resource=) 126 def initialize(*args) 127 if Utils.element_initialize_arguments?(args) 128 super 129 else 130 super() 131 self.resource = args[0] 132 end 133 end 134 135 def full_name 136 tag_name_with_prefix(TRACKBACK_PREFIX) 137 end 138 end 139 140 class TrackBackAbout < Element 141 include RSS10 142 143 class << self 144 145 def required_prefix 146 TRACKBACK_PREFIX 147 end 148 149 def required_uri 150 TRACKBACK_URI 151 end 152 153 end 154 155 @tag_name = "about" 156 157 [ 158 ["resource", ::RSS::RDF::URI, true] 159 ].each do |name, uri, required| 160 install_get_attribute(name, uri, required, nil, nil, 161 "#{::RSS::RDF::PREFIX}:#{name}") 162 end 163 164 alias_method(:value, :resource) 165 alias_method(:value=, :resource=) 166 167 def initialize(*args) 168 if Utils.element_initialize_arguments?(args) 169 super 170 else 171 super() 172 self.resource = args[0] 173 end 174 end 175 176 def full_name 177 tag_name_with_prefix(TRACKBACK_PREFIX) 178 end 179 180 private 181 def maker_target(abouts) 182 abouts.new_about 183 end 184 185 def setup_maker_attributes(about) 186 about.resource = self.resource 187 end 188 189 end 190 end 191 192 module TrackBackModel20 193 extend BaseModel 194 extend BaseTrackBackModel 195 196 class TrackBackPing < Element 197 include RSS09 198 199 @tag_name = "ping" 200 201 content_setup 202 203 class << self 204 205 def required_prefix 206 TRACKBACK_PREFIX 207 end 208 209 def required_uri 210 TRACKBACK_URI 211 end 212 213 end 214 215 alias_method(:value, :content) 216 alias_method(:value=, :content=) 217 218 def initialize(*args) 219 if Utils.element_initialize_arguments?(args) 220 super 221 else 222 super() 223 self.content = args[0] 224 end 225 end 226 227 def full_name 228 tag_name_with_prefix(TRACKBACK_PREFIX) 229 end 230 231 end 232 233 class TrackBackAbout < Element 234 include RSS09 235 236 @tag_name = "about" 237 238 content_setup 239 240 class << self 241 242 def required_prefix 243 TRACKBACK_PREFIX 244 end 245 246 def required_uri 247 TRACKBACK_URI 248 end 249 250 end 251 252 alias_method(:value, :content) 253 alias_method(:value=, :content=) 254 255 def initialize(*args) 256 if Utils.element_initialize_arguments?(args) 257 super 258 else 259 super() 260 self.content = args[0] 261 end 262 end 263 264 def full_name 265 tag_name_with_prefix(TRACKBACK_PREFIX) 266 end 267 268 end 269 end 270 271 class RDF 272 class Item; include TrackBackModel10; end 273 end 274 275 class Rss 276 class Channel 277 class Item; include TrackBackModel20; end 278 end 279 end 280 281 BaseTrackBackModel::ELEMENTS.each do |name| 282 class_name = Utils.to_class_name(name) 283 BaseListener.install_class_name(TRACKBACK_URI, name, 284 "TrackBack#{class_name}") 285 end 286 287 BaseTrackBackModel::ELEMENTS.collect! {|name| "#{TRACKBACK_PREFIX}_#{name}"} 288end 289