Class Icalendar::Component
In: lib/icalendar/component.rb
Parent: Icalendar::Base

The body of the iCalendar object consists of a sequence of calendar properties and one or more calendar components. The calendar properties are attributes that apply to the calendar as a whole. The calendar components are collections of properties that express a particular calendar semantic. For example, the calendar component can specify an Event, a Todo, a Journal entry, Timezone information, or Freebusy time information, or an Alarm.

Methods

Attributes

name  [R] 
properties  [RW] 
property_params  [RW] 

Public Class methods

[Source]

    # File lib/icalendar/component.rb, line 26
26:     def initialize(name)
27:       @name = name
28:       @components = Hash.new([])
29:       @properties = {}
30:       @property_params = {}
31: 
32:       @@logger.info("New #{@name[1,@name.size].capitalize}...")
33:     end

Protected Class methods

Make it protected so we can monitor usage…

[Source]

     # File lib/icalendar/component.rb, line 129
129:     def Component.ical_component(*syms)
130:       hash_accessor :components, syms
131:     end

Define a set of methods defining a new property, which supports multiple values for the same property name.

[Source]

     # File lib/icalendar/component.rb, line 201
201:     def Component.ical_multi_property(property, singular, plural)
202:       property = "#{property}".strip.upcase
203:       singular = "#{singular}".strip.downcase
204:       plural = "#{plural}".strip.downcase
205: 
206:       getter = "#{plural}"
207:       setter = "#{plural}="
208:       adder = "add_#{singular}"
209:       remover = "remove_#{singular}"
210:       query = "#{plural}?"
211: 
212:       # Set this key so the parser knows to use an array for
213:       # storing this property type.
214:       @@multi_properties["#{property}"] = true
215: 
216:       # Getter for whole array
217:       unless instance_methods.include? getter
218:         code = "def \#{getter}(*a)\nif a.empty?\nif @properties.has_key?(\"\#{property}\")\n@properties[\"\#{property}\"]\nelse\n[]\nend\nelse\nself.\#{setter}(a.first)\nend\nend\n"
219: 
220:         class_eval code, "component.rb", 186
221:       end
222: 
223:       # Setter for whole array
224:       unless instance_methods.include? setter
225:         code = "def \#{setter}(a)\nif a.respond_to?(:to_ary)\na.to_ary.each do |val|\nunless val.respond_to?(:to_ical)\nraise(NotImplementedError, \"Property values do not support to_ical method!\")\nend\nend\n\n@properties[\"\#{property}\"] = a.to_ary\n\nelse\nraise ArgumentError, \"\#{getter} is a multi-property that must be an array! Use the \#{adder} method to add single entries.\"\nend\nend\n"
226: 
227:         class_eval code, "component.rb", 198
228:       end
229: 
230:       # Query for any of these properties
231:       unless instance_methods.include? query
232:         code = "def \#{query}\n@properties.has_key?(\"\#{property}\")\nend\n"
233: 
234:         class_eval code, "component.rb", 210
235:       end
236: 
237:       # Add another item to this properties array
238:       unless instance_methods.include? adder
239:         code = "def \#{adder}(val, params = {})\nunless val.respond_to?(:to_ical)\nraise(NotImplementedError, \"Property value object does not support to_ical method!\")\nend\n\nif @properties.has_key?(\"\#{property}\")\n@properties[\"\#{property}\"] << val\nelse\n@properties[\"\#{property}\"] = [val]\nend\nend\n"
240: 
241:         class_eval code, "component.rb", 228
242:         alias_method("add_#{property.downcase}", "#{adder}") 
243:       end
244: 
245:       # Remove an item from this properties array
246:       unless instance_methods.include? remover
247:         code = "def \#{remover}(a)\nif @properties.has_key?(\"\#{property}\")\n@properties[\"\#{property}\"].delete(a)\nend\nend\n"
248: 
249:         class_eval code, "component.rb", 241
250:         alias_method("remove_#{property.downcase}", "#{remover}")
251:       end
252: 
253:     end

Define a set of methods supporting a new property

[Source]

     # File lib/icalendar/component.rb, line 134
134:     def Component.ical_property(property, alias_name = nil, prop_name = nil)
135: 
136:       property = "#{property}".strip.downcase
137:       getter = "#{property}"
138:       setter = "#{property}="
139:       query = "#{property}?"
140:       alias_name = "#{alias_name}".strip.downcase unless alias_name.nil?
141: 
142:       # If a prop_name was given then we use that for the actual storage
143:       property = "#{prop_name}".strip.upcase unless prop_name.nil?
144: 
145:       # Change underscores in property name to a dash
146:       property[/_/] = '-' if property =~ /_/
147: 
148:       # All properties names are stored in caps...
149:       property = property.upcase
150: 
151:       unless instance_methods.include? getter
152:         code = "def \#{getter}(val = nil, params = {})\nif val.nil?\n@properties[\"\#{property}\"]\nelse\n# Set the value just like normal\nself.\#{setter}(val)\nend\nend\n"
153: 
154:         class_eval code, "component.rb", 155
155:         alias_method("#{alias_name}", "#{getter}") unless alias_name.nil?
156:       end
157: 
158:       unless instance_methods.include? setter
159:         code = "def \#{setter}(val)\nunless val.respond_to?(:to_ical)\nraise(NotImplementedError, \"Value of type (\" + val.class.to_s + \") does not support to_ical method!\")\nend\n\n@properties[\"\#{property}\"] = val\nend\n"
160: 
161:         class_eval code, "component.rb", 171
162: 
163:         alias_method("#{alias_name}=", "#{setter}") unless alias_name.nil?
164:       end
165: 
166:       unless instance_methods.include? query
167:         code = "def \#{query}\n@properties.has_key?(\"\#{property}\")\nend\n"
168: 
169:         class_eval code, "component.rb", 183
170: 
171:         alias_method("#{alias_name}\?", "#{query}") unless alias_name.nil?
172:       end    
173:     end

Public Instance methods

add(component)

Alias for add_component

Add a sub-component to the current component object.

[Source]

    # File lib/icalendar/component.rb, line 36
36:     def add_component(component)
37:       key = (component.class.to_s.downcase + 's').gsub('icalendar::', '').to_sym
38: 
39:       unless @components.has_key? key
40:         @components[key] = []
41:       end
42: 
43:       @components[key] << component
44:     end

TODO: Look into the x-property, x-param stuff…

[Source]

     # File lib/icalendar/component.rb, line 118
118:     def custom_property(name, value)
119:       @properties[name] = value
120:     end

[Source]

     # File lib/icalendar/component.rb, line 122
122:     def multi_property?(name)
123:       @@multi_properties.has_key?(name.upcase)
124:     end

Print this icalendar component

[Source]

    # File lib/icalendar/component.rb, line 57
57:     def print_component
58:       s = ""
59: 
60:       # Begin a new component
61:       s << "BEGIN:#{@name.upcase}\r\n"
62: 
63:       # Then the properties
64:       print_properties(s)
65: 
66:       # Any custom body of the derived component
67:       yield(s)
68: 
69:       # End of this component
70:       s << "END:#{@name.upcase}\r\n"
71:     end

Print the parameters for a specific property

[Source]

     # File lib/icalendar/component.rb, line 94
 94:     def print_parameter(s, key, value)
 95:       if @property_params.has_key?(key) 
 96:         params = @property_params[key]
 97:         params.each do |key,val|
 98:           s << ";#{key}"
 99:           val = [ val ] unless val.respond_to?(:to_ary)
100: 
101:           # Possible parameter values
102:           unless val.empty?
103:             s << "="
104:             sep = "" # First entry comes after = sign, but then we need commas
105:             val.each do |pval| 
106:               if pval.respond_to? :to_ical 
107:                 s << sep << pval.to_ical
108:                 sep = ","
109:               end
110:             end
111:           end
112: 
113:         end
114:       end
115:     end

Print this components properties

[Source]

    # File lib/icalendar/component.rb, line 74
74:     def print_properties(s)
75:       @properties.each do |key,value| 
76:         # Take out underscore for property names that conflicted
77:         # with built-in words.
78:         if key =~ /ip_.*/
79:           key = key[3..-1]
80:         end
81: 
82:         # Property name
83:         s << "#{key.upcase}"
84: 
85:         # Possible parameters
86:         print_parameter(s, key, value)
87: 
88:         # Property value
89:         s << ":#{value.to_ical}\r\n" 
90:       end
91:     end

[Source]

     # File lib/icalendar/component.rb, line 333
333:     def respond_to?(method_name)
334:       unless method_name.to_s.downcase =~ /x-.*/
335:         super
336:       end
337: 
338:       true
339:     end

[Source]

    # File lib/icalendar/component.rb, line 48
48:     def to_ical
49:       print_component do |s|
50:         @components.each_value do |comps|
51:           comps.each { |component| s << component.to_ical }
52:         end
53:       end
54:     end

Protected Instance methods

[Source]

     # File lib/icalendar/component.rb, line 309
309:     def method_missing(method_name, *args)
310:       method_name = method_name.to_s.downcase
311: 
312:       unless method_name =~ /x_.*/
313:         raise NoMethodError
314:       end
315: 
316:       val = args.first
317: 
318:       unless val.respond_to?(:to_ical)
319:         raise(NotImplementedError, "Value of type (" + val.class.to_s + ") does not support to_ical method!")
320:       end
321: 
322:       if method_name =~ /(.*)(=)/ # Its a setter
323:         @properties[$1] = val
324:         @@logger.debug("Setting #{$1} => #{val}")
325:       else # Or its a getter
326:         @@logger.debug("Getting #{method_name} => #{@properties[method_name]}")
327:         return @properties[method_name]
328:       end
329:     end

[Validate]