Created
October 8, 2008 13:44
-
-
Save michael/15520 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # namestorming | |
| # SteadyStateMachine | |
| # Workflowable | |
| # WorkflowEngine | |
| module DataMapper | |
| module Is | |
| module PersistentStateMachine | |
| class DmIsPersistentStateMachineException < Exception; end | |
| def self.included(base) | |
| base.extend ClassMethods | |
| end | |
| # -> FooStateTransition | |
| module Transition | |
| def self.included(base) | |
| base.extend ClassMethods | |
| end | |
| include DataMapper::Resource | |
| is :remixable | |
| property :id, Integer, :key => true, :serial => true | |
| property :guard, String | |
| #belongs_to :quote_event | |
| # alias event quote_event | |
| # def event | |
| # self.class | |
| # # self.quote_event | |
| # end | |
| module ClassMethods | |
| end | |
| end | |
| # -> FooState | |
| module State | |
| def self.included(base) | |
| base.extend ClassMethods | |
| end | |
| include DataMapper::Resource | |
| # def self.remix | |
| # def id | |
| property :id, Integer, :key => true, :serial => true | |
| property :code, String | |
| property :name, String, :length => 255 | |
| # not possible here, why?? | |
| # remix n, "DataMapper::Is::PersistentStateMachine::Transition", :as => "destinations", :for => 'self.name', :via => "target" | |
| def events | |
| evts = [] | |
| destinations.map do |transition| | |
| # uses the generic event method | |
| transition.event | |
| end | |
| end | |
| module ClassMethods | |
| end | |
| end | |
| # -> FooEvent | |
| module Event | |
| include DataMapper::Resource | |
| property :id, Integer, :key => true, :serial => true | |
| property :name, String | |
| end | |
| # this method is executed in the context of the base model on class level | |
| def is_persistent_state_machine(options = {}) | |
| @is_persistent_state_machine = true | |
| @prefix = options[:prefix] || self.name | |
| attr_accessor :my_instance_var | |
| # spielerei | |
| @my_instance_var = "blaaah" | |
| @@my_class_var = "blaaah" | |
| # adds class and instance methods to the base class? | |
| extend Forwardable | |
| extend DataMapper::Is::PersistentStateMachine::ClassMethods | |
| include DataMapper::Is::PersistentStateMachine::InstanceMethods | |
| # new property that holds the foo_state_id | |
| property Extlib::Inflection.foreign_key(@prefix+"State").to_sym, Integer | |
| belongs_to Extlib::Inflection.underscore(@prefix+"State").to_sym | |
| def_delegators :@state, :events, :destinations | |
| DataMapper.logger.info "Loading PersistentStateMachine Plugin" | |
| # will create FooState | |
| @state_model = model_from_context(DataMapper::Is::PersistentStateMachine::State) | |
| # will create FooStateTransition = Many-To-Many Unary relationship between FooState & FooState through transitions | |
| @state_model.send( | |
| :remix, n, | |
| "DataMapper::Is::PersistentStateMachine::Transition", | |
| :as => "destinations", | |
| :for => Extlib::Inflection.demodulize(@state_model.name), | |
| :via => "target" | |
| ) | |
| # will create FooEvent | |
| @event_model = model_from_context(DataMapper::Is::PersistentStateMachine::Event) | |
| # add belongs to FooEvent association to transition model | |
| @transition_model = Extlib::Inflection.constantize(self.name+"StateTransition") | |
| @transition_model.send(:property, Extlib::Inflection.foreign_key(@event_model.to_s).to_sym, Integer) | |
| @transition_model.send(:belongs_to, Extlib::Inflection.underscore(@event_model.to_s).to_sym) | |
| # alias FooEvent association | |
| @transition_model.send :define_method, 'event' do | |
| send(Extlib::Inflection.underscore(@event_model.to_s)) | |
| end | |
| self.send :define_method, 'hello_world' do | |
| "hello world" | |
| end | |
| # alias | |
| # DataMapper.logger.info "DDDDDD:"+ | |
| #transition_model.class_eval(<<-EOS, __FILE__, __LINE__ + 1) | |
| # alias :event #{} | |
| #EOS | |
| end | |
| module ClassMethods | |
| # e.g. model_from_context(state_module) | |
| def model_from_context(sub_module) | |
| # use caller class name as a prefix | |
| class_name = Extlib::Inflection.demodulize(self.name)+Extlib::Inflection.demodulize(sub_module.name) | |
| DataMapper.logger.info "dynamic class name:"+class_name | |
| klass = Class.new Object do | |
| include DataMapper::Resource | |
| end | |
| #Give remixed model a name and create its constant | |
| model = Object.full_const_set(class_name, klass) | |
| # get instance methods, class methods & validators | |
| model.send(:include,sub_module) | |
| # model.send(:extend,sub_module) | |
| # port the properties over... | |
| sub_module.properties.each do |prop| | |
| model.property(prop.name, prop.type, prop.options) | |
| end | |
| model | |
| end | |
| # def event_fk | |
| # demodulized_name = Extlib::Inflection.demodulize(self.name) | |
| # Extlib::Inflection.foreign_key(demodulized_name).to_sym | |
| # end | |
| end | |
| module InstanceMethods | |
| # just a convenience method | |
| def state | |
| #send(Extlib::Inflection.underscore(@state_model.to_s)) | |
| end | |
| end | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment