lib/openwfe/extras/participants/activeparticipants.rb in openwferu-extras-0.9.13 vs lib/openwfe/extras/participants/activeparticipants.rb in openwferu-extras-0.9.14

- old
+ new

@@ -41,16 +41,19 @@ require_gem 'activerecord' require 'openwfe/workitem' require 'openwfe/flowexpressionid' +require 'openwfe/engine/engine' require 'openwfe/participants/participant' module OpenWFE module Extras + MUTEX = Mutex.new + # # The migration for ActiveParticipant and associated classes. # # There are two tables 'workitems' and 'fields'. As its name implies, # the latter table stores the fields (also called attributes in OpenWFE @@ -68,18 +71,23 @@ t.column :fei, :string t.column :wfid, :string t.column :wf_name, :string t.column :wf_revision, :string t.column :participant_name, :string - t.column :store, :string + t.column :store_name, :string + t.column :dispatch_time, :timestamp + t.column :last_modified, :timestamp end create_table :fields do |t| t.column :key, :string, :null => false - t.column :value, :text + t.column :svalue, :string + t.column :yvalue, :text t.column :workitem_id, :integer, :null => false end - add_index :fields, [ :workitem_id, :key], :unique => true + add_index :fields, [ :workitem_id, :key ], :unique => true + add_index :fields, :key + add_index :fields, :svalue end def self.down drop_table :workitems drop_table :fields end @@ -130,29 +138,39 @@ # # Generates a (new) Workitem from an OpenWFEru InFlowWorkItem instance. # # This is a 'static' method : # - # awi = OpenWFE::Densha::Workitem.from_owfe_workitem(wi) + # awi = OpenWFE::Extras::Workitem.from_owfe_workitem(wi) # # (This method will not save the 'ActiveWorkitem'). # - def self.from_owfe_workitem (wi) + def Workitem.from_owfe_workitem (wi, store_name=nil) - i = Workitem.new - i.fei = wi.fei.to_s - i.wfid = wi.fei.wfid - i.wf_name = wi.fei.workflow_definition_name - i.wf_revision = wi.fei.workflow_definition_revision - i.participant_name = wi.participant_name + i = nil - wi.attributes.each do |k, v| - f = Field.new - f.key = k - f.value = v - i.fields << f + MUTEX.synchronize do + + i = Workitem.new + i.fei = wi.fei.to_s + i.wfid = wi.fei.wfid + i.wf_name = wi.fei.workflow_definition_name + i.wf_revision = wi.fei.workflow_definition_revision + i.participant_name = wi.participant_name + i.dispatch_time = wi.dispatch_time + i.last_modified = nil + + i.store_name = store_name + + wi.attributes.each do |k, v| + i.fields << Field.new_field(k, v) + end + + i.save! + end + i end # # Turns the densha Workitem into an OpenWFEru InFlowWorkItem. @@ -161,10 +179,11 @@ wi = OpenWFE::InFlowWorkItem.new wi.fei = full_fei wi.participant_name = participant_name wi.attributes = fields_hash + # don't care about dispatch_time and last_modified wi end # # Returns a hash version of the 'fields' of this workitem. @@ -179,10 +198,30 @@ end h end # + # Replaces the current fields of this workitem with the given hash. + # + # This method modifies the content of the db. + # + def replace_fields (fhash) + + fields.delete_all + + fhash.each do |k, v| + fields << Field.new_field(k, v) + end + + #f = Field.new_field("___map_type", "smap") + # + # an old trick for backward compatibility with OpenWFEja + + save! + end + + # # Returns the Field instance with the given key. This method accept # symbols as well as strings as its parameter. # # wi.field("customer_name") # wi.field :customer_name @@ -205,19 +244,62 @@ self.destroy end alias :forward :reply alias :proceed :reply + + # + # Opening engine to update its reply method to accept these + # active record workitems. + # + class OpenWFE::Engine + + alias :oldreply :reply + + def reply (workitem) + + if workitem.is_a?(Workitem) + + oldreply(workitem.as_owfe_workitem) + workitem.destroy + else + + oldreply(workitem) + end + end + + alias :forward :reply + alias :proceed :reply + end + + # + # Returns all the workitems belonging to the stores listed + # in the parameter storename_list. + # The result is a Hash whose keys are the store names and whose + # values are list of workitems. + # + def Workitem.find_in_stores (storename_list) + + workitems = find_all_by_store_name(storename_list) + + result = {} + + workitems.each do |wi| + (result[wi.store_name] ||= []) << wi + end + + result + end end # # A Field (Attribute) of a Workitem. # class Field < ActiveRecord::Base belongs_to :workitem - serialize :value + serialize :yvalue # # A quick method for doing # # f = Field.new @@ -226,16 +308,34 @@ # # One can then quickly add fields to an [active] workitem via : # # wi.fields << Field.new_field("toto", "b") # + # This method does not save the new Field. + # def self.new_field (key, value) + f = Field.new f.key = key f.value = value f end + + def value= (v) + + if v.is_a?(String) + self.svalue = v + else + self.yvalue = v + end + end + + def value + + return self.svalue if self.svalue + self.yvalue + end end # # A basic 'ActiveParticipant'. @@ -278,17 +378,11 @@ # This is the method called by the OpenWFEru engine to hand a # workitem to this participant. # def consume (workitem) - awi = Workitem.from_owfe_workitem(workitem) - # - # turns the workitem into an 'active' one - - awi.save - # - # and saves it in the db. + Workitem.from_owfe_workitem(workitem) end # # Called by the engine when the whole process instance (or just the # segment of it that sports this participant) is cancelled. @@ -318,15 +412,45 @@ # removes the workitem from the database end end # - # TODO : please document me + # An extension of ActiveParticipant. It has a 'store_name' and it + # makes sure to flag every workitem it 'consumes' with that name + # (in its 'store_name' column/field). # + # This is the participant used mainly in 'densha' for human users. + # class ActiveStoreParticipant < ActiveParticipant include Enumerable + def initialize (store_name) + + super() + @store_name = store_name + end + + # + # This is the method called by the OpenWFEru engine to hand a + # workitem to this participant. + # + def consume (workitem) + + Workitem.from_owfe_workitem(workitem, @store_name) + end + + # + # Iterates over the workitems currently in this store. + # def each (&block) + + return unless block + + wis = Workitem.find_by_store_name @store_name + + wis.each do |wi| + block.call wi + end end end end end