wonkavision 0.5.4 → 0.5.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/CHANGELOG.rdoc +28 -16
  2. data/Gemfile +5 -0
  3. data/LICENSE.txt +21 -21
  4. data/Rakefile +47 -47
  5. data/lib/wonkavision.rb +75 -74
  6. data/lib/wonkavision/acts_as_oompa_loompa.rb +22 -22
  7. data/lib/wonkavision/event_binding.rb +21 -21
  8. data/lib/wonkavision/event_context.rb +9 -9
  9. data/lib/wonkavision/event_coordinator.rb +75 -75
  10. data/lib/wonkavision/event_handler.rb +15 -15
  11. data/lib/wonkavision/event_namespace.rb +79 -79
  12. data/lib/wonkavision/event_path_segment.rb +35 -35
  13. data/lib/wonkavision/message_mapper.rb +30 -30
  14. data/lib/wonkavision/message_mapper/indifferent_access.rb +30 -26
  15. data/lib/wonkavision/message_mapper/map.rb +241 -153
  16. data/lib/wonkavision/persistence/mongo_mapper_adapter.rb +32 -32
  17. data/lib/wonkavision/persistence/mongoid_adapter.rb +32 -0
  18. data/lib/wonkavision/plugins.rb +30 -30
  19. data/lib/wonkavision/plugins/business_activity.rb +92 -92
  20. data/lib/wonkavision/plugins/business_activity/event_binding.rb +15 -15
  21. data/lib/wonkavision/plugins/callbacks.rb +182 -182
  22. data/lib/wonkavision/plugins/event_handling.rb +111 -111
  23. data/lib/wonkavision/plugins/timeline.rb +79 -79
  24. data/lib/wonkavision/version.rb +3 -3
  25. data/test/business_activity_test.rb +31 -31
  26. data/test/event_handler_test.rb +68 -69
  27. data/test/event_namespace_test.rb +108 -108
  28. data/test/event_path_segment_test.rb +41 -41
  29. data/test/log/test.log +817 -18354
  30. data/test/map_test.rb +315 -201
  31. data/test/message_mapper_test.rb +20 -20
  32. data/test/test_activity_models.rb +72 -72
  33. data/test/test_helper.rb +70 -63
  34. data/test/timeline_test.rb +55 -61
  35. data/test/wonkavision_test.rb +9 -9
  36. metadata +72 -12
  37. data/wonkavision.gemspec +0 -97
@@ -1,75 +1,75 @@
1
- module Wonkavision
2
- class EventCoordinator
3
-
4
- attr_reader :root_namespace
5
-
6
- def initialize
7
- @root_namespace = Wonkavision::EventNamespace.new
8
- @lock = Mutex.new
9
- #@event_cache = {}
10
- @incoming_event_filters = []
11
- end
12
-
13
- def before_receive_event(&block)
14
- @incoming_event_filters << block
15
- end
16
-
17
- def clear_filters
18
- @incoming_event_filters = []
19
- end
20
-
21
- def configure(&block)
22
- self.instance_eval(&block)
23
- end
24
-
25
- def map ()
26
- yield root_namespace if block_given?
27
- end
28
-
29
- def subscribe(event_path,final_segment_type=nil,&block)
30
- event_path, final_segment_type = *detect_final_segment(event_path) unless final_segment_type
31
- segment = (event_path.blank? ? root_namespace : root_namespace.find_or_create(event_path,final_segment_type))
32
- segment.subscribe(&block)
33
- end
34
-
35
- def receive_event(event_path, event_data)
36
- @lock.synchronize do
37
- #If process_incoming_event returns nil or false, it means a filter chose to abort
38
- #the event processing, in which case we'll break for lunch.
39
- return unless event_data = process_incoming_event(event_path,event_data)
40
-
41
- event_path = Wonkavision.normalize_event_path(event_path)
42
- targets = root_namespace.find_matching_segments(event_path).values
43
- #If the event wasn't matched, maybe someone is subscribing to '/*' ?
44
- targets = [root_namespace] if targets.blank?
45
- targets.each{|target|target.notify_subscribers(event_data,event_path)}
46
- end
47
- end
48
-
49
- protected
50
- def process_incoming_event(event_path,event_data)
51
- return nil unless event_data
52
- @incoming_event_filters.each do |filter_block|
53
- if (filter_block.arity < 1)
54
- event_data = event_data.instance_eval(&filter_block)
55
- elsif filter_block.arity == 1
56
- event_data = filter_block.call(event_data)
57
- else
58
- event_data = filter_block.call(event_data,event_path)
59
- end
60
- return nil unless event_data
61
- end
62
- event_data
63
- end
64
-
65
- def detect_final_segment(event_path)
66
- parts = Wonkavision.split(event_path)
67
- if parts[-1] == Wonkavision.namespace_wildcard_character
68
- [Wonkavision.join(parts.slice(0..-2)),:namespace]
69
- else
70
- [event_path,:event]
71
- end
72
- end
73
-
74
- end
75
- end
1
+ module Wonkavision
2
+ class EventCoordinator
3
+
4
+ attr_reader :root_namespace
5
+
6
+ def initialize
7
+ @root_namespace = Wonkavision::EventNamespace.new
8
+ @lock = Mutex.new
9
+ #@event_cache = {}
10
+ @incoming_event_filters = []
11
+ end
12
+
13
+ def before_receive_event(&block)
14
+ @incoming_event_filters << block
15
+ end
16
+
17
+ def clear_filters
18
+ @incoming_event_filters = []
19
+ end
20
+
21
+ def configure(&block)
22
+ self.instance_eval(&block)
23
+ end
24
+
25
+ def map ()
26
+ yield root_namespace if block_given?
27
+ end
28
+
29
+ def subscribe(event_path,final_segment_type=nil,&block)
30
+ event_path, final_segment_type = *detect_final_segment(event_path) unless final_segment_type
31
+ segment = (event_path.blank? ? root_namespace : root_namespace.find_or_create(event_path,final_segment_type))
32
+ segment.subscribe(&block)
33
+ end
34
+
35
+ def receive_event(event_path, event_data)
36
+ @lock.synchronize do
37
+ #If process_incoming_event returns nil or false, it means a filter chose to abort
38
+ #the event processing, in which case we'll break for lunch.
39
+ return unless event_data = process_incoming_event(event_path,event_data)
40
+
41
+ event_path = Wonkavision.normalize_event_path(event_path)
42
+ targets = root_namespace.find_matching_segments(event_path).values
43
+ #If the event wasn't matched, maybe someone is subscribing to '/*' ?
44
+ targets = [root_namespace] if targets.blank?
45
+ targets.each{|target|target.notify_subscribers(event_data,event_path)}
46
+ end
47
+ end
48
+
49
+ protected
50
+ def process_incoming_event(event_path,event_data)
51
+ return nil unless event_data
52
+ @incoming_event_filters.each do |filter_block|
53
+ if (filter_block.arity < 1)
54
+ event_data = event_data.instance_eval(&filter_block)
55
+ elsif filter_block.arity == 1
56
+ event_data = filter_block.call(event_data)
57
+ else
58
+ event_data = filter_block.call(event_data,event_path)
59
+ end
60
+ return nil unless event_data
61
+ end
62
+ event_data
63
+ end
64
+
65
+ def detect_final_segment(event_path)
66
+ parts = Wonkavision.split(event_path)
67
+ if parts[-1] == Wonkavision.namespace_wildcard_character
68
+ [Wonkavision.join(parts.slice(0..-2)),:namespace]
69
+ else
70
+ [event_path,:event]
71
+ end
72
+ end
73
+
74
+ end
75
+ end
@@ -1,15 +1,15 @@
1
- module Wonkavision
2
-
3
- module EventHandler
4
-
5
- def self.included(handler)
6
- handler.class_eval do
7
- extend Plugins
8
- use Plugins::EventHandling
9
- use Plugins::Callbacks
10
- end
11
-
12
- super
13
- end
14
- end
15
- end
1
+ module Wonkavision
2
+
3
+ module EventHandler
4
+
5
+ def self.included(handler)
6
+ handler.class_eval do
7
+ extend Plugins
8
+ use Plugins::EventHandling
9
+ use Plugins::Callbacks
10
+ end
11
+
12
+ super
13
+ end
14
+ end
15
+ end
@@ -1,79 +1,79 @@
1
- module Wonkavision
2
-
3
- class EventNamespace < EventPathSegment
4
-
5
- attr_reader :children
6
-
7
- def initialize(name=nil,namespace = nil,opts={})
8
- super name, namespace,opts
9
- @children=HashWithIndifferentAccess.new
10
- end
11
-
12
- def find_or_create (path, final_segment_type = :event)
13
- if path.is_a?(Array)
14
- child_name = path.shift
15
- segment_type = path.blank? ? final_segment_type : :namespace
16
- child = @children[child_name] ||= self.send(segment_type,child_name)
17
- return child if path.blank?
18
- raise "Events cannot have children. The path you requested is not valid" if child.is_a?(Wonkavision::Event)
19
- child.find_or_create(path,final_segment_type)
20
- else
21
- path = Wonkavision.normalize_event_path(path)
22
- source_ns = self
23
- if (Wonkavision.is_absolute_path(path)) #indicates an absolute path, because it begins with a '/'
24
- source_ns = root_namespace
25
- path = path[1..-1]
26
- end
27
- source_ns.find_or_create(path.split(Wonkavision.event_path_separator), final_segment_type)
28
- end
29
- end
30
-
31
- def find_matching_segments (event_path)
32
- selected = {}
33
- @children.each_value do |child|
34
- if (child.is_a?(Wonkavision::Event))
35
- select_segment(child,selected) if child.matches(event_path)
36
- elsif (child.is_a?(Wonkavision::EventNamespace))
37
- selected.merge!(child.find_matching_segments(event_path))
38
- else
39
- raise "An unexpected child type was encountered in find_matching_events #{child.class}"
40
- end
41
- end
42
- #If no child was found, and the event matches this namespace, we should add ourselves to the list.
43
- #This is not necessary if any child event was located, because in that case event notifications
44
- #would bubble up to us anyway. If no event was found, there's nobody to blow the bubble but us.
45
- select_segment(self,selected) if selected.blank? && matches_event(event_path)
46
- selected
47
- end
48
-
49
- def matches_event(event_path)
50
- Wonkavision.split(path) == Wonkavision.split(event_path).slice(0..-2)
51
- end
52
-
53
- #dsl
54
- def namespace(*args)
55
- return super if args.blank?
56
- name, opts = args.shift, (args.shift || {})
57
- ns = @children[name] || Wonkavision::EventNamespace.new(name,self,opts)
58
- yield ns if block_given?
59
- @children[ns.name] = ns
60
- ns
61
- end
62
-
63
- def event(*args)
64
- name, opts = args.shift, args.extract_options!
65
- opts[:source_events] = (opts[:source_events] || []).concat(args) unless args.blank?
66
- evt = @children[name] || Wonkavision::Event.new(name,self,opts)
67
- yield evt if block_given?
68
- @children[evt.name] = evt
69
- evt
70
- end
71
-
72
- private
73
- def select_segment(segment,selected)
74
- selected[segment.name] = segment
75
- select_segment(segment.namespace,selected) if segment.namespace
76
- end
77
-
78
- end
79
- end
1
+ module Wonkavision
2
+
3
+ class EventNamespace < EventPathSegment
4
+
5
+ attr_reader :children
6
+
7
+ def initialize(name=nil,namespace = nil,opts={})
8
+ super name, namespace,opts
9
+ @children=HashWithIndifferentAccess.new
10
+ end
11
+
12
+ def find_or_create (path, final_segment_type = :event)
13
+ if path.is_a?(Array)
14
+ child_name = path.shift
15
+ segment_type = path.blank? ? final_segment_type : :namespace
16
+ child = @children[child_name] ||= self.send(segment_type,child_name)
17
+ return child if path.blank?
18
+ raise "Events cannot have children. The path you requested is not valid" if child.is_a?(Wonkavision::Event)
19
+ child.find_or_create(path,final_segment_type)
20
+ else
21
+ path = Wonkavision.normalize_event_path(path)
22
+ source_ns = self
23
+ if (Wonkavision.is_absolute_path(path)) #indicates an absolute path, because it begins with a '/'
24
+ source_ns = root_namespace
25
+ path = path[1..-1]
26
+ end
27
+ source_ns.find_or_create(path.split(Wonkavision.event_path_separator), final_segment_type)
28
+ end
29
+ end
30
+
31
+ def find_matching_segments (event_path)
32
+ selected = {}
33
+ @children.each_value do |child|
34
+ if (child.is_a?(Wonkavision::Event))
35
+ select_segment(child,selected) if child.matches(event_path)
36
+ elsif (child.is_a?(Wonkavision::EventNamespace))
37
+ selected.merge!(child.find_matching_segments(event_path))
38
+ else
39
+ raise "An unexpected child type was encountered in find_matching_events #{child.class}"
40
+ end
41
+ end
42
+ #If no child was found, and the event matches this namespace, we should add ourselves to the list.
43
+ #This is not necessary if any child event was located, because in that case event notifications
44
+ #would bubble up to us anyway. If no event was found, there's nobody to blow the bubble but us.
45
+ select_segment(self,selected) if selected.blank? && matches_event(event_path)
46
+ selected
47
+ end
48
+
49
+ def matches_event(event_path)
50
+ Wonkavision.split(path) == Wonkavision.split(event_path).slice(0..-2)
51
+ end
52
+
53
+ #dsl
54
+ def namespace(*args)
55
+ return super if args.blank?
56
+ name, opts = args.shift, (args.shift || {})
57
+ ns = @children[name] || Wonkavision::EventNamespace.new(name,self,opts)
58
+ yield ns if block_given?
59
+ @children[ns.name] = ns
60
+ ns
61
+ end
62
+
63
+ def event(*args)
64
+ name, opts = args.shift, args.extract_options!
65
+ opts[:source_events] = (opts[:source_events] || []).concat(args) unless args.blank?
66
+ evt = @children[name] || Wonkavision::Event.new(name,self,opts)
67
+ yield evt if block_given?
68
+ @children[evt.name] = evt
69
+ evt
70
+ end
71
+
72
+ private
73
+ def select_segment(segment,selected)
74
+ selected[segment.name] = segment
75
+ select_segment(segment.namespace,selected) if segment.namespace
76
+ end
77
+
78
+ end
79
+ end
@@ -1,36 +1,36 @@
1
- module Wonkavision
2
- class EventPathSegment
3
- attr_reader :name, :namespace, :options, :subscribers
4
-
5
- def initialize(name = nil, namespace = nil, opts={})
6
- @name = name
7
- @namespace = namespace
8
- @options = opts
9
- @subscribers = []
10
- end
11
-
12
- def path
13
- Wonkavision.join(namespace.blank? ? nil : namespace.path,name)
14
- end
15
-
16
- def subscribe(&block)
17
- @subscribers << block
18
- self
19
- end
20
-
21
- def notify_subscribers(event_data, event_path=self.path)
22
- @subscribers.each do |sub|
23
- sub.call(event_data,event_path)
24
- end
25
- end
26
-
27
- def root_namespace
28
- cur_namespace = self
29
- while (cur_namespace.namespace)
30
- cur_namespace=cur_namespace.namespace
31
- end
32
- cur_namespace
33
- end
34
-
35
- end
1
+ module Wonkavision
2
+ class EventPathSegment
3
+ attr_reader :name, :namespace, :options, :subscribers
4
+
5
+ def initialize(name = nil, namespace = nil, opts={})
6
+ @name = name
7
+ @namespace = namespace
8
+ @options = opts
9
+ @subscribers = []
10
+ end
11
+
12
+ def path
13
+ Wonkavision.join(namespace.blank? ? nil : namespace.path,name)
14
+ end
15
+
16
+ def subscribe(&block)
17
+ @subscribers << block
18
+ self
19
+ end
20
+
21
+ def notify_subscribers(event_data, event_path=self.path)
22
+ @subscribers.each do |sub|
23
+ sub.call(event_data,event_path)
24
+ end
25
+ end
26
+
27
+ def root_namespace
28
+ cur_namespace = self
29
+ while (cur_namespace.namespace)
30
+ cur_namespace=cur_namespace.namespace
31
+ end
32
+ cur_namespace
33
+ end
34
+
35
+ end
36
36
  end
@@ -1,30 +1,30 @@
1
- module Wonkavision
2
-
3
- module MessageMapper
4
-
5
- class << self
6
- def maps
7
- @maps ||={}
8
- end
9
-
10
- def register(map_name,&block)
11
- MessageMapper.maps[map_name] = block
12
- end
13
-
14
- def execute(map,data_source)
15
- map_block = map.kind_of?(Proc) ? map : MessageMapper.maps[map]
16
-
17
- raise "#{map} not found" unless map_block
18
- message = MessageMapper::Map.new(data_source)
19
- message.instance_eval(&map_block)
20
- message
21
- end
22
-
23
- def register_map_directory(directory_path, recursive=true)
24
- searcher = "#{recursive ? "*" : "**/*"}.rb"
25
- Dir[File.join(directory_path,searcher)].each {|map| require map}
26
- end
27
- end
28
-
29
- end
30
- end
1
+ module Wonkavision
2
+
3
+ module MessageMapper
4
+
5
+ class << self
6
+ def maps
7
+ @maps ||={}
8
+ end
9
+
10
+ def register(map_name,&block)
11
+ MessageMapper.maps[map_name] = block
12
+ end
13
+
14
+ def execute(map,data_source)
15
+ map_block = map.kind_of?(Proc) ? map : MessageMapper.maps[map]
16
+
17
+ raise "#{map} not found" unless map_block
18
+ message = MessageMapper::Map.new(data_source)
19
+ message.instance_eval(&map_block)
20
+ message
21
+ end
22
+
23
+ def register_map_directory(directory_path, recursive=true)
24
+ searcher = "#{recursive ? "*" : "**/*"}.rb"
25
+ Dir[File.join(directory_path,searcher)].each {|map| require map}
26
+ end
27
+ end
28
+
29
+ end
30
+ end