1require "rss/rss"
2
3module RSS
4  DC_PREFIX = 'dc'
5  DC_URI = "http://purl.org/dc/elements/1.1/"
6
7  module BaseDublinCoreModel
8    def append_features(klass)
9      super
10
11      return if klass.instance_of?(Module)
12      DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
13        plural = plural_name || "#{name}s"
14        full_name = "#{DC_PREFIX}_#{name}"
15        full_plural_name = "#{DC_PREFIX}_#{plural}"
16        klass_name = "DublinCore#{Utils.to_class_name(name)}"
17        klass.install_must_call_validator(DC_PREFIX, DC_URI)
18        klass.install_have_children_element(name, DC_URI, "*",
19                                            full_name, full_plural_name)
20        klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
21          remove_method :#{full_name}
22          remove_method :#{full_name}=
23          remove_method :set_#{full_name}
24
25          def #{full_name}
26            @#{full_name}.first and @#{full_name}.first.value
27          end
28
29          def #{full_name}=(new_value)
30            @#{full_name}[0] = Utils.new_with_value_if_need(#{klass_name}, new_value)
31          end
32          alias set_#{full_name} #{full_name}=
33        EOC
34      end
35      klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
36        if method_defined?(:date)
37          alias date_without_#{DC_PREFIX}_date= date=
38
39          def date=(value)
40            self.date_without_#{DC_PREFIX}_date = value
41            self.#{DC_PREFIX}_date = value
42          end
43        else
44          alias date #{DC_PREFIX}_date
45          alias date= #{DC_PREFIX}_date=
46        end
47
48        # For backward compatibility
49        alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
50      EOC
51    end
52  end
53
54  module DublinCoreModel
55
56    extend BaseModel
57    extend BaseDublinCoreModel
58
59    TEXT_ELEMENTS = {
60      "title" => nil,
61      "description" => nil,
62      "creator" => nil,
63      "subject" => nil,
64      "publisher" => nil,
65      "contributor" => nil,
66      "type" => nil,
67      "format" => nil,
68      "identifier" => nil,
69      "source" => nil,
70      "language" => nil,
71      "relation" => nil,
72      "coverage" => nil,
73      "rights" => "rights_list"
74    }
75
76    DATE_ELEMENTS = {
77      "date" => "w3cdtf",
78    }
79
80    ELEMENT_NAME_INFOS = DublinCoreModel::TEXT_ELEMENTS.to_a
81    DublinCoreModel::DATE_ELEMENTS.each do |name, |
82      ELEMENT_NAME_INFOS << [name, nil]
83    end
84
85    ELEMENTS = TEXT_ELEMENTS.keys + DATE_ELEMENTS.keys
86
87    ELEMENTS.each do |name, plural_name|
88      module_eval(<<-EOC, *get_file_and_line_from_caller(0))
89        class DublinCore#{Utils.to_class_name(name)} < Element
90          include RSS10
91
92          content_setup
93
94          class << self
95            def required_prefix
96              DC_PREFIX
97            end
98
99            def required_uri
100              DC_URI
101            end
102          end
103
104          @tag_name = #{name.dump}
105
106          alias_method(:value, :content)
107          alias_method(:value=, :content=)
108
109          def initialize(*args)
110            if Utils.element_initialize_arguments?(args)
111              super
112            else
113              super()
114              self.content = args[0]
115            end
116          end
117
118          def full_name
119            tag_name_with_prefix(DC_PREFIX)
120          end
121
122          def maker_target(target)
123            target.new_#{name}
124          end
125
126          def setup_maker_attributes(#{name})
127            #{name}.content = content
128          end
129        end
130      EOC
131    end
132
133    DATE_ELEMENTS.each do |name, type|
134      tag_name = "#{DC_PREFIX}:#{name}"
135      module_eval(<<-EOC, *get_file_and_line_from_caller(0))
136        class DublinCore#{Utils.to_class_name(name)} < Element
137          remove_method(:content=)
138          remove_method(:value=)
139
140          date_writer("content", #{type.dump}, #{tag_name.dump})
141
142          alias_method(:value=, :content=)
143        end
144      EOC
145    end
146  end
147
148  # For backward compatibility
149  DublincoreModel = DublinCoreModel
150
151  DublinCoreModel::ELEMENTS.each do |name|
152    class_name = Utils.to_class_name(name)
153    BaseListener.install_class_name(DC_URI, name, "DublinCore#{class_name}")
154  end
155
156  DublinCoreModel::ELEMENTS.collect! {|name| "#{DC_PREFIX}_#{name}"}
157end
158
159require 'rss/dublincore/1.0'
160require 'rss/dublincore/2.0'
161require 'rss/dublincore/atom'
162