e56d9624a83dbc33802d7f1d0594ea6746c7a9cd
[god.git] / lib / god / condition.rb
blobe56d9624a83dbc33802d7f1d0594ea6746c7a9cd
1 module God
2   
3   class Condition < Behavior
4     attr_accessor :transition, :notify, :info
5     
6     # Generate a Condition of the given kind. The proper class if found by camel casing the
7     # kind (which is given as an underscored symbol).
8     #   +kind+ is the underscored symbol representing the class (e.g. :foo_bar for God::Conditions::FooBar)
9     def self.generate(kind, watch)
10       sym = kind.to_s.capitalize.gsub(/_(.)/){$1.upcase}.intern
11       c = God::Conditions.const_get(sym).new
12       
13       unless c.kind_of?(PollCondition) || c.kind_of?(EventCondition) || c.kind_of?(TriggerCondition)
14         abort "Condition '#{c.class.name}' must subclass God::PollCondition, God::EventCondition, or God::TriggerCondition" 
15       end
16       
17       c.watch = watch
18       c
19     rescue NameError
20       raise NoSuchConditionError.new("No Condition found with the class name God::Conditions::#{sym}")
21     end
22     
23     def self.valid?(condition)
24       valid = true
25       if condition.notify
26         begin
27           Contact.normalize(condition.notify)
28         rescue ArgumentError => e
29           valid &= Configurable.complain("Attribute 'notify' " + e.message, condition)
30         end
31       end
32       valid
33     end
34     
35     # Construct the friendly name of this Condition, looks like:
36     #
37     # Condition FooBar on Watch 'baz'
38     def friendly_name
39       "Condition #{self.class.name.split('::').last} on Watch '#{self.watch.name}'"
40     end
41   end
42   
43   class PollCondition < Condition
44     # all poll conditions can specify a poll interval 
45     attr_accessor :interval
46     
47     # Override this method in your Conditions (optional)
48     def before
49     end
50     
51     # Override this method in your Conditions (mandatory)
52     #
53     # Return true if the test passes (everything is ok)
54     # Return false otherwise
55     def test
56       raise AbstractMethodNotOverriddenError.new("PollCondition#test must be overridden in subclasses")
57     end
58     
59     # Override this method in your Conditions (optional)
60     def after
61     end
62   end
63   
64   class EventCondition < Condition
65     def register
66       raise AbstractMethodNotOverriddenError.new("EventCondition#register must be overridden in subclasses")
67     end
68     
69     def deregister
70       raise AbstractMethodNotOverriddenError.new("EventCondition#deregister must be overridden in subclasses")
71     end
72   end
73   
74   class TriggerCondition < Condition
75     def process(event, payload)
76       raise AbstractMethodNotOverriddenError.new("TriggerCondition#process must be overridden in subclasses")
77     end
78     
79     def trigger
80       Hub.trigger(self)
81     end
82     
83     def register
84       Trigger.register(self)
85     end
86     
87     def deregister
88       Trigger.deregister(self)
89     end
90   end
91   
92 end