/// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Close the requested job
            try
            {
                IJTXJobManager     jobManager = this.WmxDatabase.JobManager;
                IJTXJob3           job        = jobManager.GetJob(m_jobToClose) as IJTXJob3;
                IJTXConfiguration3 configMgr  = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;

                if (job.Stage != jtxJobStage.jtxJobStageClosed && !job.CanClose())
                {
                    throw new WmauException(WmauErrorCodes.C_CANNOT_CLOSE_JOB_ERROR);
                }

                msgs.AddMessage("Closing job " + m_jobToClose + " (" + job.Name + ")");
                job.Close();

                // Once the job is closed, do the other things that still need to be handled
                // separately (status updates, notifications, ...)
                Common.WmauHelperFunctions.UpdateJobStatus(this.WmxDatabase, job);
                job.Store();

                job.LogJobAction(
                    configMgr.GetActivityType(ESRI.ArcGIS.JTX.Utilities.Constants.ACTTYPE_CLOSE_JOB),
                    null,
                    string.Empty);
                Common.WmauHelperFunctions.SendNotification(
                    ESRI.ArcGIS.JTX.Utilities.Constants.NOTIF_JOB_CLOSED,
                    this.WmxDatabase,
                    job);

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_JOB_CLOSED);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobToClose;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Builds a domain consisting of the IDs of every job in the database that
        /// has not already been closed.
        /// </summary>
        /// <param name="wmxDb">A reference to the active Workflow Manager database</param>
        /// <returns>A coded value domain as an IGPDomain</returns>
        public static IGPDomain BuildNonClosedJobIdDomain(IJTXDatabase3 wmxDb)
        {
            IGPCodedValueDomain domain = new GPCodedValueDomainClass();

            // Set up a query filter to return only those jobs that are not closed
            IQueryFilter queryFilter = new QueryFilterClass();

            queryFilter.WhereClause =
                ESRI.ArcGIS.JTX.Utilities.Constants.FIELD_STAGE + " <> '" +
                ((int)jtxJobStage.jtxJobStageClosed).ToString() + "'";

            IJTXJobSet nonClosedJobs = wmxDb.JobManager.GetJobsByQuery(queryFilter);

            // Iterate through this job list, sorting the IDs
            SortedList <int, string> sortedJobIds = new SortedList <int, string>();

            for (int i = 0; i < nonClosedJobs.Count; i++)
            {
                IJTXJob3 job = nonClosedJobs.get_Item(i) as IJTXJob3;
                sortedJobIds[job.ID] = null;
            }

            // Build a GP domain from the sorted job IDs.
            foreach (int id in sortedJobIds.Keys)
            {
                IGPValue tempGpVal = new GPLongClass();
                tempGpVal.SetAsText(id.ToString());
                domain.AddCode(tempGpVal, id.ToString());
            }

            return(domain as IGPDomain);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Assign the requested job
            try
            {
                IJTXJobManager     jobManager = this.WmxDatabase.JobManager;
                IJTXConfiguration3 configMgr  = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;
                IJTXJob3           job        = jobManager.GetJob(m_jobId) as IJTXJob3;

                // As of Jan. 2011, the core Workflow Manager libraries do not
                // seem to check if the user has the privilege to add a comment
                // if a job as a hold on it.  So run the check here.
                IJTXJobHolds jobHolds = job as IJTXJobHolds;
                if (jobHolds.Holds != null &&
                    jobHolds.Holds.Count > 0 &&
                    !CurrentUserHasPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_CAN_ADD_COMMENTS_FOR_HELD_JOBS))
                {
                    throw new WmauException(WmauErrorCodes.C_NO_ADD_COMMENTS_HELD_JOBS_ERROR);
                }

                // If we get this far, then add the comment to the job.
                IJTXActivityType commentType = configMgr.GetActivityType(ESRI.ArcGIS.JTX.Utilities.Constants.ACTTYPE_COMMENT);
                job.LogJobAction(commentType, null, m_comment);
                job.Store();

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_JOB_ID);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobId;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
        /// <summary>
        /// Find those priority levels in the database that are not being used by any
        /// job or job type.
        /// </summary>
        /// <returns>The total number of orphaned items found</returns>
        private int UpdateOrphanedPriorityTypes()
        {
            Dictionary <int, string> usedTypes = new Dictionary <int, string>();
            IJTXDatabase3            wmxDb     = this.WmxDatabase;

            // Check all the jobs for priorities currently in use
            IJTXJobSet allJobs = wmxDb.JobManager.GetAllJobs();

            for (int i = 0; i < allJobs.Count; i++)
            {
                IJTXJob3 job = allJobs.get_Item(i) as IJTXJob3;
                if (!usedTypes.ContainsKey(job.Priority.Value))
                {
                    usedTypes[job.Priority.Value] = job.Priority.Name;
                }
            }

            // Check the template job types for default priorities in use
            IJTXJobTypeSet allJobTypes = wmxDb.ConfigurationManager.JobTypes;

            for (int i = 0; i < allJobTypes.Count; i++)
            {
                // TODO: Skip unused job types

                IJTXJobType3 jobType = allJobTypes.get_Item(i) as IJTXJobType3;
                if (!usedTypes.ContainsKey(jobType.DefaultPriority.Value))
                {
                    usedTypes[jobType.DefaultPriority.Value] = jobType.DefaultPriority.Name;
                }
            }

            // Loop over all of the priorities.  For anything whose name is not contained
            // in the "used" list, add it to the "unused" list.  If all of the items are
            // used, don't bother trying to add to the unused list.
            IJTXPrioritySet allTypes = wmxDb.ConfigurationManager.Priorities;

            if (usedTypes.Count != allTypes.Count)
            {
                for (int i = 0; i < allTypes.Count; i++)
                {
                    IJTXPriority priority = allTypes.get_Item(i) as IJTXPriority;
                    if (!usedTypes.ContainsKey(priority.Value))
                    {
                        m_unusedPriorities[priority.Value] = priority.Name;
                    }
                }
            }

            return(m_unusedPriorities.Count);
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Assign the requested job
            try
            {
                IJTXJobManager     jobManager = this.WmxDatabase.JobManager;
                IJTXJob3           job        = jobManager.GetJob(m_jobId) as IJTXJob3;
                IJTXConfiguration3 configMgr  = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;

                // As of Jan. 2011, the core Workflow Manager libraries do not
                // seem to check if the user has the privilege to add an attachment
                // if a job as a hold on it.  So run the check here.
                IJTXJobHolds jobHolds = job as IJTXJobHolds;
                if (jobHolds.Holds != null &&
                    jobHolds.Holds.Count > 0 &&
                    !CurrentUserHasPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_CAN_ADD_ATTACHES_FOR_HELD_JOBS))
                {
                    throw new WmauException(WmauErrorCodes.C_NO_ADD_ATTACHMENTS_HELD_JOBS_ERROR);
                }

                // If we get this far, then figure out how to associate the attachment
                // with the job, and add the attachment.
                jtxFileStorageType attachmentType;
                if (m_attachmentType.Equals(C_OPT_EMBEDDED))
                {
                    attachmentType = jtxFileStorageType.jtxStoreInDB;
                }
                else
                {
                    attachmentType = jtxFileStorageType.jtxStoreAsLink;
                }

                msgs.AddMessage("Adding attachment '" + m_attachmentPath + "' to job " + m_jobId + " (" + job.Name + ")");
                job.AddAttachment(m_attachmentPath, attachmentType, m_attachmentType);
                job.Store();

                // Do the other things that still need to be handled manually, such as logging
                // the job's reassignment and sending any necessary notifications.
                IPropertySet propSet = new PropertySetClass();
                propSet.SetProperty(C_PROP_VAL_ATTACHMENT, "'" + m_attachmentPath + "'");
                job.LogJobAction(
                    configMgr.GetActivityType(ESRI.ArcGIS.JTX.Utilities.Constants.ACTTYPE_ADD_ATTACHMENT),
                    propSet,
                    string.Empty);
                Common.WmauHelperFunctions.SendNotification(
                    ESRI.ArcGIS.JTX.Utilities.Constants.NOTIF_ATTACHMENT_ADDED,
                    this.WmxDatabase,
                    job);

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_JOB_ID);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobId;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
 /// <summary>
 /// Helper function to update the status of a job
 /// </summary>
 /// <param name="wmxDb">A reference to the active Workflow Manager database</param>
 /// <param name="job">The job whose status is to be updated</param>
 public static void UpdateJobStatus(IJTXDatabase wmxDb, IJTXJob3 job)
 {
     // NOTE: The ConfigurationCache must be initialized before calling this function
     // (this is now handled elsewhere).
     ESRI.ArcGIS.JTXUI.JobUtilities.UpdateStatusOfJob(wmxDb, job, false);
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            // Assign the requested job
            try
            {
                IJTXJobManager     jobManager = this.WmxDatabase.JobManager;
                IJTXJob3           job        = jobManager.GetJob(m_jobId) as IJTXJob3;
                IJTXConfiguration3 configMgr  = this.WmxDatabase.ConfigurationManager as IJTXConfiguration3;

                jtxAssignmentType assigneeType;
                string            descriptionStr;
                string            assigneeStr;
                if (m_assigneeType.Equals(C_OPT_ASSIGN_TO_GROUP))
                {
                    assigneeType   = jtxAssignmentType.jtxAssignmentTypeGroup;
                    assigneeStr    = m_assignee;
                    descriptionStr = "group '" + assigneeStr + "'";
                }
                else if (m_assigneeType.Equals(C_OPT_ASSIGN_TO_USER))
                {
                    assigneeType   = jtxAssignmentType.jtxAssignmentTypeUser;
                    assigneeStr    = m_assignee;
                    descriptionStr = "user '" + assigneeStr + "'";
                }
                else
                {
                    assigneeType   = jtxAssignmentType.jtxAssignmentTypeUnassigned;
                    assigneeStr    = string.Empty;
                    descriptionStr = "no one (unassigned)";
                }

                msgs.AddMessage("Assigning job " + m_jobId + " (" + job.Name + ") to " + descriptionStr);
                job.AssignedType = assigneeType;
                job.AssignedTo   = assigneeStr;
                job.Store();

                // Do the other things that still need to be handled manually, such as logging
                // the job's reassignment and sending any necessary notifications.
                job.LogJobAction(
                    configMgr.GetActivityType(ESRI.ArcGIS.JTX.Utilities.Constants.ACTTYPE_ASSIGN_JOB),
                    null,
                    string.Empty);
                Common.WmauHelperFunctions.SendNotification(
                    ESRI.ArcGIS.JTX.Utilities.Constants.NOTIF_JOB_ASSIGNED,
                    this.WmxDatabase,
                    job);

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_OUT_JOB_ID);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobId;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (WmauException wmEx)
            {
                try
                {
                    msgs.AddError(wmEx.ErrorCodeAsInt, wmEx.Message);
                }
                catch
                {
                    // Catch anything else that possibly happens
                }
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_UNSPECIFIED_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }
        /// <summary>
        /// Find those users in the database who are not being referenced in any way
        /// </summary>
        /// <returns>The total number of orphaned items found</returns>
        private int UpdateOrphanedUsers()
        {
            SortedList <string, string> unusedItems = new SortedList <string, string>();
            IJTXDatabase3      wmxDb     = this.WmxDatabase;
            IJTXConfiguration3 configMgr = wmxDb.ConfigurationManager as IJTXConfiguration3;
            IJTXJobManager     jobMgr    = wmxDb.JobManager;
            IJTXUserSet        allUsers  = configMgr.Users;

            Dictionary <string, string> usedItems = new Dictionary <string, string>();

            // Get all of the users who are members of a group
            IJTXUserGroupSet allGroups = configMgr.UserGroups;

            for (int i = 0; i < allGroups.Count; i++)
            {
                IJTXUserGroup2 group = allGroups.get_Item(i) as IJTXUserGroup2;
                for (int j = 0; j < group.Users.Count; j++)
                {
                    IJTXUser3 user = group.Users.get_Item(j) as IJTXUser3;
                    usedItems[user.UserName] = user.FullName;
                }
            }

            // If necessary, add in the users who have jobs assigned to them
            if (usedItems.Count < allUsers.Count)
            {
                IJTXJobSet allJobs = jobMgr.GetAllJobs();
                for (int i = 0; i < allJobs.Count; i++)
                {
                    IJTXJob3 job = allJobs.get_Item(i) as IJTXJob3;
                    if (job.AssignedType == jtxAssignmentType.jtxAssignmentTypeUser)
                    {
                        IJTXUser3 user = configMgr.GetUser(job.AssignedTo) as IJTXUser3;

                        // It's possible for a user to have a job assigned, but have
                        // already been removed from the DB.  Throw an exception in
                        // this case, as the DB needs to be cleaned up.
                        if (user == null)
                        {
                            throw new WmauException(WmauErrorCodes.C_USER_NOT_FOUND_ERROR);
                        }
                        usedItems[user.UserName] = user.FullName;
                    }
                }
            }

            // If necessary, add in the users who have a job type's default assignment
            // set to them
            if (usedItems.Count < allUsers.Count)
            {
                IJTXJobTypeSet allJobTypes = configMgr.JobTypes;
                for (int i = 0; i < allJobTypes.Count; i++)
                {
                    // TODO: Exclude orphaned job types

                    IJTXJobType3 jobType = allJobTypes.get_Item(i) as IJTXJobType3;
                    if (jobType.DefaultAssignedType == jtxAssignmentType.jtxAssignmentTypeUser)
                    {
                        IJTXUser3 user = configMgr.GetUser(jobType.DefaultAssignedTo) as IJTXUser3;

                        // It's possible for a user to have a job assigned, but have
                        // already been removed from the DB.  Throw an exception in
                        // this case, as the DB needs to be cleaned up.
                        if (user == null)
                        {
                            throw new WmauException(WmauErrorCodes.C_USER_NOT_FOUND_ERROR);
                        }
                        usedItems[user.UserName] = user.FullName;
                    }
                }
            }

            // If necessary, add in the users who have steps assigned to them
            // by default
            if (usedItems.Count < allUsers.Count)
            {
                IJTXWorkflowSet allWorkflows = configMgr.Workflows;
                for (int i = 0; i < allWorkflows.Count; i++)
                {
                    // Skip over unused workflows
                    IJTXWorkflow workflow = allWorkflows.get_Item(i);
                    if (m_unusedWorkflows.Keys.Contains(workflow.ID))
                    {
                        continue;
                    }

                    // Examine the other items
                    IJTXWorkflowConfiguration workflowCfg = allWorkflows.get_Item(i) as IJTXWorkflowConfiguration;
                    int[] workflowStepIds = workflowCfg.GetAllSteps();
                    foreach (int j in workflowStepIds)
                    {
                        IJTXStep3 step = workflowCfg.GetStep(j) as IJTXStep3;
                        if (step.AssignedType == jtxAssignmentType.jtxAssignmentTypeUser)
                        {
                            IJTXUser3 user = configMgr.GetUser(step.AssignedTo) as IJTXUser3;

                            // It's possible for a user to have a job assigned, but have
                            // already been removed from the DB.  Throw an exception in
                            // this case, as the DB needs to be cleaned up.
                            if (user == null)
                            {
                                throw new WmauException(WmauErrorCodes.C_USER_NOT_FOUND_ERROR);
                            }
                            usedItems[user.UserName] = user.FullName;
                        }
                    }
                }
            }

            // Loop over all the users in the DB, looking for anything
            // that we didn't identify as "in use"
            for (int i = 0; i < allUsers.Count; i++)
            {
                IJTXUser3 item = allUsers.get_Item(i) as IJTXUser3;
                if (!usedItems.ContainsKey(item.UserName))
                {
                    m_unusedUsers[item.UserName] = item.FullName;
                }
            }

            return(m_unusedUsers.Count);
        }
        /// <summary>
        /// Find those status types in the database that are not being used by any step.
        /// </summary>
        /// <returns>The total number of orphaned items found</returns>
        private int UpdateOrphanedStatusTypes()
        {
            Dictionary <int, int> usedStatusTypes = new Dictionary <int, int>();
            IJTXDatabase3         wmxDb           = this.WmxDatabase;

            string[] coreStatusNames =
            {
                C_STATUS_CLOSED,
                C_STATUS_CREATED,
                C_STATUS_DONE_WORKING,
                C_STATUS_READY_TO_WORK,
                C_STATUS_WORKING
            };

            IJTXConfiguration3 configMgr = wmxDb.ConfigurationManager as IJTXConfiguration3;

            // Iterate through each job currently in the system, adding the status types used
            // by these jobs
            IJTXJobSet jobs = wmxDb.JobManager.GetAllJobs();

            for (int i = 0; i < jobs.Count; i++)
            {
                IJTXJob3 job = jobs.get_Item(i) as IJTXJob3;
                if (job.Status != null)
                {
                    usedStatusTypes[job.Status.ID] = job.Status.ID;
                }
            }

            // Iterate through each workflow, building up the list of used status types
            // based on the statuses that are assigned by each step
            IJTXWorkflowSet workflows = configMgr.Workflows;

            for (int i = 0; i < workflows.Count; i++)
            {
                // Skip over those workflows that aren't in use
                IJTXWorkflow workflow = workflows.get_Item(i);
                if (m_unusedWorkflows.Keys.Contains(workflow.ID))
                {
                    continue;
                }

                // Examine the remaining workflows
                IJTXWorkflowConfiguration workflowCfg = workflows.get_Item(i) as IJTXWorkflowConfiguration;
                int[] stepIds = workflowCfg.GetAllSteps();
                foreach (int stepId in stepIds)
                {
                    IJTXStep3 step = workflowCfg.GetStep(stepId) as IJTXStep3;
                    usedStatusTypes[step.StatusID] = step.StatusID;
                }
            }

            // Add the status types used by Workflow Manager itself
            foreach (string s in coreStatusNames)
            {
                IJTXStatus2 status = configMgr.GetStatus(s) as IJTXStatus2;

                // Avoid problems if someone deleted one of these mandatory types from the database
                if (status != null)
                {
                    int id = status.ID;
                    usedStatusTypes[id] = id;
                }
            }

            // Get the complete list of status types in the database
            IJTXStatusSet allStatusTypes = configMgr.Statuses;

            // Loop over all of the status types.  For anything whose ID is not contained
            // in the "used" list, add it to the "unused" list. If all of the items are
            // used, don't bother trying to add to the unused list.
            if (usedStatusTypes.Count != allStatusTypes.Count)
            {
                for (int i = 0; i < allStatusTypes.Count; i++)
                {
                    IJTXStatus2 statusType = allStatusTypes.get_Item(i) as IJTXStatus2;
                    if (!usedStatusTypes.ContainsKey(statusType.ID))
                    {
                        m_unusedStatusTypes[statusType.ID] = statusType.Name;
                    }
                }
            }

            return(m_unusedStatusTypes.Count);
        }
        /// <summary>
        /// Required by IGPFunction2 interface; this function is called when the GP tool is ready to be executed.
        /// </summary>
        /// <param name="paramValues"></param>
        /// <param name="trackCancel"></param>
        /// <param name="envMgr"></param>
        /// <param name="msgs"></param>
        public override void Execute(IArray paramValues, ITrackCancel trackCancel, IGPEnvironmentManager envMgr, IGPMessages msgs)
        {
            // Do some common error-checking
            base.Execute(paramValues, trackCancel, envMgr, msgs);

            //////////////////////////////////////////////////////////////////////
            // TODO: Update the job-deletion logic.
            //
            // In subsequent builds of Workflow Manager (post-10.0), there may be
            // a new API that deletes jobs and handles some of the logic included
            // in this class (ex: checking permissions, deleting versions, etc.).
            // If so, this GP tool should be revised to make use of this
            // simplified interface.
            //
            // Anyone using this tool as a reference, particularly with regards
            // to deleting Workflow Manager jobs, should keep this in mind.
            //////////////////////////////////////////////////////////////////////

            // Delete the requested job
            try
            {
                IJTXJobManager jobManager = this.WmxDatabase.JobManager;
                IJTXJob3       job        = jobManager.GetJob(m_jobToDelete) as IJTXJob3;

                msgs.AddMessage("Deleting job " + m_jobToDelete + " (" + job.Name + ")");
                job.DeleteMXD();
                if (job.VersionExists())
                {
                    if (CurrentUserHasPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_DELETE_VERSION))
                    {
                        try
                        {
                            job.DeleteVersion(null);
                        }
                        catch (System.Runtime.InteropServices.COMException comEx)
                        {
                            if (comEx.ErrorCode == (int)fdoError.FDO_E_SE_VERSION_NOEXIST)
                            {
                                // The "VersionExists" method above can apparently be fooled; if it is, an exception with this
                                // error code is thrown.  In this case, add a warning and continue on.
                                msgs.AddWarning("Version '" + job.VersionName + "' is assigned to job " + job.ID.ToString() + " but could not be found");
                            }
                            else
                            {
                                // If there's a different error, then re-throw it for someone else to deal with
                                throw comEx;
                            }
                        }
                    }
                    else
                    {
                        string username = ESRI.ArcGIS.JTXUI.ConfigurationCache.GetCurrentSystemUser(ESRI.ArcGIS.JTXUI.ConfigurationCache.UseUserDomain);
                        msgs.AddWarning("User '" + username + "' does not have permissions to " +
                                        "delete job versions; version '" + job.VersionName + "' will not be deleted");
                    }
                }
                jobManager.DeleteJob(m_jobToDelete, true);

                // Set the output parameter
                WmauParameterMap  paramMap     = new WmauParameterMap(paramValues);
                IGPParameterEdit3 outParamEdit = paramMap.GetParamEdit(C_PARAM_JOB_DELETED);
                IGPLong           outValue     = new GPLongClass();
                outValue.Value     = m_jobToDelete;
                outParamEdit.Value = outValue as IGPValue;

                msgs.AddMessage(Properties.Resources.MSG_DONE);
            }
            catch (Exception ex)
            {
                WmauError error = new WmauError(WmauErrorCodes.C_DELETE_JOB_VERSION_ERROR);
                msgs.AddError(error.ErrorCodeAsInt, error.Message + "; " + ex.Message);
            }
        }