Skip to content

Commit

Permalink
renamed flow_handler to flow
Browse files Browse the repository at this point in the history
  • Loading branch information
kristianmandrup committed Aug 21, 2012
1 parent 2cb02bd commit c265e4c
Show file tree
Hide file tree
Showing 99 changed files with 167 additions and 274 deletions.
32 changes: 16 additions & 16 deletions README.md
Expand Up @@ -96,9 +96,9 @@ class ServicesController < ApplicationController
end end
``` ```


A `FlowHandler` can use Executors to encapsulate execution logic, which again can execute Commands that encapsulate business logic related to the user Session or models (data). A `Flow` can use Executors to encapsulate execution logic, which again can execute Commands that encapsulate business logic related to the user Session or models (data).


The FlowHandler takes the last event on the event stack and consults the ActionPaths registered, usually a Redirecter and Renderer. An ActionPath is a type of Action which can return a path. The FlowHandler initiates an Executor which iterates the ActionPaths to find the first one which can match the event. The Flow takes the last event on the event stack and consults the ActionPaths registered, usually a Redirecter and Renderer. An ActionPath is a type of Action which can return a path. The Flow initiates an Executor which iterates the ActionPaths to find the first one which can match the event.


The first one with a match is returned as the Action, which the controller can then perform in order to either render or redirect. The first one with a match is returned as the Action, which the controller can then perform in order to either render or redirect.


Expand All @@ -117,14 +117,14 @@ Using these Controll artifacts/systems, you can avoid the typical Rails anti-pat
The recommended approach to handle complex Controller logic using Controll: The recommended approach to handle complex Controller logic using Controll:


* Enable Controll on Controller * Enable Controll on Controller
* Configure Controller with FlowHandler, Commander and Notifier * Configure Controller with Flow, Commander and Notifier


* Create Commands for Commander * Create Commands for Commander
* Define events corresponding to commands * Define events corresponding to commands
* Configure Commander with Command methods * Configure Commander with Command methods


* Create FlowHandler * Create Flow
* Configure FlowHandler with Render and Redirect event mappings * Configure Flow with Render and Redirect event mappings


* Create Notifier * Create Notifier
* Configure Notifier with Event handlers and event -> message mappings * Configure Notifier with Event handlers and event -> message mappings
Expand Down Expand Up @@ -192,7 +192,7 @@ class ServicesController < ApplicationController
protected protected


def create_action def create_action
@create_action ||= FlowHandlers::CreateService.new(self) @create_action ||= Flows::CreateService.new(self)
end end


fallback do |event| fallback do |event|
Expand All @@ -217,7 +217,7 @@ class ServicesController
extend ActiveSupport::Concern extend ActiveSupport::Concern


included do included do
controll :notifier, :commander, :flow_handler controll :notifier, :commander, :flow
end end


def fallback_action def fallback_action
Expand Down Expand Up @@ -274,12 +274,12 @@ The `Commander class extends `Imperator::Command::MethodFactory` making `#comman


For how to implement the Commands themselves, see the [imperator-ext](https://github.com/kristianmandrup/imperator-ext) gem. For how to implement the Commands themselves, see the [imperator-ext](https://github.com/kristianmandrup/imperator-ext) gem.


## FlowHandlers ## Flows


For Controller actions that require complex flow control, use a FlowHandler: For Controller actions that require complex flow control, use a Flow:


```ruby ```ruby
module FlowHandlers module Flows
class CreateService < Master class CreateService < Master


# event method that returns the event to be processed by the flow handler # event method that returns the event to be processed by the flow handler
Expand Down Expand Up @@ -314,22 +314,22 @@ module FlowHandlers
end end
``` ```


The `#renderer` and `#redirector` macros will each create a Class of the same name that inherit from Controll::FlowHandler::ActionMapper::Simple or Controll::FlowHandler::ActionMapper::Complex. The `#renderer` and `#redirector` macros will each create a Class of the same name that inherit from Controll::Flow::ActionMapper::Simple or Controll::Flow::ActionMapper::Complex.
You can also define these classes directly yourself instead of using the macros. You can also define these classes directly yourself instead of using the macros.
The *simple* action mapper maps a list of events to a single path and otherwise falls back. The *simple* action mapper maps a list of events to a single path and otherwise falls back.
The complex action mapper maps the event to an event hash for each registered event type. The complex action mapper maps the event to an event hash for each registered event type.


In the `Redirecter` class we are setting up a mapping for various paths, for each path specifying which events should cause a redirect to that path. In the `Redirecter` class we are setting up a mapping for various paths, for each path specifying which events should cause a redirect to that path.


If you are rendering or redirecting to paths that take arguments, you can either extend the `#action` class method of your Redirect or Render class implementation or you can define a `#use_alternatives` method in your `FlowHandler` that contains this particular flow logic. If you are rendering or redirecting to paths that take arguments, you can either extend the `#action` class method of your Redirect or Render class implementation or you can define a `#use_alternatives` method in your `Flow` that contains this particular flow logic.


Note: For mapping paths that take arguments, there should be an option to take a block (closure) to be late-evaluated on the controller context ;) Note: For mapping paths that take arguments, there should be an option to take a block (closure) to be late-evaluated on the controller context ;)


## The Executor ## The Executor


The `Authenticator` class shown below inherits from `Executor::Notificator` which uses `#method_missing` in order to delegate any missing method back to the controller of the Executor. The FlowHandler passed in the controller. This means that calls can be executed directly on the controller, such as making notifications etc. The `Authenticator` class shown below inherits from `Executor::Notificator` which uses `#method_missing` in order to delegate any missing method back to the controller of the Executor. The Flow passed in the controller. This means that calls can be executed directly on the controller, such as making notifications etc.


The `#result` call at the end of `#execute` ensures that the last notification event is returned, to be used for deciding what to render or where to redirect (see FlowHandler). The `#result` call at the end of `#execute` ensures that the last notification event is returned, to be used for deciding what to render or where to redirect (see Flow).


```ruby ```ruby
module Executors module Executors
Expand Down Expand Up @@ -450,12 +450,12 @@ Generate only specific controll folders


* assistant * assistant
* executor * executor
* flow_handler * flow
* notifier * notifier


Example usage: Example usage:


`$ rails g controll:flow_handler create_service` `$ rails g controll:flow create_service`


Use `-h` for help on any specific controller for more usage options and info. Use `-h` for help on any specific controller for more usage options and info.


Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Expand Up @@ -18,7 +18,7 @@ Jeweler::Tasks.new do |gem|
gem.homepage = "http://github.com/kristianmandrup/controll" gem.homepage = "http://github.com/kristianmandrup/controll"
gem.license = "MIT" gem.license = "MIT"
gem.summary = %Q{Utils for handling complex Controller/Business logic} gem.summary = %Q{Utils for handling complex Controller/Business logic}
gem.description = %Q{FlowHandler, Executor, Notifier and more, all tied together tool pack} gem.description = %Q{Flow, Executor, Notifier and more, all tied together tool pack}
gem.email = "kmandrup@gmail.com" gem.email = "kmandrup@gmail.com"
gem.authors = ["Kristian Mandrup"] gem.authors = ["Kristian Mandrup"]
# dependencies defined in Gemfile # dependencies defined in Gemfile
Expand Down
30 changes: 15 additions & 15 deletions controll.gemspec
Expand Up @@ -10,7 +10,7 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Kristian Mandrup"] s.authors = ["Kristian Mandrup"]
s.date = "2012-08-16" s.date = "2012-08-16"
s.description = "FlowHandler, Executor, Notifier and more, all tied together tool pack" s.description = "Flow, Executor, Notifier and more, all tied together tool pack"
s.email = "kmandrup@gmail.com" s.email = "kmandrup@gmail.com"
s.extra_rdoc_files = [ s.extra_rdoc_files = [
"LICENSE.txt", "LICENSE.txt",
Expand All @@ -34,15 +34,15 @@ Gem::Specification.new do |s|
"lib/controll/executor.rb", "lib/controll/executor.rb",
"lib/controll/executor/base.rb", "lib/controll/executor/base.rb",
"lib/controll/executor/notificator.rb", "lib/controll/executor/notificator.rb",
"lib/controll/flow_handler.rb", "lib/controll/flow.rb",
"lib/controll/flow_handler/base.rb", "lib/controll/flow/base.rb",
"lib/controll/flow_handler/control.rb", "lib/controll/flow/control.rb",
"lib/controll/flow_handler/errors.rb", "lib/controll/flow/errors.rb",
"lib/controll/flow_handler/event_helper.rb", "lib/controll/flow/event_helper.rb",
"lib/controll/flow_handler/redirect.rb", "lib/controll/flow/redirect.rb",
"lib/controll/flow_handler/redirect/action.rb", "lib/controll/flow/redirect/action.rb",
"lib/controll/flow_handler/redirect/mapper.rb", "lib/controll/flow/redirect/mapper.rb",
"lib/controll/flow_handler/render.rb", "lib/controll/flow/render.rb",
"lib/controll/helper.rb", "lib/controll/helper.rb",
"lib/controll/helper/event_matcher.rb", "lib/controll/helper/event_matcher.rb",
"lib/controll/helper/hash_access.rb", "lib/controll/helper/hash_access.rb",
Expand Down Expand Up @@ -115,11 +115,11 @@ Gem::Specification.new do |s|
"spec/controll/command_spec.rb", "spec/controll/command_spec.rb",
"spec/controll/commander_spec.rb", "spec/controll/commander_spec.rb",
"spec/controll/executor/notificator_spec.rb", "spec/controll/executor/notificator_spec.rb",
"spec/controll/flow_handler/control_spec.rb", "spec/controll/flow/control_spec.rb",
"spec/controll/flow_handler/redirect/action_spec.rb", "spec/controll/flow/redirect/action_spec.rb",
"spec/controll/flow_handler/redirect/mapper_spec.rb", "spec/controll/flow/redirect/mapper_spec.rb",
"spec/controll/flow_handler/redirect_spec.rb", "spec/controll/flow/redirect_spec.rb",
"spec/controll/flow_handler/render_spec.rb", "spec/controll/flow/render_spec.rb",
"spec/controll/helper/event_matcher_spec.rb", "spec/controll/helper/event_matcher_spec.rb",
"spec/controll/helper/hash_access_spec.rb", "spec/controll/helper/hash_access_spec.rb",
"spec/controll/helper/notify_spec.rb", "spec/controll/helper/notify_spec.rb",
Expand Down
2 changes: 1 addition & 1 deletion lib/controll.rb
Expand Up @@ -9,7 +9,7 @@ module Controll
require 'controll/assistant' require 'controll/assistant'
require 'controll/executor' require 'controll/executor'
require 'controll/notify' require 'controll/notify'
require 'controll/flow_handler' require 'controll/flow'
require 'controll/helper' require 'controll/helper'
require 'controll/enabler' require 'controll/enabler'
require 'controll/command' require 'controll/command'
Expand Down
10 changes: 5 additions & 5 deletions lib/controll/enabler/macros.rb
Expand Up @@ -46,11 +46,11 @@ def notifier name, options = {}
end end
end end


def flow_handler name, options = {} def flow name, options = {}
define_method :flow_handler do define_method :flow do
unless instance_variable_get("@flow_handler") unless instance_variable_get("@flow")
clazz = "FlowHandlers::#{name.to_s.camelize}".constantize clazz = "Flows::#{name.to_s.camelize}".constantize
instance_variable_set "@flow_handler", clazz.new(self, options) instance_variable_set "@flow", clazz.new(self, options)
end end
end end
end end
Expand Down
6 changes: 3 additions & 3 deletions lib/controll/enabler/path_resolver.rb
Expand Up @@ -2,7 +2,7 @@ module Controll::Enabler
class PathResolver class PathResolver
attr_reader :caller, :event_map attr_reader :caller, :event_map


ActionMapper = Controll::FlowHandler::ActionMapper ActionMapper = Controll::Flow::ActionMapper


def initialize caller, event_map def initialize caller, event_map
@caller = caller @caller = caller
Expand Down Expand Up @@ -30,7 +30,7 @@ def handle action
else else
resolve_event resolve_event
end end
rescue Controll::FlowHandler::PathActionError rescue Controll::Flow::PathActionError
nil nil
end end


Expand All @@ -40,7 +40,7 @@ def resolve_event event = nil
end end


def mapper def mapper
@mapper ||= Controll::FlowHandler::EventMapper::Util.new main_event, event_map @mapper ||= Controll::Flow::EventMapper::Util.new main_event, event_map
end end
end end
end end
14 changes: 14 additions & 0 deletions lib/controll/flow.rb
@@ -0,0 +1,14 @@
require 'controll/flow/errors'

module Controll
module Flow
autoload :Master, 'controll/flow/master'
autoload :EventMapper, 'controll/flow/event_mapper'
autoload :ActionMapper, 'controll/flow/action_mapper'
end
end

module Flows
Master = Controll::Flow::Master
Flow = Controll::Flow::Master
end
10 changes: 10 additions & 0 deletions lib/controll/flow/action_mapper.rb
@@ -0,0 +1,10 @@
module Controll::Flow
module ActionMapper
autoload :Action, 'controll/flow/action_mapper/action'
autoload :PathAction, 'controll/flow/action_mapper/path_action'
autoload :Fallback, 'controll/flow/action_mapper/fallback'

autoload :Simple, 'controll/flow/action_mapper/simple'
autoload :Complex, 'controll/flow/action_mapper/complex'
end
end
@@ -1,4 +1,4 @@
module Controll::FlowHandler::ActionMapper module Controll::Flow::ActionMapper
class Action class Action
attr_reader :path, :controller, :errors attr_reader :path, :controller, :errors


Expand Down
@@ -1,4 +1,4 @@
module Controll::FlowHandler::ActionMapper module Controll::Flow::ActionMapper
class Complex < PathAction class Complex < PathAction
attr_reader :maps attr_reader :maps


Expand Down Expand Up @@ -43,7 +43,7 @@ def path_finder event
end end


def path_finder_class def path_finder_class
Controll::FlowHandler::EventMapper::PathFinder Controll::Flow::EventMapper::PathFinder
end end
end end
end end
Expand Down
@@ -1,4 +1,4 @@
module Controll::FlowHandler::ActionMapper module Controll::Flow::ActionMapper
class Fallback < Action class Fallback < Action
attr_reader :controller, :event attr_reader :controller, :event


Expand Down
@@ -1,4 +1,4 @@
module Controll::FlowHandler::ActionMapper module Controll::Flow::ActionMapper
class PathAction < Action class PathAction < Action
def perform def perform
raise BadPathError, "Bad path: #{path}" if path.blank? raise BadPathError, "Bad path: #{path}" if path.blank?
Expand Down
@@ -1,7 +1,7 @@
module Controll::FlowHandler::ActionMapper module Controll::Flow::ActionMapper
class Simple < PathAction class Simple < PathAction
NoEventsDefinedError = Controll::FlowHandler::NoEventsDefinedError NoEventsDefinedError = Controll::Flow::NoEventsDefinedError
NoDefaultPathDefinedError = Controll::FlowHandler::NoDefaultPathDefinedError NoDefaultPathDefinedError = Controll::Flow::NoDefaultPathDefinedError


# TODO: Should combine with Redirecter style, allowing for multiple render path mappings! # TODO: Should combine with Redirecter style, allowing for multiple render path mappings!
# This is fx useful for Wizards etc. where one Controller can render to many views, depending on state # This is fx useful for Wizards etc. where one Controller can render to many views, depending on state
Expand Down
@@ -1,4 +1,4 @@
module Controll::FlowHandler module Controll::Flow
class ActionEventError < StandardError; end class ActionEventError < StandardError; end


class EventNotImplementedError < StandardError; end class EventNotImplementedError < StandardError; end
Expand Down
6 changes: 6 additions & 0 deletions lib/controll/flow/event_mapper.rb
@@ -0,0 +1,6 @@
module Controll::Flow
module EventMapper
autoload :Util, 'controll/flow/event_mapper/util'
autoload :PathFinder, 'controll/flow/event_mapper/path_finder'
end
end
@@ -1,9 +1,9 @@
module Controll::FlowHandler module Controll::Flow
class EventMapper class EventMapper
class PathFinder class PathFinder
attr_accessor :event, :maps, :types attr_accessor :event, :maps, :types


NoMappingFoundError = Controll::FlowHandler::NoMappingFoundError NoMappingFoundError = Controll::Flow::NoMappingFoundError


# event <Event> # event <Event>
def initialize event, maps, types = [] def initialize event, maps, types = []
Expand All @@ -22,14 +22,14 @@ def path


protected protected


include Controll::FlowHandler::EventHelper include Controll::Flow::EventHelper


def event_map def event_map
@event_map ||= maps[event.type] || {} @event_map ||= maps[event.type] || {}
end end


def mapper def mapper
@mapper ||= Controll::FlowHandler::EventMapper::Util.new event, event_map @mapper ||= Controll::Flow::EventMapper::Util.new event, event_map
end end
end end
end end
Expand Down
@@ -1,9 +1,9 @@
module Controll::FlowHandler module Controll::Flow
module EventMapper module EventMapper
class Util class Util
attr_reader :event_map, :event attr_reader :event_map, :event


NoMappingFoundError = Controll::FlowHandler::NoMappingFoundError NoMappingFoundError = Controll::Flow::NoMappingFoundError


def initialize event, event_map def initialize event, event_map
@event ||= normalize event @event ||= normalize event
Expand Down
@@ -1,7 +1,7 @@
module Controll::FlowHandler module Controll::Flow
class Master class Master
autoload :Macros, 'controll/flow_handler/master/macros' autoload :Macros, 'controll/flow/master/macros'
autoload :Executor, 'controll/flow_handler/master/executor' autoload :Executor, 'controll/flow/master/executor'


include Macros include Macros


Expand Down Expand Up @@ -64,7 +64,7 @@ def action_handlers
end end


def event def event
raise Controll::FlowHandler::EventNotImplementedError, 'You must define an #event method that returns an event (or Symbol). You can use an Executor for this.' raise Controll::Flow::EventNotImplementedError, 'You must define an #event method that returns an event (or Symbol). You can use an Executor for this.'
end end
end end
end end
@@ -1,10 +1,10 @@
module Controll::FlowHandler module Controll::Flow
class Master class Master
class Executor < Controll::Executor::Base class Executor < Controll::Executor::Base
FlowHandler = Controll::FlowHandler Flow = Controll::Flow


NoEventsDefinedError = FlowHandler::NoEventsDefinedError NoEventsDefinedError = Flow::NoEventsDefinedError
NoMappingFoundError = FlowHandler::NoMappingFoundError NoMappingFoundError = Flow::NoMappingFoundError


def initialize initiator, options = {} def initialize initiator, options = {}
super super
Expand Down Expand Up @@ -40,7 +40,7 @@ def fallback
end end


def fallback_class def fallback_class
FlowHandler::ActionMapper::Fallback Flow::ActionMapper::Fallback
end end


def action_handlers def action_handlers
Expand Down

0 comments on commit c265e4c

Please sign in to comment.