Index: openacs-4/packages/workflow/workflow.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/workflow.info,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/workflow/workflow.info 14 Jan 2003 15:08:54 -0000 1.2
+++ openacs-4/packages/workflow/workflow.info 21 Jan 2003 18:05:20 -0000 1.3
@@ -26,6 +26,7 @@
+
@@ -35,8 +36,12 @@
+
+
+
+
Index: openacs-4/packages/workflow/sql/postgresql/workflow-procedural-create.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/sql/postgresql/workflow-procedural-create.sql,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/workflow/sql/postgresql/workflow-procedural-create.sql 14 Jan 2003 15:09:07 -0000 1.2
+++ openacs-4/packages/workflow/sql/postgresql/workflow-procedural-create.sql 21 Jan 2003 18:05:48 -0000 1.3
@@ -23,42 +23,45 @@
-- Function for creating a workflow
-create function workflow__new (varchar, -- short_name
- varchar, -- pretty_name
- integer, -- object_id
- varchar, -- object_type
- integer, -- creation_user
- varchar, -- creation_ip
- integer -- context_id
- )
+create function workflow__new (
+ varchar, -- short_name
+ varchar, -- pretty_name
+ varchar, -- package_key
+ integer, -- object_id
+ varchar, -- object_type
+ integer, -- creation_user
+ varchar, -- creation_ip
+ integer -- context_id
+)
returns integer as '
declare
- p_short_name alias for $1;
- p_pretty_name alias for $2;
- p_object_id alias for $3;
- p_object_type alias for $4;
- p_creation_user alias for $5;
- p_creation_ip alias for $6;
- p_context_id alias for $7;
-
- v_workflow_id integer;
+ p_short_name alias for $1;
+ p_pretty_name alias for $2;
+ p_package_key alias for $3;
+ p_object_id alias for $4;
+ p_object_type alias for $5;
+ p_creation_user alias for $6;
+ p_creation_ip alias for $7;
+ p_context_id alias for $8;
+
+ v_workflow_id integer;
begin
- -- Instantiate the ACS Object super type with auditing info
- v_workflow_id := acs_object__new(null,
- ''workflow_lite'',
- now(),
- p_creation_user,
- p_creation_ip,
- p_context_id,
- ''t'');
+ -- Instantiate the ACS Object super type with auditing info
+ v_workflow_id := acs_object__new(null,
+ ''workflow_lite'',
+ now(),
+ p_creation_user,
+ p_creation_ip,
+ p_context_id,
+ ''t'');
- -- Insert workflow specific info into the workflows table
- insert into workflows
- (workflow_id, short_name, pretty_name, object_id, object_type)
- values
- (v_workflow_id, p_short_name, p_pretty_name, p_object_id, p_object_type);
-
+ -- Insert workflow specific info into the workflows table
+ insert into workflows
+ (workflow_id, short_name, pretty_name, package_key, object_id, object_type)
+ values
+ (v_workflow_id, p_short_name, p_pretty_name, p_package_key, p_object_id, p_object_type);
+
- return v_workflow_id;
+ return v_workflow_id;
end;
' language 'plpgsql';
Index: openacs-4/packages/workflow/sql/postgresql/workflow-tables-create.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/sql/postgresql/workflow-tables-create.sql,v
diff -u -r1.4 -r1.5
--- openacs-4/packages/workflow/sql/postgresql/workflow-tables-create.sql 20 Jan 2003 15:44:59 -0000 1.4
+++ openacs-4/packages/workflow/sql/postgresql/workflow-tables-create.sql 21 Jan 2003 18:05:48 -0000 1.5
@@ -56,11 +56,12 @@
constraint workflows_pretty_name_nn
not null,
object_id integer
- constraint workflows_object_id_nn
- not null
constraint workflows_object_id_fk
references acs_objects(object_id)
on delete cascade,
+ package_key varchar(100)
+ constraint workflows_apm_package_types_fk
+ references apm_package_types(package_key),
-- object_id points to either a package type, package instance, or single workflow case
-- For Bug Tracker, every package instance will get its own workflow instance that is a copy
-- of the workflow instance for the Bug Tracker package type
@@ -70,30 +71,28 @@
constraint workflows_object_type_fk
references acs_object_types(object_type)
on delete cascade,
- -- the object type (and its subtypes) this workflow is designed for. Use acs_object
- -- if you don't want to restrict the types of objects this workflow can be applied to.
constraint workflows_oid_sn_un
unique (object_id, short_name)
);
--- For callback procedures that execute when any action in the workflow is taken
-create table workflow_side_effects (
+-- For callbacks on workflow
+create table workflow_callbacks (
workflow_id integer
- constraint workflow_side_effects_wid_nn
+ constraint workflow_callbacks_wid_nn
not null
- constraint workflow_side_effects_wid_fk
+ constraint workflow_callbacks_wid_fk
references workflows(workflow_id)
on delete cascade,
acs_sc_impl_id integer
- constraint workflow_side_effects_sci_nn
+ constraint workflow_callbacks_sci_nn
not null
- constraint workflow_side_effects_sci_fk
+ constraint workflow_callbacks_sci_fk
references acs_sc_impls(impl_id)
on delete cascade,
sort_order integer
- constraint workflow_side_effects_so_nn
+ constraint workflow_callbacks_so_nn
not null,
- constraint workflow_side_effects_pk
+ constraint workflow_callbacks_pk
primary key (workflow_id, acs_sc_impl_id)
);
@@ -151,28 +150,30 @@
primary key (role_id, party_id)
);
--- Application specific callback procedures for dynamically mapping parties to roles
-create table workflow_role_assignment_rules (
+-- Callbacks for roles
+create table workflow_role_callbacks (
role_id integer
- constraint workflow_role_assignment_rules_role_id_nn
+ constraint workflow_role_callbacks_role_id_nn
not null
- constraint workflow_role_assignment_rules_role_id_fk
+ constraint workflow_role_callbacks_role_id_fk
references workflow_roles(role_id)
on delete cascade,
acs_sc_impl_id integer
- constraint workflow_role_assignment_rules_contract_id_nn
+ constraint workflow_role_callbacks_contract_id_nn
not null
- constraint workflow_role_assignment_rules_contract_id_fk
+ constraint workflow_role_callbacks_contract_id_fk
references acs_sc_impls(impl_id)
on delete cascade,
- -- this can be an implementation of any of the three assignment
+ -- this should be an implementation of any of the three assignment
-- service contracts: DefaultAssignee, AssigneePickList, or
-- AssigneeSubQuery
sort_order integer
- constraint workflow_role_assignment_rules_sort_order_nn
+ constraint workflow_role_callbacks_sort_order_nn
not null,
- constraint workflow_role_assignment_rules_pk
- primary key (role_id, acs_sc_impl_id)
+ constraint workflow_role_callbacks_pk
+ primary key (role_id, acs_sc_impl_id),
+ constraint workflow_role_asgn_rol_sort_un
+ unique (role_id, sort_order)
);
create table workflow_actions (
@@ -241,25 +242,24 @@
primary key (action_id, privilege)
);
--- For application specific callback procedures that execute when
--- certain actions are taken
-create table workflow_action_side_effects (
+-- For callbacks on actions
+create table workflow_action_callbacks (
action_id integer
- constraint workflow_action_side_effects_action_id_nn
+ constraint workflow_action_callbacks_action_id_nn
not null
- constraint workflow_action_side_effects_action_id_fk
+ constraint workflow_action_callbacks_action_id_fk
references workflow_actions(action_id)
on delete cascade,
acs_sc_impl_id integer
- constraint workflow_action_side_effects_sci_nn
+ constraint workflow_action_callbacks_sci_nn
not null
- constraint workflow_action_side_effects_sci_fk
+ constraint workflow_action_callbacks_sci_fk
references acs_sc_impls(impl_id)
on delete cascade,
sort_order integer
- constraint workflow_action_side_effects_sort_order_nn
+ constraint workflow_action_callbacks_sort_order_nn
not null,
- constraint workflow_action_side_effects_pk
+ constraint workflow_action_callbacks_pk
primary key (action_id, acs_sc_impl_id)
);
Index: openacs-4/packages/workflow/sql/postgresql/workflow-tables-drop.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/sql/postgresql/workflow-tables-drop.sql,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/workflow/sql/postgresql/workflow-tables-drop.sql 14 Jan 2003 15:09:07 -0000 1.2
+++ openacs-4/packages/workflow/sql/postgresql/workflow-tables-drop.sql 21 Jan 2003 18:05:48 -0000 1.3
@@ -48,15 +48,15 @@
drop table workflow_fsm_actions;
drop table workflow_initial_action;
drop table workflow_fsm_states;
-drop table workflow_action_side_effects;
+drop table workflow_action_callbacks;
drop table workflow_action_privileges;
drop table workflow_action_allowed_roles;
drop table workflow_actions;
-drop table workflow_role_assignment_rules;
+drop table workflow_role_callbacks;
drop table workflow_role_allowed_parties;
drop table workflow_role_default_parties;
drop table workflow_roles;
-drop table workflow_side_effects;
+drop table workflow_callbacks;
drop table workflows;
-- Drop sequences
Index: openacs-4/packages/workflow/tcl/action-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/action-procs.tcl,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/workflow/tcl/action-procs.tcl 20 Jan 2003 15:45:00 -0000 1.3
+++ openacs-4/packages/workflow/tcl/action-procs.tcl 21 Jan 2003 18:06:00 -0000 1.4
@@ -10,14 +10,16 @@
namespace eval workflow::action {}
namespace eval workflow:::action::fsm {}
+
+
+
#####
#
# workflow::action namespace
#
#####
ad_proc -public workflow::action::new {
- -initial_action:boolean
{-workflow_id:required}
{-sort_order {}}
{-short_name:required}
@@ -26,7 +28,9 @@
{-assigned_role {}}
{-allowed_roles {}}
{-privileges {}}
+ {-callbacks {}}
{-always_enabled_p f}
+ {-initial_action:boolean}
} {
This procedure is normally not invoked from application code. Instead
a procedure for a certain workflow implementation, such as for example
@@ -47,6 +51,8 @@
treated by the workflow (i.e. a bug in the
Bug Tracker) will be allowed to take this
action.
+ @param callbacks List of names of service contract implementations of callbacks for the action in
+ impl_owner_name.impl_name format.
@param initial_action Use this switch to indicate that this is the initial
action that will fire whenever a case of the workflow
is created. The initial action is used to determine
@@ -62,15 +68,22 @@
db_transaction {
# Insert basic action info
if { [empty_string_p $sort_order] } {
- set sort_order [workflow::default_sort_order -workflow_id $workflow_id workflow_actions]
+ set sort_order [workflow::default_sort_order \
+ -workflow_id $workflow_id \
+ -table_name "workflow_actions"]
}
+
set action_id [db_nextval "workflow_actions_seq"]
+
if { [empty_string_p $assigned_role] } {
set assigned_role_id [db_null]
} else {
- set assigned_role_id [workflow::role::get_id -workflow_id $workflow_id \
- -short_name $assigned_role]
+ set assigned_role_id [workflow::role::get_id \
+ -workflow_id $workflow_id \
+ -short_name $assigned_role]
}
+
+ # Insert the action
db_dml insert_action {}
# Record which roles are allowed to take action
@@ -87,6 +100,14 @@
if { $initial_action_p } {
db_dml insert_initial_action {}
}
+
+ # Callbacks
+ foreach callback_name $callbacks {
+ workflow::action::callback_insert \
+ -action_id $action_id \
+ -name $callback_name
+ }
+
}
return $action_id
@@ -137,6 +158,7 @@
ad_proc -public workflow::action::get {
{-action_id:required}
+ {-array:required}
} {
Return information about an action with a given id.
@@ -146,36 +168,71 @@
pretty_past_tense, assigned_role, and always_enabled_p column
values for an action.
} {
- db_1row action_info {} -column_array action_info
+ # Select the info into the upvar'ed Tcl Array
+ upvar $array row
- return [array get action_info]
+ db_1row action_info {} -column_array row
}
+ad_proc -public workflow::action::callback_insert {
+ {-action_id:required}
+ {-name:required}
+ {-sort_order {}}
+} {
+ Add a side-effect to an action.
+
+ @param action_id The ID of the action.
+ @param name Name of service contract implementation, in the form (impl_owner_name).(impl_name),
+ for example, bug-tracker.CaptureResolutionCode
+ @param sort_order The sort_order for the rule. Leave blank to add to the end of the list
+
+ @author Lars Pind (lars@collaboraid.biz)
+} {
+ # TODO:
+ # Insert for real when the service contracts have been defined
+
+ ns_log Error "LARS: workflow::action::callback_insert -- would have inserted the callback $name to action $action_id"
+ return
+ db_transaction {
+
+ # Get the impl_id
+ set acs_sc_impl_id [workflow::service_contract::get_impl_id -name $name]
+
+ # Get the sort order
+ if { ![exists_and_not_null sort_order] } {
+ set sort_order [db_string select_sort_order {}]
+ }
+
+ # Insert the callback
+ db_dml insert_callback {}
+ }
+ return $acs_sc_impl_id
+}
+
+
+
+
+
#####
#
# workflow::action::fsm
#
#####
-#####
-#
-# workflow::fsm::action namespace
-#
-#####
-
ad_proc -public workflow::action::fsm::new {
- -initial_action:boolean
{-workflow_id:required}
{-short_name:required}
{-pretty_name:required}
{-pretty_past_tense {}}
{-allowed_roles {}}
{-assigned_role {}}
{-privileges {}}
- {-always_enabled_p f}
{-enabled_states {}}
{-new_state {}}
+ {-callbacks {}}
+ {-always_enabled_p f}
+ {-initial_action:boolean}
} {
Add an action to a certain FSM (Finite State Machine) workflow. This procedure
invokes the generic workflow::action::new procedures and does additional inserts
@@ -194,31 +251,35 @@
db_transaction {
# Generic workflow data:
- set action_id [workflow::action::new -initial_action=$initial_action_p \
- -workflow_id $workflow_id \
- -short_name $short_name \
- -pretty_name $pretty_name \
- -pretty_past_tense $pretty_past_tense \
- -allowed_roles $allowed_roles \
- -assigned_role $assigned_role \
- -privileges $privileges \
- -always_enabled_p $always_enabled_p]
+ set action_id [workflow::action::new \
+ -initial_action=$initial_action_p \
+ -workflow_id $workflow_id \
+ -short_name $short_name \
+ -pretty_name $pretty_name \
+ -pretty_past_tense $pretty_past_tense \
+ -allowed_roles $allowed_roles \
+ -assigned_role $assigned_role \
+ -privileges $privileges \
+ -callbacks $callbacks \
+ -always_enabled_p $always_enabled_p]
# FSM specific data:
# Record whether the action changes state
if { ![empty_string_p $new_state] } {
- set new_state_id [workflow::state::fsm::get_id -workflow_id $workflow_id \
- -short_name $new_state]
+ set new_state_id [workflow::state::fsm::get_id \
+ -workflow_id $workflow_id \
+ -short_name $new_state]
} else {
set new_state_id [db_null]
}
db_dml insert_fsm_action {}
# Record in which states the action is enabled
foreach state_short_name $enabled_states {
- set enabled_state_id [workflow::state::fsm::get_id -workflow_id $workflow_id \
- -short_name $state_short_name]
+ set enabled_state_id [workflow::state::fsm::get_id \
+ -workflow_id $workflow_id \
+ -short_name $state_short_name]
db_dml insert_enabled_state {}
}
}
@@ -233,3 +294,73 @@
} {
return [db_string select_new_state {} -default {}]
}
+
+
+ad_proc -private workflow::action::fsm::parse_spec {
+ {-workflow_id:required}
+ {-short_name:required}
+ {-spec:required}
+} {
+ Parse the spec for an individual action definition.
+
+ @param workflow_id The id of the workflow to delete.
+ @param short_name The short_name of the action
+ @param spec The action spec
+
+ @author Lars Pind (lars@collaboraid.biz)
+} {
+ # Initialize array with default values
+ array set action {
+ pretty_past_tense {}
+ allowed_roles {}
+ assigned_role {}
+ privileges {}
+ always_enabled_p f
+ enabled_states {}
+ new_state {}
+ initial_action_p 0
+ }
+
+ # Get the info from the spec
+ array set action $spec
+
+ # Create the action
+ set action_id [workflow::action::fsm::new \
+ -workflow_id $workflow_id \
+ -short_name $short_name \
+ -pretty_name $action(pretty_name) \
+ -pretty_past_tense $action(pretty_past_tense) \
+ -allowed_roles $action(allowed_roles) \
+ -assigned_role $action(assigned_role) \
+ -privileges $action(privileges) \
+ -always_enabled_p $action(always_enabled_p) \
+ -enabled_states $action(enabled_states) \
+ -new_state $action(new_state) \
+ -initial_action=$action(initial_action_p) \
+ ]
+}
+
+ad_proc -private workflow::action::fsm::parse_actions_spec {
+ {-workflow_id:required}
+ {-spec:required}
+} {
+ Parse the spec for the block containing the definition of all
+ actions for the workflow.
+
+ @param workflow_id The id of the workflow to delete.
+ @param spec The actions spec
+
+ @author Lars Pind (lars@collaboraid.biz)
+} {
+ # actions(short_name) { ... action-spec ... }
+ array set actions $spec
+
+ foreach short_name [array names actions] {
+ workflow::action::fsm::parse_spec \
+ -workflow_id $workflow_id \
+ -short_name $short_name \
+ -spec $actions($short_name)
+ }
+}
+
+
Index: openacs-4/packages/workflow/tcl/action-procs.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/action-procs.xql,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/workflow/tcl/action-procs.xql 20 Jan 2003 15:45:00 -0000 1.3
+++ openacs-4/packages/workflow/tcl/action-procs.xql 21 Jan 2003 18:06:00 -0000 1.4
@@ -85,6 +85,23 @@
+
+
+ select coalesce(max(sort_order)) + 1
+ from workflow_action_callbacks
+ where action_id = :action_id
+
+
+
+
+
+ insert into workflow_action_callbacks (action_id, acs_sc_impl_id, sort_order)
+ values (:action_id, :acs_sc_impl_id, :sort_order)
+
+
+
+
+
insert into workflow_fsm_actions
Index: openacs-4/packages/workflow/tcl/case-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/case-procs.tcl,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/workflow/tcl/case-procs.tcl 20 Jan 2003 15:45:00 -0000 1.2
+++ openacs-4/packages/workflow/tcl/case-procs.tcl 21 Jan 2003 18:06:00 -0000 1.3
@@ -74,7 +74,7 @@
# Execute the initial action
workflow::case::action::execute \
-case_id $case_id \
- -action_id [workflow::action::get_initial_action -workflow_id $workflow_id] \
+ -action_id [workflow::get_initial_action -workflow_id $workflow_id] \
-comment $comment \
-comment_format $comment_format \
-user_id $user_id \
@@ -101,7 +101,7 @@
if { $found_p } {
return $case_id
} else {
- return {}
+ error "No matching workflow case found for object_id $object_id and workflow_short_name $workflow_short_name"
}
}
@@ -155,16 +155,14 @@
return $action_list
}
-ad_proc -public workflow::case::get_user_actions {
+ad_proc -public workflow::case::get_available_actions {
{-case_id:required}
-user_id
} {
- Get the currently enabled actions, which the user has permission
- to execute.
+ Get the actions which are enabled and which the current user have permission to execute.
@param case_id The ID of the case.
- @return A list of id:s of the actions
- which are currently enabled
+ @return A list of ID's of the available actions.
@author Lars Pind (lars@collaboraid.biz)
} {
@@ -237,7 +235,7 @@
set object_id [workflow::case::get_object_id -case_id $case_id]
- db_foreach select_assignment_rules {} {
+ db_foreach select_callbacks {} {
# Run the service contract
set party_id_list [acs_sc_call $contract_name "GetAssignees" [list $case_id $object_id $role_id] $impl_name]
Index: openacs-4/packages/workflow/tcl/case-procs.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/case-procs.xql,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/workflow/tcl/case-procs.xql 20 Jan 2003 15:45:00 -0000 1.2
+++ openacs-4/packages/workflow/tcl/case-procs.xql 21 Jan 2003 18:06:00 -0000 1.3
@@ -53,24 +53,22 @@
- select distinct action_id
- from (select waeis.action_id
- from workflow_cases c,
- workflow_case_fsm cfsm,
- workflow_fsm_action_enabled_in_states waeis
- where c.case_id = :case_id
- and cfsm.case_id = c.case_id
- and waeis.state_id = cfsm.current_state
-
- union
-
- select a.action_id
- from workflow_cases c,
- workflow_actions a
- where c.case_id = :case_id
- and a.workflow_id = c.workflow_id
- and a.always_enabled_p = 't'
- ) enabled_actions
+ select a.action_id
+ from workflow_cases c,
+ workflow_actions a
+ where c.case_id = :case_id
+ and a.workflow_id = c.workflow_id
+ and not exists (select 1
+ from workflow_initial_action wia
+ where wia.workflow_id = c.workflow_id
+ and wia.action_id = a.action_id)
+ and (a.always_enabled_p = 't'
+ or exists (select 1
+ from workflow_case_fsm cfsm,
+ workflow_fsm_action_enabled_in_states waeis
+ where cfsm.case_id = c.case_id
+ and waeis.state_id = cfsm.current_state
+ and waeis.action_id = a.action_id))
@@ -83,10 +81,10 @@
-
+
select impl.impl_name
- from workflow_role_assignment_rules r,
+ from workflow_role_callbacks r,
acs_sc_impls impl,
acs_sc_bindings bind,
acs_sc_contracts ctr
Fisheye: Tag 1.4 refers to a dead (removed) revision in file `openacs-4/packages/workflow/tcl/fsm-procs.tcl'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 1.4 refers to a dead (removed) revision in file `openacs-4/packages/workflow/tcl/fsm-procs.xql'.
Fisheye: No comparison available. Pass `N' to diff?
Index: openacs-4/packages/workflow/tcl/role-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/role-procs.tcl,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/workflow/tcl/role-procs.tcl 20 Jan 2003 15:45:00 -0000 1.3
+++ openacs-4/packages/workflow/tcl/role-procs.tcl 21 Jan 2003 18:06:00 -0000 1.4
@@ -9,28 +9,71 @@
namespace eval workflow::role {}
+
+
+
#####
#
# workflow::role namespace
#
#####
+ad_proc -private workflow::role::insert {
+ {-workflow_id:required}
+ {-short_name:required}
+ {-pretty_name:required}
+} {
+ Inserts the DB row for a new role. You shouldn't normally be usin
+ this procedure, use workflow::role::new instead.
+
+ @param workflow_id The ID of the workflow the new role belongs to
+ @param short_name The short_name of the new role
+ @param pretty_name The pretty name of the new role
+ @return The ID of the new role
+
+ @author Lars Pind (lars@collaboraid.biz)
+ @see workflow::role::new
+} {
+ db_transaction {
+ set role_id [db_nextval "workflow_roles_seq"]
+ db_dml do_insert {}
+ }
+ return $role_id
+}
+
ad_proc -public workflow::role::new {
{-workflow_id:required}
{-short_name:required}
{-pretty_name:required}
+ {-callbacks {}}
} {
- Creates a new role for a certain workflow.
+ Creates a new role for a workflow.
- @param workflow_id
- @param short_name
- @param pretty_name
+ @param workflow_id The ID of the workflow the new role belongs to
+ @param short_name The short_name of the new role
+ @param pretty_name The pretty name of the new role
+ @param callbacks A list of names service-contract implementations.
+ @return The ID of the new role
@author Peter Marklund
+ @author Lars Pind (lars@collaboraid.biz)
} {
- set role_id [db_nextval "workflow_roles_seq"]
+ db_transaction {
+ # Insert the role
+ set role_id [insert \
+ -workflow_id $workflow_id \
+ -short_name $short_name \
+ -pretty_name $pretty_name\
+ ]
- db_dml do_insert {}
+ # Set up the assignment rules
+ foreach callback_name $callbacks {
+ workflow::role::callback_insert \
+ -role_id $role_id \
+ -name $callback_name
+ }
+ }
+ return $role_id
}
ad_proc -public workflow::role::get_id {
@@ -45,3 +88,90 @@
} {
return [db_string select_role_id {} -default {}]
}
+
+ad_proc -private workflow::role::parse_spec {
+ {-workflow_id:required}
+ {-short_name:required}
+ {-spec:required}
+} {
+ Parse the spec for an individual role definition.
+
+ @param workflow_id The id of the workflow to delete.
+ @param short_name The short_name of the role
+ @param spec The roles spec
+
+ @author Lars Pind (lars@collaboraid.biz)
+} {
+ # Initialize array with default values
+ array set role { callbacks {} }
+
+ # Get the info from the spec
+ array set role $spec
+
+ # Create the role
+ set role_id [workflow::role::new \
+ -workflow_id $workflow_id \
+ -short_name $short_name \
+ -pretty_name $role(pretty_name) \
+ -callbacks $role(callbacks)
+ ]
+}
+
+ad_proc -private workflow::role::parse_roles_spec {
+ {-workflow_id:required}
+ {-spec:required}
+} {
+ Parse the spec for the block containing the definition of all
+ roles for the workflow.
+
+ @param workflow_id The id of the workflow to delete.
+ @param spec The roles spec
+
+ @author Lars Pind (lars@collaboraid.biz)
+} {
+ # roles(short_name) { ... role-spec ... }
+ array set roles $spec
+
+ foreach short_name [array names roles] {
+ workflow::role::parse_spec \
+ -workflow_id $workflow_id \
+ -short_name $short_name \
+ -spec $roles($short_name)
+ }
+}
+
+ad_proc -private workflow::role::callback_insert {
+ {-role_id:required}
+ {-name:required}
+ {-sort_order}
+} {
+ Add an assignment rule to a role.
+
+ @param role_id The ID of the role
+ @param name Name of service contract implementation, in the form (impl_owner_name).(impl_name),
+ for example, bug-tracker.ComponentMaintainer.
+ @param sort_order The sort_order for the rule. Leave blank to add to the end of the list
+
+ @author Lars Pind (lars@collaboraid.biz)
+} {
+ # TODO:
+ # Insert for real when the service contracts have been defined
+
+ ns_log Error "LARS: workflow::role::callback_insert -- would have inserted the callback $name to role $role_id"
+ return
+
+ db_transaction {
+
+ # Get the impl_id
+ set acs_sc_impl_id [workflow::service_contract::get_impl_id -name $name]
+
+ # Get the sort order
+ if { ![exists_and_not_null sort_order] } {
+ set sort_order [db_string select_sort_order {}]
+ }
+
+ # Insert the rule
+ db_dml insert_rule {}
+ }
+ return $acs_sc_impl_id
+}
Index: openacs-4/packages/workflow/tcl/role-procs.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/role-procs.xql,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/workflow/tcl/role-procs.xql 20 Jan 2003 15:45:00 -0000 1.3
+++ openacs-4/packages/workflow/tcl/role-procs.xql 21 Jan 2003 18:06:00 -0000 1.4
@@ -1,7 +1,7 @@
-
+
insert into workflow_roles
(role_id, workflow_id, short_name, pretty_name)
@@ -19,4 +19,21 @@
+
+
+ select coalesce(max(sort_order)) + 1
+ from workflow_role_callbacks
+ where role_id = :role_id
+
+
+
+
+
+ insert into workflow_role_callbacks (role_id, acs_sc_impl_id, sort_order)
+ values (:role_id, :acs_sc_impl_id, :sort_order)
+
+
+
+
+
Index: openacs-4/packages/workflow/tcl/state-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/state-procs.tcl,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/workflow/tcl/state-procs.tcl 21 Jan 2003 18:06:00 -0000 1.1
@@ -0,0 +1,125 @@
+ad_library {
+ Procedures in the workflow::fsm::state namespace and
+ in its child namespaces.
+
+ @creation-date 8 January 2003
+ @author Lars Pind (lars@collaboraid.biz)
+ @author Peter Marklund (peter@collaboraid.biz)
+ @cvs-id $Id: state-procs.tcl,v 1.1 2003/01/21 18:06:00 lars Exp $
+}
+
+namespace eval workflow::state::fsm {}
+
+#####
+#
+# workflow::state::fsm namespace
+#
+#####
+
+ad_proc -public workflow::state::fsm::new {
+ {-workflow_id:required}
+ {-short_name:required}
+ {-pretty_name:required}
+ {-sort_order {}}
+} {
+ Creates a new state for a certain FSM (Finite State Machine) workflow.
+
+ @param workflow_id The id of the FSM workflow to add the state to
+ @param short_name
+ @param pretty_name
+ @return ID of new state.
+
+ @author Peter Marklund
+} {
+ db_transaction {
+
+ set state_id [db_nextval "workflow_fsm_states_seq"]
+
+ if { [empty_string_p $sort_order] } {
+ set sort_order [workflow::default_sort_order -workflow_id $workflow_id -table_name "workflow_fsm_states"]
+ }
+
+ db_dml do_insert {}
+ }
+ return $state_id
+}
+
+ad_proc -public workflow::state::fsm::get {
+ {-state_id:required}
+ {-array:required}
+} {
+ Return workflow_id, sort_order, short_name, and pretty_name for a certain
+ FSM workflow state.
+
+ @author Peter Marklund
+} {
+ # Select the info into the upvar'ed Tcl Array
+ upvar $array row
+
+ db_1row state_info {} -column_array row
+}
+
+ad_proc -public workflow::state::fsm::get_id {
+ {-workflow_id:required}
+ {-short_name:required}
+} {
+ Return the id of the state with given short name
+
+ @param workflow_id The id of the workflow the state belongs to.
+ @param short_name The name of the state to return the id for.
+
+ @author Peter Marklund
+} {
+ return [db_string select_id {}]
+}
+
+
+ad_proc -private workflow::state::fsm::parse_spec {
+ {-workflow_id:required}
+ {-short_name:required}
+ {-spec:required}
+} {
+ Parse the spec for an individual state definition.
+
+ @param workflow_id The id of the workflow to delete.
+ @param short_name The short_name of the state
+ @param spec The state spec
+
+ @author Lars Pind (lars@collaboraid.biz)
+} {
+ # Initialize array with default values
+ array set state {}
+
+ # Get the info from the spec
+ array set state $spec
+
+ # Create the state
+ set state_id [workflow::state::fsm::new \
+ -workflow_id $workflow_id \
+ -short_name $short_name \
+ -pretty_name $state(pretty_name)
+ ]
+}
+
+ad_proc -private workflow::state::fsm::parse_states_spec {
+ {-workflow_id:required}
+ {-spec:required}
+} {
+ Parse the spec for the block containing the definition of all
+ states for the workflow.
+
+ @param workflow_id The id of the workflow to delete.
+ @param spec The states spec
+
+ @author Lars Pind (lars@collaboraid.biz)
+} {
+ # states(short_name) { ... state-spec ... }
+ array set states $spec
+
+ foreach short_name [array names states] {
+ workflow::state::fsm::parse_spec \
+ -workflow_id $workflow_id \
+ -short_name $short_name \
+ -spec $states($short_name)
+ }
+}
Index: openacs-4/packages/workflow/tcl/state-procs.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/state-procs.xql,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/workflow/tcl/state-procs.xql 21 Jan 2003 18:06:00 -0000 1.1
@@ -0,0 +1,32 @@
+
+
+
+
+
+ insert into workflow_fsm_states
+ (state_id, workflow_id, sort_order, short_name, pretty_name)
+ values (:state_id, :workflow_id, :sort_order, :short_name, :pretty_name)
+
+
+
+
+
+ select workflow_id,
+ sort_order,
+ short_name,
+ pretty_name
+ from workflow_fsm_states
+ where state_id = :state_id
+
+
+
+
+
+ select state_id
+ from workflow_fsm_states
+ where short_name = :short_name
+ and workflow_id = :workflow_id
+
+
+
+
Index: openacs-4/packages/workflow/tcl/workflow-procs-postgresql.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/workflow-procs-postgresql.xql,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/workflow/tcl/workflow-procs-postgresql.xql 20 Jan 2003 15:45:00 -0000 1.3
+++ openacs-4/packages/workflow/tcl/workflow-procs-postgresql.xql 21 Jan 2003 18:06:00 -0000 1.4
@@ -4,15 +4,16 @@
- select workflow__new (:short_name,
- :pretty_name,
- :object_id,
- :object_type,
- :creation_user,
- :creation_ip,
- :context_id
- );
-
+ select workflow__new (
+ :short_name,
+ :pretty_name,
+ :package_key,
+ :object_id,
+ :object_type,
+ :creation_user,
+ :creation_ip,
+ :context_id
+ );
Index: openacs-4/packages/workflow/tcl/workflow-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/workflow-procs.tcl,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/workflow/tcl/workflow-procs.tcl 20 Jan 2003 15:45:00 -0000 1.3
+++ openacs-4/packages/workflow/tcl/workflow-procs.tcl 21 Jan 2003 18:06:00 -0000 1.4
@@ -8,6 +8,7 @@
}
namespace eval workflow {}
+namespace eval workflow::fsm {}
namespace eval workflow::service_contract {}
#####
@@ -23,20 +24,25 @@
ad_proc -public workflow::new {
{-short_name:required}
{-pretty_name:required}
- {-object_id:required}
+ {-package_key {}}
+ {-object_id {}}
{-object_type "acs_object"}
+ {-callbacks {}}
} {
Creates a new workflow. For each workflow you must create an initial action
(using the workflow::action::new proc) to be fired when a workflow case is opened.
@param short_name For referring to the workflow from Tcl code. Use Tcl variable syntax.
@param pretty_name A human readable name for the workflow for use in the UI.
+ @param package_key The package to which this workflow belongs
@param object_id The id of an ACS Object indicating the scope the workflow.
Typically this will be the id of a package type or a package instance
but it could also be some other type of ACS object within a package, for example
the id of a bug in the Bug Tracker application.
@param object_type The type of objects that the workflow will be applied to. Valid values are in the
acs_object_types table. The parameter is optional and defaults to acs_object.
+ @param callbacks List of names of service contract implementations of callbacks for the workflow in
+ impl_owner_name.impl_name format.
@author Peter Marklund
} {
@@ -46,20 +52,64 @@
set creation_ip [ad_conn peeraddr]
} else {
# No HTTP request so we have don't have IP and user info
- set creation_user ""
- set creation_ip ""
+ set creation_user {}
+ set creation_ip {}
}
# It makes sense that the workflow inherits permissions from the object
# (typically package type or package instance) that sets the scope of the workflow
set context_id $object_id
- # Insert the workflow
- set workflow_id [db_string do_insert {}]
+ db_transaction {
+ if { [empty_string_p $package_key] } {
+ set package_key [db_null]
+ }
+
+ if { [empty_string_p $object_id] } {
+ set object_id [db_null]
+ }
+
+ # Insert the workflow
+ set workflow_id [db_string do_insert {}]
+
+ # Callbacks
+ foreach callback_name $callbacks {
+ workflow::callback_insert \
+ -workflow_id $workflow_id \
+ -name $callback_name
+ }
+
+ # May need to parse the simple workflow notation
+ if { [exists_and_not_null workflow] } {
+ parse_spec -workflow_id $workflow_id -spec $workflow
+ }
+ }
+
return $workflow_id
}
+ad_proc -private workflow::fsm::parse_spec {
+ {-workflow_id:required}
+ {-spec:required}
+} {
+ Parse the -workflow argument to workflow::new and create roles,
+ states, actions, etc., as appropriate
+
+ @param workflow_id The id of the workflow to delete.
+
+ @author Lars Pind (lars@collaboraid.biz)
+ @see workflow::new
+} {
+ array set workflow { roles {} states {} actions {} }
+ array set workflow $spec
+
+ workflow::roles::parse_spec $workflow(roles)
+ workflow::roles::parse_spec $workflow(roles)
+}
+
+
+
ad_proc -public workflow::delete {
{-workflow_id:required}
} {
@@ -73,7 +123,8 @@
}
ad_proc -public workflow::get_id {
- {-object_id:required}
+ {-package_key {}}
+ {-object_id {}}
{-short_name:required}
} {
Get workflow_id by short_name and object_id.
@@ -83,10 +134,34 @@
@author Lars Pind (lars@collaboraid.biz)
} {
- return [db_string select_workflow_id {} -default {}]
+ if { [empty_string_p $package_key] } {
+ if { [empty_string_p $object_id] } {
+ if { [ad_conn isconnected] } {
+ set package_key [ad_conn package_key]
+ } else {
+ error "You must supply either package_key or object_id, or there must be a current connection"
+ set query_name select_workflow_id_by_package_key
+ }
+ } else {
+ set query_name select_workflow_id_by_object_id
+ }
+ } else {
+ if { [empty_string_p $object_id] } {
+ set query_name select_workflow_id_by_package_key
+ } else {
+ error "You must supply only one of either package_key or object_id"
+ }
+ }
+
+ set workflow_id [db_string $query_name {} -default {}]
+ if { ![empty_string_p $workflow_id] } {
+ return $workflow_id
+ } else {
+ error "No workflow found with object_id $object_id and short_name $short_name"
+ }
}
-ad_proc -public workflow::action::get_initial_action {
+ad_proc -public workflow::get_initial_action {
{-workflow_id:required}
} {
Get the action_id of the special 'open' action of a workflow.
@@ -101,27 +176,143 @@
ad_proc -private workflow::default_sort_order {
{-workflow_id:required}
- table_name
+ {-table_name:required}
} {
By default the sort_order will be the highest current sort order plus 1.
This reflects the order in which states and actions are added to the
workflow starting with 1
@author Peter Marklund
} {
- set sort_order_current \
- [db_string max_sort_order "select max(sort_order) \
- from $table_name \
- where workflow_id = $workflow_id" \
- -default 0]
+ set max_sort_order [db_string max_sort_order {} -default 0]
- set sort_order [expr $sort_order_current + 1]
+ return [expr $max_sort_order + 1]
+}
- return $sort_order
+ad_proc -private workflow::callback_insert {
+ {-workflow_id:required}
+ {-name:required}
+ {-sort_order {}}
+} {
+ Add a side-effect to a workflow.
+
+ @param workflow_id The ID of the workflow.
+ @param name Name of service contract implementation, in the form (impl_owner_name).(impl_name),
+ for example, bug-tracker.FormatLogTitle.
+ @param sort_order The sort_order for the rule. Leave blank to add to the end of the list
+
+ @author Lars Pind (lars@collaboraid.biz)
+} {
+ # TODO:
+ # Insert for real when the service contracts have been defined
+
+ ns_log Error "LARS: workflow::callback_insert -- would have inserted the callback $name to workflow $workflow_id"
+ return
+
+ db_transaction {
+
+ # Get the impl_id
+ set acs_sc_impl_id [workflow::service_contract::get_impl_id -name $name]
+
+ # Get the sort order
+ if { ![exists_and_not_null sort_order] } {
+ set sort_order [db_string select_sort_order {}]
+ }
+
+ # Insert the callback
+ db_dml insert_callback {}
+ }
+ return $acs_sc_impl_id
}
+
+
#####
#
+# workflow::fsm namespace
+#
+#####
+
+ad_proc -public workflow::fsm::new {
+ {-short_name:required}
+ {-pretty_name:required}
+ {-object_id:required}
+ {-object_type "acs_object"}
+ {-callbacks {}}
+ {-spec}
+} {
+ Creates a new FSM workflow, with an optional spec argument.
+
+ @param short_name For referring to the workflow from Tcl code. Use Tcl variable syntax.
+ @param pretty_name A human readable name for the workflow for use in the UI.
+ @param object_id The id of an ACS Object indicating the scope the workflow.
+ Typically this will be the id of a package type or a package instance
+ but it could also be some other type of ACS object within a package, for example
+ the id of a bug in the Bug Tracker application.
+ @param object_type The type of objects that the workflow will be applied to. Valid values are in the
+ acs_object_types table. The parameter is optional and defaults to acs_object.
+ @param spec The workflow spec in array-lists-in-array-lists format.
+
+ @author Lars Pind (lars@collaboraid.biz)
+ @see workflow::new
+} {
+
+ db_transaction {
+
+ # Create the workflow
+ set workflow_id [workflow::new \
+ -short_name $short_name \
+ -pretty_name $pretty_name \
+ -object_id $object_id \
+ -object_type $object_type \
+ -callbacks $callbacks]
+
+ # May need to parse the simple workflow notation
+ if { [exists_and_not_null spec] } {
+ parse_spec -workflow_id $workflow_id -spec $spec
+ }
+ }
+
+ return $workflow_id
+}
+
+ad_proc -private workflow::fsm::parse_spec {
+ {-workflow_id:required}
+ {-spec:required}
+} {
+ Parse the -workflow argument to workflow::new and create roles,
+ states, actions, etc., as appropriate
+
+ @param workflow_id The id of the workflow to delete.
+ @param spec The roles spec
+
+ @author Lars Pind (lars@collaboraid.biz)
+ @see workflow::new
+} {
+ array set workflow { roles {} states {} actions {} }
+ array set workflow $spec
+
+ workflow::role::parse_roles_spec \
+ -workflow_id $workflow_id \
+ -spec $workflow(roles)
+
+ workflow::state::fsm::parse_states_spec \
+ -workflow_id $workflow_id \
+ -spec $workflow(states)
+
+ workflow::action::fsm::parse_actions_spec \
+ -workflow_id $workflow_id \
+ -spec $workflow(actions)
+}
+
+
+
+
+
+
+
+#####
+#
# workflow::service_contract
#
#####
@@ -146,3 +337,15 @@
return "ActivityLog_FormatTitle"
}
+ad_proc -public workflow::service_contract::get_impl_id {
+ {-name:required}
+} {
+ set namev [split $name "."]
+
+ set impl_owner_name [lindex $namev 0]
+ set impl_name [lindex $namev 1]
+
+ set acs_sc_impl_id [db_string select_impl_id {}]
+
+ return $acs_sc_impl_id
+}
Index: openacs-4/packages/workflow/tcl/workflow-procs.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/workflow-procs.xql,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/workflow/tcl/workflow-procs.xql 20 Jan 2003 15:45:00 -0000 1.2
+++ openacs-4/packages/workflow/tcl/workflow-procs.xql 21 Jan 2003 18:06:00 -0000 1.3
@@ -1,7 +1,7 @@
-
+
select workflow_id
from workflows
@@ -10,12 +10,53 @@
-
+
+ select workflow_id
+ from workflows
+ where package_key = :package_key
+ and short_name = :short_name
+
+
+
+
+
select action_id
from workflow_initial_action
where workflow_id = :workflow_id
+
+
+ select max(sort_order)
+ from $table_name
+ where workflow_id = :workflow_id
+
+
+
+
+
+ select coalesce(max(sort_order)) + 1
+ from workflow_callbacks
+ where workflow_id = :workflow_id
+
+
+
+
+
+ insert into workflow_callbacks (workflow_id, acs_sc_impl_id, sort_order)
+ values (:workflow_id, :acs_sc_impl_id, :sort_order)
+
+
+
+
+
+ select impl_id
+ from acs_sc_impls
+ where impl_owner_name = :impl_owner_name
+ and impl_name = :impl_name
+
+
+
Index: openacs-4/packages/workflow/tcl/test/workflow-test-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/test/workflow-test-procs.tcl,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/workflow/tcl/test/workflow-test-procs.tcl 20 Jan 2003 15:45:00 -0000 1.2
+++ openacs-4/packages/workflow/tcl/test/workflow-test-procs.tcl 21 Jan 2003 18:06:13 -0000 1.3
@@ -28,8 +28,9 @@
ad_proc workflow::test::workflow_id {} {
Get the id of the Bug Tracker bug workflow
} {
- return [workflow::get_id -object_id [workflow::test::workflow_object_id] \
- -short_name [workflow::test::workflow_name]]
+ return [workflow::get_id \
+ -object_id [workflow::test::workflow_object_id] \
+ -short_name [workflow::test::workflow_name]]
}
ad_proc workflow::test::admin_owner_id {} {
@@ -47,7 +48,7 @@
} {
set short_name_list [list]
foreach action_id $action_id_list {
- array set action_info [workflow::action::get -action_id $action_id]
+ workflow::action::get -action_id $action_id -array action_info
lappend short_name_list $action_info(short_name)
}
@@ -73,10 +74,13 @@
-user_id [workflow::test::admin_owner_id]]
set enabled_actions [workflow::test::action_short_names \
[workflow::case::get_enabled_actions -case_id $case_id]]
- array set state_info \
- [workflow::state::fsm::get -state_id [workflow::case::fsm::get_current_state -case_id $case_id]]
+
+ workflow::state::fsm::get \
+ -state_id [workflow::case::fsm::get_current_state -case_id $case_id] \
+ -array state_info
+
set user_actions [workflow::test::action_short_names \
- [workflow::case::get_user_actions -case_id $case_id \
+ [workflow::case::get_available_actions -case_id $case_id \
-user_id [workflow::test::admin_owner_id]]]
aa_true "current state should be $expect_current_state" \
@@ -89,6 +93,101 @@
[empty_string_p $user_roles]
}
+ad_proc workflow::test::workflow_setup_array_style {} {
+ Create a test workflow for the Bug Tracker
+ Bug use case.
+} {
+ set spec {
+ roles {
+ submitter {
+ pretty_name "Submitter"
+ callbacks {
+ workflow.CreationUser
+ }
+ }
+ assignee {
+ pretty_name "Assignee"
+ callbacks {
+ bug-tracker.ComponentMaintainer
+ bug-tracker.ProjectMaintainer
+ }
+ }
+ }
+ states {
+ open {
+ pretty_name "Open"
+ }
+ resolved {
+ pretty_name "Resolved"
+ }
+ closed {
+ pretty_name "Closed"
+ }
+ }
+ actions {
+ open {
+ pretty_name "Open"
+ pretty_past_tense "Opened"
+ new_state "open"
+ initial_action_p 1
+ }
+ comment {
+ pretty_name "Comment"
+ pretty_past_tense "Commented"
+ allowed_roles { submitter assignee }
+ privileges { read }
+ always_enabled_p t
+ }
+ edit {
+ pretty_name "Edit"
+ pretty_past_tense "Edited"
+ allowed_roles { submitter assignee }
+ privileges { write }
+ always_enabled_p t
+ }
+ resolve {
+ pretty_name "Resolve"
+ pretty_past_tense "Resolved"
+ assigned_roles { assignee }
+ enabled_states { open resolved }
+ new_state "resolved"
+ privileges { write }
+ callbacks { bug-tracker.CaptureResolutionCode }
+ }
+ close {
+ pretty_name "Close"
+ pretty_past_tense "Closed"
+ assigned_roles { submitter }
+ enabled_states { resolved }
+ new_state "closed"
+ privileges { write }
+ }
+ reopen {
+ pretty_name "Reopen"
+ pretty_past_tense "Closed"
+ allowed_roles { submitter }
+ enabled_states { resolved closed }
+ new_state "open"
+ privileges { write }
+ }
+ }
+ }
+
+ set main_site_package_id [workflow::test::workflow_object_id]
+
+ # Cannot use bt_bug as we cannot assume Bug Tracker to be installed
+
+ set workflow_id [workflow::fsm::new \
+ -short_name [workflow::test::workflow_name] \
+ -pretty_name "Bug Test" \
+ -object_id $main_site_package_id \
+ -object_type "acs_object" \
+ -callbacks { bug-tracker.FormatLogTitle } \
+ -spec $spec]
+
+ return $workflow_id
+}
+
ad_proc workflow::test::workflow_setup {} {
Create a test workflow for the Bug Tracker
Bug use case.
@@ -100,35 +199,34 @@
#####
set main_site_package_id [workflow::test::workflow_object_id]
+
# Cannot use bt_bug as we cannot assume Bug Tracker to be installed
- # TODO: test side_effects?
- # -side_effects { bug-tracker.FormatLogTitle }
+
set workflow_id [workflow::new \
-short_name [workflow::test::workflow_name] \
-pretty_name "Bug Test" \
-object_id $main_site_package_id \
- -object_type "acs_object"]
+ -object_type "acs_object" \
+ -callbacks { bug-tracker.FormatLogTitle }]
#####
#
# Roles
#
#####
- # TODO: add assignment rules?
- # -assignment_rules { workflow.CreationUser }
workflow::role::new -workflow_id $workflow_id \
-short_name "submitter" \
- -pretty_name "Submitter"
+ -pretty_name "Submitter" \
+ -callbacks { workflow.CreationUser }
- # TODO: add assignment rules?
- # -assignment_rules {
- # bug-tracker.ComponentMaintainer
- # bug-tracker.ProjectMaintainer
- # }
workflow::role::new -workflow_id $workflow_id \
-short_name "assignee" \
- -pretty_name "Assignee"
+ -pretty_name "Assignee" \
+ -callbacks {
+ bug-tracker.ComponentMaintainer
+ bug-tracker.ProjectMaintainer
+ }
#####
#
@@ -154,41 +252,45 @@
#
#####
- workflow::action::fsm::new -initial_action \
- -workflow_id $workflow_id \
- -short_name "open" \
- -pretty_name "Open" \
- -pretty_past_tense "Opened" \
- -new_state "open"
-
- workflow::action::fsm::new -workflow_id $workflow_id \
+ workflow::action::fsm::new \
+ -initial_action \
+ -workflow_id $workflow_id \
+ -short_name "open" \
+ -pretty_name "Open" \
+ -pretty_past_tense "Opened" \
+ -new_state "open"
+
+ workflow::action::fsm::new \
+ -workflow_id $workflow_id \
-short_name "comment" \
-pretty_name "Comment" \
-pretty_past_tense "Commented" \
-allowed_roles { submitter assignee } \
-privileges { read } \
-always_enabled_p t
- workflow::action::fsm::new -workflow_id $workflow_id \
+ workflow::action::fsm::new \
+ -workflow_id $workflow_id \
-short_name "edit" \
-pretty_name "Edit" \
-pretty_past_tense "Edited" \
-allowed_roles { submitter assignee } \
-privileges { write } \
-always_enabled_p t
- # TODO add side effects?
- # -side_effects { bug-tracker.CaptureResolutionCode }
- workflow::action::fsm::new -workflow_id $workflow_id \
+ workflow::action::fsm::new \
+ -workflow_id $workflow_id \
-short_name "resolve" \
-pretty_name "Resolve" \
-pretty_past_tense "Resolved" \
-assigned_role { assignee } \
-enabled_states { open resolved } \
-new_state "resolved" \
- -privileges { write }
+ -privileges { write } \
+ -callbacks { bug-tracker.CaptureResolutionCode }
- workflow::action::fsm::new -workflow_id $workflow_id \
+ workflow::action::fsm::new \
+ -workflow_id $workflow_id \
-short_name "close" \
-pretty_name "Close" \
-pretty_past_tense "Closed" \
@@ -197,7 +299,8 @@
-new_state "closed" \
-privileges { write }
- workflow::action::fsm::new -workflow_id $workflow_id \
+ workflow::action::fsm::new \
+ -workflow_id $workflow_id \
-short_name "reopen" \
-pretty_name "Reopen" \
-pretty_past_tense "Closed" \
@@ -212,10 +315,14 @@
ad_proc workflow::test::workflow_teardown {} {
Delete the Bug Tracker Bug test workflow.
} {
- set workflow_id [workflow::get_id -object_id [workflow::test::workflow_object_id] \
- -short_name [workflow::test::workflow_name]]
+ # We don't care about error here
+ catch {
+ set workflow_id [workflow::get_id \
+ -object_id [workflow::test::workflow_object_id] \
+ -short_name [workflow::test::workflow_name]]
- workflow::delete -workflow_id $workflow_id
+ workflow::delete -workflow_id $workflow_id
+ }
}
@@ -235,77 +342,115 @@
return $case_id
}
-aa_register_case bugtracker_workflow_create {
- Test creation and teardown of an FSM workflow case.
-
- @author Peter Marklund
- @creation-date 16 January 2003
+ad_proc workflow::test::run_bug_tracker_test {
+ {-create_proc "workflow_setup"}
} {
- # Setup
- # Make sure to run the teardown proc even if there is an error
- # Cannot get this to work as it seems the catch will return true
- # if any catch did so in the executed code.
- # set error_p [catch workflow::test::workflow_setup error]
- set workflow_id [workflow::test::workflow_setup]
+ set test_chunk {
+ # Setup
+ # Make sure to run the teardown proc even if there is an error
+ # Cannot get this to work as it seems the catch will return true
+ # if any catch did so in the executed code.
+ # set error_p [catch workflow::test::workflow_setup error]
+ set workflow_id [workflow::test::$create_proc]
+
+ # Create the workflow case in open state
+ set object_id [workflow::test::workflow_object_id]
+ set case_id [workflow::test::case_setup]
+
+ set retrieved_case_id \
+ [workflow::case::get_id \
+ -object_id $object_id \
+ -workflow_short_name [workflow::test::workflow_name]]
+
+ set retrieved_object_id \
+ [workflow::case::get_object_id -case_id $case_id]
+
+ aa_true "case_id of a created workflow case should be retrievable" \
+ [string equal $case_id $retrieved_case_id]
+ aa_true "object_id of a created workflow case should be retrievable" \
+ [string equal $object_id $retrieved_object_id]
+
+ set expect_enabled_actions [list comment edit resolve]
+ workflow::test::assert_case_state \
+ -workflow_id $workflow_id \
+ -case_id $case_id \
+ -expect_current_state open \
+ -expect_enabled_actions $expect_enabled_actions \
+ -expect_user_actions $expect_enabled_actions \
+ -expect_user_roles {}
+
+ # Resolve the bug
+ workflow::case::action::execute \
+ -case_id $case_id \
+ -action_id [workflow::action::get_id -workflow_id $workflow_id \
+ -short_name "resolve"] \
+ -comment "Resolving Bug" \
+ -comment_format plain \
+ -user_id [workflow::test::admin_owner_id]
+
+ set expect_enabled_actions [list comment edit resolve reopen close]
+ workflow::test::assert_case_state \
+ -workflow_id $workflow_id \
+ -case_id $case_id \
+ -expect_current_state resolved \
+ -expect_enabled_actions $expect_enabled_actions \
+ -expect_user_actions $expect_enabled_actions \
+ -expect_user_roles {}
+
+ # Close the bug
+ workflow::case::action::execute \
+ -case_id $case_id \
+ -action_id [workflow::action::get_id -workflow_id $workflow_id \
+ -short_name "close"] \
+ -comment "Closing Bug" \
+ -comment_format plain \
+ -user_id [workflow::test::admin_owner_id]
+
+ set expect_enabled_actions [list comment edit reopen]
+ workflow::test::assert_case_state \
+ -workflow_id $workflow_id \
+ -case_id $case_id \
+ -expect_current_state closed \
+ -expect_enabled_actions $expect_enabled_actions \
+ -expect_user_actions $expect_enabled_actions \
+ -expect_user_roles {}
+
+ }
- # Create the workflow case in open state
- set object_id [workflow::test::workflow_object_id]
- set case_id [workflow::test::case_setup]
+ set error_p [catch $test_chunk errMsg]
+
+ # Teardown
+ workflow::test::workflow_teardown
- set retrieved_case_id \
- [workflow::case::get_id -object_id $object_id \
- -workflow_short_name [workflow::test::workflow_name]]
- set retrieved_object_id \
- [workflow::case::get_object_id -case_id $case_id]
- aa_true "case_id of a created workflow case should be retrievable" \
- [string equal $case_id $retrieved_case_id]
- aa_true "object_id of a created workflow case should be retrievable" \
- [string equal $object_id $retrieved_object_id]
+ # Report any errors from the setup proc
+ global errorInfo
+ aa_false "error during setup: $errMsg - $errorInfo" $error_p
+}
- set expect_enabled_actions [list comment edit resolve]
- workflow::test::assert_case_state -workflow_id $workflow_id \
- -case_id $case_id \
- -expect_current_state open \
- -expect_enabled_actions $expect_enabled_actions \
- -expect_user_actions $expect_enabled_actions \
- -expect_user_roles {}
- # Resolve the bug
- workflow::case::action::execute -case_id $case_id \
- -action_id [workflow::action::get_id -workflow_id $workflow_id \
- -short_name "resolve"] \
- -comment "Resolving Bug" \
- -comment_format plain \
- -user_id [workflow::test::admin_owner_id]
- set expect_enabled_actions [list comment edit resolve reopen close]
- workflow::test::assert_case_state -workflow_id $workflow_id \
- -case_id $case_id \
- -expect_current_state resolved \
- -expect_enabled_actions $expect_enabled_actions \
- -expect_user_actions $expect_enabled_actions \
- -expect_user_roles {}
-
- # Close the bug
- workflow::case::action::execute -case_id $case_id \
- -action_id [workflow::action::get_id -workflow_id $workflow_id \
- -short_name "close"] \
- -comment "Closing Bug" \
- -comment_format plain \
- -user_id [workflow::test::admin_owner_id]
- set expect_enabled_actions [list comment edit reopen]
- workflow::test::assert_case_state -workflow_id $workflow_id \
- -case_id $case_id \
- -expect_current_state closed \
- -expect_enabled_actions $expect_enabled_actions \
- -expect_user_actions $expect_enabled_actions \
- -expect_user_roles {}
+#####
+#
+# Register the test cases
+#
+#####
- # Teardown
- workflow::test::workflow_teardown
+aa_register_case bugtracker_workflow_create_normal {
+ Test creation and teardown of an FSM workflow case.
- # Report any errors from the setup proc
- #global errorInfo
- #aa_false "error during setup: $error - $errorInfo" $error_p
+ @author Peter Marklund
+ @creation-date 16 January 2003
+} {
+ workflow::test::run_bug_tracker_test -create_proc "workflow_setup"
}
+
+aa_register_case bugtracker_workflow_create_array_style {
+ Test creation and teardown of an FSM workflow case, with array style specification.
+
+ @author Peter Marklund
+ @creation-date 16 January 2003
+} {
+ workflow::test::run_bug_tracker_test -create_proc "workflow_setup_array_style"
+}
+