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