wonkavision 0.5.4 → 0.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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