/// <summary> /// Builds a domain of the priority strings in the system /// </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 BuildPriorityDomain(IJTXDatabase3 wmxDb) { IGPCodedValueDomain domain = new GPCodedValueDomainClass(); // Sort the types first IJTXPrioritySet allValues = wmxDb.ConfigurationManager.Priorities; SortedList <int, string> sortedValues = new SortedList <int, string>(); for (int i = 0; i < allValues.Count; i++) { IJTXPriority temp = allValues.get_Item(i); sortedValues.Add(temp.Value, temp.Name); } // Since the highest priority elements are those with the largest number, // reverse the order of the list so that these priorities show up first IEnumerable <string> valueList = sortedValues.Values.Reverse(); // Add the sorted types to the domain foreach (string value in valueList) { IGPValue tempGpVal = new GPStringClass(); tempGpVal.SetAsText(value); domain.AddCode(tempGpVal, value); } return(domain as IGPDomain); }
/// <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); }
/// <summary> /// Builds a domain consisting of the names of the system groups to which the current /// user can assign a job. /// </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 BuildAssignableGroupsDomain(IJTXDatabase3 wmxDb) { return(WmauGpDomainBuilder.BuildAssignableGroupsDomain( wmxDb, ESRI.ArcGIS.JTXUI.ConfigurationCache.GetCurrentSystemUser(ESRI.ArcGIS.JTXUI.ConfigurationCache.UseUserDomain), null)); }
/// <summary> /// Builds a domain consisting of all the usernames in the system /// </summary> /// <param name="wmxDb">A reference to the active Workflow Manager database</param> /// <param name="extraValues">An array of string values to be added to the list</param> /// <returns>A coded value domain as an IGPDomain</returns> public static IGPDomain BuildUsersDomain(IJTXDatabase3 wmxDb, string[] extraValues) { IGPCodedValueDomain domain = new GPCodedValueDomainClass(); // Sort the types first IJTXUserSet allValues = wmxDb.ConfigurationManager.Users; SortedList <string, string> sortedValues = new SortedList <string, string>(); for (int i = 0; i < allValues.Count; i++) { sortedValues.Add(allValues.get_Item(i).UserName, null); } // Add the extra values, if any if (extraValues != null) { foreach (string s in extraValues) { sortedValues.Add(s, null); } } // Add the sorted types to the domain foreach (string value in sortedValues.Keys) { IGPValue tempGpVal = new GPStringClass(); tempGpVal.SetAsText(value); domain.AddCode(tempGpVal, value); } return(domain as IGPDomain); }
/// <summary> /// Builds a domain containing the usernames of the users to whom the current /// user can assign jobs. /// </summary> /// <param name="wmxDb">A reference to the active Workflow Manager database</param> /// <param name="extraValues">An array of string values to be added to the list</param> /// <returns>A coded value domain of strings</returns> public static IGPDomain BuildAssignableUsersDomain(IJTXDatabase3 wmxDb, string[] extraValues) { return(Common.WmauGpDomainBuilder.BuildAssignableUsersDomain( wmxDb, ESRI.ArcGIS.JTXUI.ConfigurationCache.GetCurrentSystemUser(ESRI.ArcGIS.JTXUI.ConfigurationCache.UseUserDomain), extraValues)); }
/// <summary> /// Find those Task Assistant workbooks in the database that are not being used by /// any step that launches ArcMap /// </summary> /// <returns>The total number of orphaned items found</returns> private int UpdateOrphanedTaWorkbooks() { SortedList <string, string> unusedItems = new SortedList <string, string>(); IJTXDatabase3 wmxDb = this.WmxDatabase; IJTXConfiguration3 configMgr = wmxDb.ConfigurationManager as IJTXConfiguration3; IJTXTaskAssistantWorkflowRecordSet allItems = configMgr.TaskAssistantWorkflowRecords; // First check to see if there are even any TA workbooks in the database if (allItems.Count > 0) { Dictionary <string, string> usedTypes = new Dictionary <string, string>(); // Search all the step types for Task Assistant workbooks currently in use IJTXStepTypeSet allStepTypes = wmxDb.ConfigurationManager.StepTypes; for (int i = 0; i < allStepTypes.Count; i++) { IJTXStepType2 stepType = allStepTypes.get_Item(i) as IJTXStepType2; // Skip over unused step types if (m_unusedStepTypes.Keys.Contains(stepType.ID)) { continue; } // Examine the remaining step types for (int j = 0; j < stepType.Arguments.Length; j++) { string stepArg = stepType.Arguments[j].ToString(); if (stepArg.StartsWith(C_WORKBOOK_FLAG)) { string suffix = stepArg.Substring(C_WORKBOOK_FLAG.Length); suffix = suffix.Trim(new char[] { '"' }); usedTypes[suffix] = null; } } } // Loop over all the Task Assistant workbooks, looking for anything // that we didn't identify as "in use" for (int i = 0; i < allItems.Count; i++) { IJTXTaskAssistantWorkflowRecord item = allItems.get_Item(i); if (!usedTypes.ContainsKey(item.Alias)) { m_unusedTaWorkbooks[item.Alias] = null; } } } return(m_unusedTaWorkbooks.Count); }
/// <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> /// Find those step types in the database that are not being used by any workflow. /// </summary> /// <returns>The total number of orphaned items found</returns> private int UpdateOrphanedStepTypes() { Dictionary <int, int> usedStepTypes = new Dictionary <int, int>(); IJTXDatabase3 wmxDb = this.WmxDatabase; IJTXConfiguration3 configMgr = wmxDb.ConfigurationManager as IJTXConfiguration3; IJTXWorkflowSet workflows = configMgr.Workflows; // Iterate through each workflow, building up the list of used steps 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) { int stepTypeId = workflowCfg.GetStep(stepId).StepTypeID; usedStepTypes[stepTypeId] = stepTypeId; } } // Get the complete list of step types in the database IJTXStepTypeSet allStepTypeObjs = configMgr.StepTypes; // Loop over all of the step types. For anything whose step type 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 (usedStepTypes.Count != allStepTypeObjs.Count) { for (int i = 0; i < allStepTypeObjs.Count; i++) { IJTXStepType2 stepType = allStepTypeObjs.get_Item(i) as IJTXStepType2; int stepTypeId = stepType.ID; if (!usedStepTypes.ContainsKey(stepTypeId)) { m_unusedStepTypes[stepTypeId] = stepType.Name; } } } return(m_unusedStepTypes.Count); }
/// <summary> /// Builds a domain consisting of the IDs for every job in the database. /// </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 BuildJobIdDomain(IJTXDatabase3 wmxDb) { IGPCodedValueDomain domain = new GPCodedValueDomainClass(); int[] allJobs = wmxDb.JobManager.GetAllJobIDs(); System.Array.Sort(allJobs); foreach (int job in allJobs) { IGPValue tempGpVal = new GPLongClass(); tempGpVal.SetAsText(job.ToString()); domain.AddCode(tempGpVal, job.ToString()); } return(domain as IGPDomain); }
/// <summary> /// Builds a domain of the version names for a workspace /// </summary> /// <param name="wmxDb">A reference to the active Workflow Manager database</param> /// <param name="workspaceName">The human-readable name of the workspace whose versions to look up</param> /// <param name="extraValues">An array of string values to be added to the list</param> /// <returns>A coded value domain of strings</returns> public static IGPDomain BuildVersionsDomain(IJTXDatabase3 wmxDb, string workspaceName, string[] extraValues) { IGPCodedValueDomain domain = new GPCodedValueDomainClass(); try { // Get all of the public versions connected to this workspace string workspaceId = Common.WmauHelperFunctions.LookupWorkspaceId(wmxDb, workspaceName); IWorkspace workspace = wmxDb.GetDataWorkspace(workspaceId, null); IVersionedWorkspace3 versionedWorkspace = workspace as IVersionedWorkspace3; IEnumVersionInfo allValues = versionedWorkspace.Versions; // Sort the types first SortedList <string, string> sortedValues = new SortedList <string, string>(); IVersionInfo version; while ((version = allValues.Next()) != null) { sortedValues.Add(version.VersionName, null); } // Add the extra values, if any if (extraValues != null) { foreach (string s in extraValues) { sortedValues.Add(s, null); } } // Add the sorted types to the domain foreach (string value in sortedValues.Keys) { IGPValue tempGpVal = new GPStringClass(); tempGpVal.SetAsText(value); domain.AddCode(tempGpVal, value); } } catch (System.Runtime.InteropServices.COMException comEx) { // If we run into an exception, send word up the chain throw new WmauException(WmauErrorCodes.C_VERSION_LOOKUP_ERROR, comEx); } return(domain as IGPDomain); }
/// <summary> /// Builds a domain consisting of the available job queries in the system. /// </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 BuildJobQueryDomain(IJTXDatabase3 wmxDb) { IGPCodedValueDomain domain = new GPCodedValueDomainClass(); IJTXConfiguration3 configMgr = wmxDb.ConfigurationManager as IJTXConfiguration3; IJTXJobQueryContainer publicQueriesContainer = configMgr.GetPublicQueryContainer(); // Sort the queries first SortedList <string, string> sortedValues = new SortedList <string, string>(); WmauGpDomainBuilder.AddQueriesFromContainer(publicQueriesContainer, string.Empty, sortedValues); // Add the sorted types to the domain foreach (string value in sortedValues.Keys) { domain.AddStringCode(value, value); } return(domain as IGPDomain); }
/// <summary> /// Find those workflows in the database that are not being used by any job type. /// </summary> /// <returns>The total number of orphaned items found</returns> private int UpdateOrphanedWorkflows() { Dictionary <int, int> usedWorkflows = new Dictionary <int, int>(); IJTXDatabase3 wmxDb = this.WmxDatabase; IJTXConfiguration3 configMgr = wmxDb.ConfigurationManager as IJTXConfiguration3; IJTXJobTypeSet jobTypes = configMgr.JobTypes; // Iterate through each item in the set, building up the list of used types for (int i = 0; i < jobTypes.Count; i++) { // TODO: Do not consider items that we know are not in use IJTXJobType3 type = jobTypes.get_Item(i) as IJTXJobType3; // job type don't always need to have a workflow if (type.Workflow != null) { usedWorkflows[type.Workflow.ID] = type.Workflow.ID; } } // Get the complete list of this type of object in the database IJTXWorkflowSet workflows = configMgr.Workflows; // Loop through the complete list of this object type. If any of the IDs // are not in the "used" list, add that object to the "unused" list. // If all of the items are used, don't bother trying to add to the // unused list. if (usedWorkflows.Count != workflows.Count) { for (int i = 0; i < workflows.Count; i++) { IJTXWorkflow workflow = workflows.get_Item(i) as IJTXWorkflow; if (!usedWorkflows.ContainsKey(workflow.ID)) { m_unusedWorkflows[workflow.ID] = workflow.Name; } } } return(m_unusedWorkflows.Count); }
/// <summary> /// Builds a domain containing the names of all the task assistant /// workbooks embedded in the database /// </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 BuildTamWorkbookDomain(IJTXDatabase3 wmxDb) { IGPCodedValueDomain tamNames = new GPCodedValueDomainClass(); SortedList <string, string> sortedTamNames = new SortedList <string, string>(); IJTXConfiguration3 configMgr = wmxDb.ConfigurationManager as IJTXConfiguration3; IJTXTaskAssistantWorkflowRecordSet tamWorkbooks = configMgr.TaskAssistantWorkflowRecords; for (int i = 0; i < tamWorkbooks.Count; i++) { IJTXTaskAssistantWorkflowRecord tamWorkbook = tamWorkbooks.get_Item(i); sortedTamNames.Add(tamWorkbook.Alias, null); } foreach (string tamName in sortedTamNames.Keys) { tamNames.AddStringCode(tamName, tamName); } return(tamNames as IGPDomain); }
/// <summary> /// Builds a domain containing the names of all the map documents embedded /// in the database /// </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 BuildMapDocumentDomain(IJTXDatabase3 wmxDb) { IGPCodedValueDomain mxdNames = new GPCodedValueDomainClass(); SortedList <string, string> mapDocumentNames = new SortedList <string, string>(); IJTXConfiguration3 configMgr = wmxDb.ConfigurationManager as IJTXConfiguration3; IJTXMapSet maps = configMgr.JTXMaps; for (int i = 0; i < maps.Count; i++) { IJTXMap map = maps.get_Item(i); mapDocumentNames.Add(map.Name, null); } foreach (string mapDocName in mapDocumentNames.Keys) { mxdNames.AddStringCode(mapDocName, mapDocName); } return(mxdNames as IGPDomain); }
/// <summary> /// Builds a domain of the data workspace names in the system /// </summary> /// <param name="wmxDb">A reference to the active Workflow Manager database</param> /// <param name="extraValues">An array of string values to be added to the list</param> /// <returns>A coded value domain as an IGPDomain</returns> public static IGPDomain BuildWorkspaceDomain(IJTXDatabase3 wmxDb, string[] extraValues) { IGPCodedValueDomain domain = new GPCodedValueDomainClass(); SortedList <string, string> sortedValues = new SortedList <string, string>(); // Workflow Manager intentionally caches the data workspaces in the system. To ensure // that we have the most current list of data workspaces, invalidate this cache // before attempting to retrieve the list from the system. wmxDb.InvalidateDataWorkspaceNames(); // Sort the types first IJTXDataWorkspaceNameSet allValues = wmxDb.GetDataWorkspaceNames(null); for (int i = 0; i < allValues.Count; i++) { IJTXDataWorkspaceName ws = allValues.get_Item(i); sortedValues.Add(ws.Name, null); } // Add the extra values, if any if (extraValues != null) { foreach (string s in extraValues) { sortedValues.Add(s, null); } } // Add the sorted types to the domain foreach (string value in sortedValues.Keys) { IGPValue tempGpVal = new GPStringClass(); tempGpVal.SetAsText(value); domain.AddCode(tempGpVal, value); } return(domain as IGPDomain); }
/// <summary> /// Builds a domain from the names of the job types in the system /// </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 BuildJobTypeDomain(IJTXDatabase3 wmxDb) { IGPCodedValueDomain domain = new GPCodedValueDomainClass(); // Sort the types first IJTXJobTypeSet allValues = wmxDb.ConfigurationManager.JobTypes; SortedList <string, string> sortedValues = new SortedList <string, string>(); for (int i = 0; i < allValues.Count; i++) { sortedValues.Add(allValues.get_Item(i).Name, null); } // Add the sorted types to the domain foreach (string value in sortedValues.Keys) { IGPValue tempGpVal = new GPStringClass(); tempGpVal.SetAsText(value); domain.AddCode(tempGpVal, value); } return(domain as IGPDomain); }
/// <summary> /// Set up a coded value domain containing the names of all the spatial notifications /// (a.k.a. "change rules") currently in the database. /// </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 BuildChangeRulesDomain(IJTXDatabase3 wmxDb) { IGPCodedValueDomain domain = new GPCodedValueDomainClass(); SortedList <string, string> sortedValues = new SortedList <string, string>(); IJTXChangeRuleSet allChangeRules = wmxDb.SpatialNotificationManager.ChangeRules; // Sort the types first for (int i = 0; i < allChangeRules.Count; i++) { IJTXChangeRule tempRule = allChangeRules.get_Item(i); sortedValues.Add(tempRule.Name, null); } // Add the sorted types to the domain foreach (string value in sortedValues.Keys) { IGPValue tempGpVal = new GPStringClass(); tempGpVal.SetAsText(value); domain.AddCode(tempGpVal, value); } return(domain as IGPDomain); }
/// <summary> /// Given the human-readable name of a data workspace, this function returns the /// unique ID string used by Workflow Manager to identify this workspace connection. /// </summary> /// <param name="wmxDb">A reference to the active Workflow Manager database</param> /// <param name="wsName"> /// The name of the data workspace whose ID is to be retrieved /// </param> /// <returns> /// The ID string for the specified data workspace; returns the empty string if /// no matching workspace can be found. /// </returns> public static string LookupWorkspaceId(IJTXDatabase3 wmxDb, string wsName) { string id = string.Empty; // Workflow Manager intentionally caches the data workspaces in the system. To ensure // that we have the most current list of data workspaces, invalidate this cache // before attempting to retrieve the list from the system. wmxDb.InvalidateDataWorkspaceNames(); // Get the workspace list from the database IJTXDataWorkspaceNameSet allValues = wmxDb.GetDataWorkspaceNames(null); // Search for the workspace ID with the matching name for (int i = 0; i < allValues.Count; i++) { if (allValues.get_Item(i).Name.Equals(wsName)) { id = allValues.get_Item(i).DatabaseID; break; } } return(id); }
/// <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> /// Builds a domain of the data workspace names in the system /// </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 BuildWorkspaceDomain(IJTXDatabase3 wmxDb) { return(BuildWorkspaceDomain(wmxDb, null)); }
/// <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 map documents embedded in the database that are not being /// referenced in any way /// </summary> /// <returns>The total number of orphaned items found</returns> private int UpdateOrphanedMapDocuments() { SortedList <string, int> unusedItems = new SortedList <string, int>(); IJTXDatabase3 wmxDb = this.WmxDatabase; IJTXConfiguration3 configMgr = wmxDb.ConfigurationManager as IJTXConfiguration3; IJTXConfigurationEdit2 configEdit = wmxDb.ConfigurationManager as IJTXConfigurationEdit2; IJTXMapSet allMaps = configMgr.JTXMaps; Dictionary <string, int> allMapNames = new Dictionary <string, int>(); for (int i = 0; i < allMaps.Count; i++) { IJTXMap map = allMaps.get_Item(i); allMapNames[map.Name] = map.ID; } Dictionary <string, int> usedItems = new Dictionary <string, int>(); // Find the map types that are associated with job types IJTXJobTypeSet allJobTypes = configMgr.JobTypes; for (int i = 0; i < allJobTypes.Count; i++) { // TODO: Skip orphaned job types IJTXJobType3 jobType = allJobTypes.get_Item(i) as IJTXJobType3; if (jobType.AOIMap != null) { usedItems[jobType.AOIMap.Name] = jobType.AOIMap.ID; } if (jobType.JobMap != null) { usedItems[jobType.JobMap.Name] = jobType.JobMap.ID; } } // If necessary, find the map types launched by custom steps. Look for // the "/mxd:" argument as an identifier. IJTXStepTypeSet allStepTypes = wmxDb.ConfigurationManager.StepTypes; for (int i = 0; i < allStepTypes.Count; i++) { IJTXStepType2 stepType = allStepTypes.get_Item(i) as IJTXStepType2; // Skip orphaned step types if (m_unusedStepTypes.Keys.Contains(stepType.ID)) { continue; } for (int j = 0; j < stepType.Arguments.Length; j++) { string stepArg = stepType.Arguments[j].ToString(); if (stepArg.StartsWith(C_MAP_DOC_FLAG)) { string suffix = stepArg.Substring(C_MAP_DOC_FLAG.Length); suffix = suffix.Trim(new char[] { '"' }); if (allMapNames.Keys.Contains(suffix)) { usedItems[suffix] = allMapNames[suffix]; } } } } // Add in the map document that's used as the template map document // (if one exists) IJTXConfigurationProperties configProps = this.WmxDatabase.ConfigurationManager as IJTXConfigurationProperties; string mapIdStr = configProps.GetProperty(Constants.JTX_PROPERTY_MAPVIEW_MAP_GUID); if (mapIdStr != null && !mapIdStr.Equals(string.Empty)) { for (int i = 0; i < allMaps.Count; i++) { IJTXMap tempMap = allMaps.get_Item(i); IJTXIdentifier tempMapId = tempMap as IJTXIdentifier; if (tempMapId.GUID.Equals(mapIdStr)) { usedItems[tempMap.Name] = tempMap.ID; break; } } } // Loop over all the map documents in the DB, looking for anything // that we didn't identify as "in use" foreach (string name in allMapNames.Keys) { if (!usedItems.ContainsKey(name)) { m_unusedMapDocs[name] = allMapNames[name]; } } return(m_unusedMapDocs.Count); }
/// <summary> /// Builds a domain consisting of all of the usernames in the system /// </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 BuildUsersDomain(IJTXDatabase3 wmxDb) { return(WmauGpDomainBuilder.BuildUsersDomain(wmxDb, null)); }
/// <summary> /// Helper function to check to see if a Workflow Manager database can be /// determined/set. (Considers any manually specified databases first; if /// none were specified, attempts to use the default Workflow Manager /// database.) /// </summary> /// <returns></returns> protected bool IsWorkflowManagerDatabaseSet() { bool isDatabaseSet = false; try { // Get a handle to the database manager, if need be if (m_wmxDbMgr == null) { m_wmxDbMgr = new JTXDatabaseManagerClass(); } // Determine the default Workflow Manager database if none has been specified if (string.IsNullOrEmpty(m_wmxDbAlias)) { // WORKAROUND: Query the environment variable directly for the alias // of the default workflow manager DB. IJTXDatabaseManager.GetActiveDatabase() // is a fairly expensive call, so this provides a way to avoid making // it unnecessarily. m_wmxDbAlias = System.Environment.GetEnvironmentVariable(C_ENV_VAR_DEFAULT_WMX_DB); if (m_wmxDbAlias == null) { m_wmxDbAlias = string.Empty; } } // If we don't already have a database object for this database, get one // and cache it away if (!m_wmxDbInfo.ContainsKey(m_wmxDbAlias)) { IJTXDatabase3 tempDb = m_wmxDbMgr.GetDatabase(m_wmxDbAlias) as IJTXDatabase3; // If this is the first time we've retrieved the information for the // default database, store it away if (!m_wmxDbInfo.ContainsKey(m_wmxDbAlias) && tempDb != null) { m_wmxDbInfo[m_wmxDbAlias] = tempDb; ESRI.ArcGIS.JTXUI.ConfigurationCache.InvalidateCache(); ESRI.ArcGIS.JTXUI.ConfigurationCache.InitializeCache(tempDb); } } // At this point, the alias should be set, and the wmx DB connection should // be stored in the table. Do one last set of sanity checks before setting // the return value. if (m_wmxDbInfo.ContainsKey(m_wmxDbAlias) && m_wmxDbInfo[m_wmxDbAlias] != null) { isDatabaseSet = true; } } catch (System.Runtime.InteropServices.COMException comEx) { m_wmxDbInfo.Remove(m_wmxDbAlias); m_wmxDbMgr = null; m_wmxDbAlias = string.Empty; int errorCode; // Check for license-related problems if (comEx.ErrorCode == (int)ESRI.ArcGIS.JTX.jtxCoreError.E_JTXCORE_ERR_LICENSE_NOT_CHECKED_OUT || comEx.ErrorCode == (int)ESRI.ArcGIS.JTX.jtxCoreError.E_JTXCORE_ERR_LICENSE_MISSING_PRODUCT || comEx.ErrorCode == (int)ESRI.ArcGIS.JTX.jtxCoreError.E_JTXCORE_ERR_LICENSE_INCOMPATIBLE_PRODUCT) { throw new WmauException(WmauErrorCodes.C_LICENSE_RELATED_ERROR, comEx); } unchecked { errorCode = (int)0x80040AF4; } if (comEx.ErrorCode != errorCode) { throw comEx; } } return(isDatabaseSet); }
/// <summary> /// Helper function to send a notification /// </summary> /// <param name="notificationName">The type (name) of the notification to send</param> /// <param name="wmxDb">A reference to the active Workflow Manager database</param> /// <param name="job">The job for which to send the notification</param> public static void SendNotification(string notificationName, IJTXDatabase3 wmxDb, IJTXJob job) { ESRI.ArcGIS.JTX.Utilities.JTXUtilities.SendNotification(notificationName, wmxDb, job, null); }
/// <summary> /// Builds a domain consisting of the names of the system groups to which a /// user can assign a job. /// </summary> /// <param name="wmxDb">A reference to the active Workflow Manager database</param> /// <param name="username">The name of the user to be tested</param> /// <param name="extraValues">An array of string values to be added to the list</param> /// <returns>A coded value domain as an IGPDomain</returns> public static IGPDomain BuildAssignableGroupsDomain(IJTXDatabase3 wmxDb, string username, string[] extraValues) { IGPCodedValueDomain domain = new GPCodedValueDomainClass(); string[] eligibleGroups = null; // Only proceed if the user exists in the Workflow Manager database IJTXUser3 user = wmxDb.ConfigurationManager.GetUser(username) as IJTXUser3; if (user == null) { return(domain as IGPDomain); } // The groups to which this user can assign jobs are based on several // different permissions. Check these permissions, in order from least // restrictive to most restrictive. if (user.HasNamedPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_ASSIGN_ANY_JOB)) { int numGroups = wmxDb.ConfigurationManager.UserGroups.Count; eligibleGroups = new string[numGroups]; for (int i = 0; i < numGroups; i++) { eligibleGroups[i] = wmxDb.ConfigurationManager.UserGroups.get_Item(i).Name; } } else if (user.HasNamedPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_GROUP_JOB_ASSIGN)) { eligibleGroups = new string[user.Groups.Count]; for (int i = 0; i < user.Groups.Count; i++) { eligibleGroups[i] = user.Groups.get_Item(i).Name; } } else { eligibleGroups = new string[0]; } // Sort the types first SortedList <string, string> sortedValues = new SortedList <string, string>(); for (int i = 0; i < eligibleGroups.Length; i++) { sortedValues.Add(eligibleGroups[i], null); } // Add the extra values, if any if (extraValues != null) { foreach (string s in extraValues) { sortedValues.Add(s, null); } } // Add the sorted types to the domain foreach (string value in sortedValues.Keys) { IGPValue tempGpVal = new GPStringClass(); tempGpVal.SetAsText(value); domain.AddCode(tempGpVal, value); } return(domain as IGPDomain); }
/// <summary> /// Builds a domain consisting of the Workflow Manager privileges /// </summary> /// <returns>A coded value domain of strings</returns> public static IGPDomain BuildPrivilegesDomain(IJTXDatabase3 wmxDb) { return(WmauGpDomainBuilder.BuildPrivilegesDomain(wmxDb)); }
/// <summary> /// Builds a domain consisting of the names of the system groups to which a /// user can assign a job. /// </summary> /// <param name="wmxDb">A reference to the active Workflow Manager database</param> /// <param name="username">The name of the user to be tested</param> /// <returns>A coded value domain as an IGPDomain</returns> public static IGPDomain BuildAssignableGroupsDomain(IJTXDatabase3 wmxDb, string username) { return(WmauGpDomainBuilder.BuildAssignableGroupsDomain(wmxDb, username, null)); }
/// <summary> /// Builds a domain containing the usernames of the users to whom a /// user can assign jobs. /// </summary> /// <param name="wmxDb">A reference to the active Workflow Manager database</param> /// <param name="username">The name of the user to be tested</param> /// <param name="extraValues">An array of string values to be added to the list</param> /// <returns>A coded value domain of strings</returns> public static IGPDomain BuildAssignableUsersDomain(IJTXDatabase3 wmxDb, string username, string[] extraValues) { IGPCodedValueDomain domain = null; // Only proceed if the user exists in the Workflow Manager database IJTXUser3 user = wmxDb.ConfigurationManager.GetUser(username) as IJTXUser3; if (user == null) { return(domain as IGPDomain); } // Case 1: If the user can assign the job to anyone, then // just use the "all users" list if (user.HasNamedPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_ASSIGN_ANY_JOB)) { domain = Common.WmauGpDomainBuilder.BuildUsersDomain(wmxDb, extraValues) as IGPCodedValueDomain; } else { domain = new GPCodedValueDomainClass(); string[] eligibleUsers = null; // Case 2: The user can assign jobs to anyone within any of their groups if (user.HasNamedPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_GROUP_JOB_ASSIGN)) { HashSet <string> usernames = new HashSet <string>(); IJTXUserGroupSet groups = user.Groups; for (int i = 0; i < groups.Count; i++) { IJTXUserGroup group = groups.get_Item(i); for (int j = 0; j < group.Users.Count; j++) { usernames.Add(group.Users.get_Item(j).UserName); } } eligibleUsers = usernames.ToArray(); } // Case 3: The user can assign jobs to themselves else if (user.HasNamedPrivilege(ESRI.ArcGIS.JTX.Utilities.Constants.PRIV_INDIVIDUAL_JOB_ASSIGN)) { eligibleUsers = new string[] { username }; } // Case 4: The user can't assign jobs to anyone else { eligibleUsers = new string[0]; } // Sort the types first SortedList <string, string> sortedValues = new SortedList <string, string>(); for (int i = 0; i < eligibleUsers.Length; i++) { sortedValues.Add(eligibleUsers[i], null); } // Add the extra values, if any if (extraValues != null) { foreach (string s in extraValues) { sortedValues.Add(s, null); } } // Add the sorted types to the domain foreach (string value in sortedValues.Keys) { IGPValue tempGpVal = new GPStringClass(); tempGpVal.SetAsText(value); domain.AddCode(tempGpVal, value); } } return(domain as IGPDomain); }