1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
module Icalendar
module HasComponents
def self.included(base)
base.extend ClassMethods
base.class_eval do
attr_reader :custom_components
end
end
def initialize(*args)
@custom_components = Hash.new
super
end
def add_component(c)
c.parent = self
yield c if block_given?
send("#{c.name.downcase}s") << c
c
end
def add_custom_component(component_name, c)
c.parent = self
yield c if block_given?
(custom_components[component_name.downcase.gsub("-", "_")] ||= []) << c
c
end
def custom_component(component_name)
custom_components[component_name.downcase.gsub("-", "_")] || []
end
def method_missing(method, *args, &block)
method_name = method.to_s
if method_name =~ /^add_(x_\w+)$/
component_name = $1
custom = args.first || Component.new(component_name, component_name.upcase)
add_custom_component(component_name, custom, &block)
elsif method_name =~ /^x_/ && custom_component(method_name).size > 0
custom_component method_name
else
super
end
end
def respond_to_missing?(method_name, include_private = false)
string_method = method_name.to_s
string_method.start_with?('add_x_') || custom_component(string_method).size > 0 || super
end
module ClassMethods
def components
@components ||= []
end
def component(singular_name, find_by = :uid, klass = nil)
components = "#{singular_name}s"
self.components << components
component_var = "@#{components}"
define_method components do
if instance_variable_defined? component_var
instance_variable_get component_var
else
instance_variable_set component_var, []
end
end
define_method singular_name do |c = nil, &block|
if c.nil?
c = begin
klass ||= Icalendar.const_get singular_name.capitalize
klass.new
rescue NameError => ne
Icalendar.logger.warn ne.message
Component.new singular_name
end
end
add_component c, &block
end
define_method "find_#{singular_name}" do |id|
send(components).find { |c| c.send(find_by) == id }
end if find_by
define_method "add_#{singular_name}" do |c|
send singular_name, c
end
define_method "has_#{singular_name}?" do
!send(components).empty?
end
end
end
end
end
|