PxDeleteByWorkFunction.cs
Copy Code
|
|
---|---|
using System; using System.Collections; using System.Text; using System.Xml; using ESRI.ArcGIS.Geodatabase; using Miner.Geodatabase.GeodatabaseManager; using Miner.Geodatabase.GeodatabaseManager.Serialization; using Miner.Process.GeodatabaseManager; using Miner.Process.GeodatabaseManager.ActionHandlers; namespace Miner.DeveloperSamples.GeodatabaseManager { /// <summary> /// Action handler to delete objects based upon their work function. /// </summary> /// <remarks>PxActionHandler is a base type that extends the ActionHandler base type by allowing information /// specific to the Process Framework (i.e., the px node) to be passed into the PxSubExecute method</remarks> public class PxDeleteByWorkFunction : PxActionHandler { #region constants private const string WorkFunction = "WorkFunction"; private const string DesignIdFieldName = "DESIGNID"; private const string GisUnitXPath = "//GISUNIT"; private const string TableNameXPath = "TABLENAME"; private const string OidXPath = "OID"; #endregion #region constructor /// <summary> /// Constructor for the action handler. Sets the name, description and default parameters for the action handler. /// </summary> public PxDeleteByWorkFunction() { this.Name = "SAMPLE: Delete Objects By Work Function"; this.Description = "Deletes objects by Work Function from a design version."; this.DefaultParameters = GetDefaultParameters(); } #endregion #region PxActionHandler overrides /// <summary> /// Determines when this action handler is enabled. This method is used to determine when the action /// handler appears in the list of available action handlers. /// </summary> /// <param name="actionType">Indicates context, whether in the reconcile or reconcile/post sequence.</param> /// <param name="gdbmAction">The particular event to which the action handler might be assigned.</param> /// <param name="versionType">If the context is reconcile, the versionType will be Any; If in /// the posting sequence, versionType distinguishes between Plain Versions, Sessions and Designs.</param> /// <returns>True if enabled, false otherwise.</returns> /// <remarks>For best results, this action handler should be assigned to the BeforePost event for a Design. /// This method enforces that.</remarks> public override bool Enabled(ActionType actionType, Actions gdbmAction, PostVersionType versionType) { bool enabled = false; if (versionType == PostVersionType.Design && actionType == ActionType.Post && gdbmAction == Actions.BeforePost) { enabled = true; } return enabled; } /// <summary> /// Deletes objects according to the configured work functions. /// </summary> /// <param name="actionData">A dictionary object containing information about the version being posted.</param> /// <param name="parameters">For this action handler, the parameters correspond to the work functions /// for the objects to be deleted. Some action handlers do not require parameters. See the /// <see cref="Miner.DeveloperSamples.GeodatabaseManager.LogToReconcileHistory">LogToReconcileHistory</see> /// sample for more information.</param> /// <returns>True if the action handler was executed successfully, false otherwise.</returns> protected override bool PxSubExecute(PxActionData actionData, GdbmParameter[] parameters) { bool success = false; // Ensure the version is being edited. if (!((IWorkspaceEdit)actionData.Version).IsBeingEdited()) { // Log message that the version must be in edit mode for this action handler to execute successfully. // Note that the Log object has been extended to take a service name as the first parameter. Log.Warn(ServiceConfiguration.Name, string.Format("Must be editing to execute action handler {0}.", Name)); } else { string versionName = actionData.VersionName; try { // Determine the deletable work function values. if (parameters == null) { //Log exception for null parameters Log.Warn(ServiceConfiguration.Name, string.Format("Could not find the deletable work function values needed by {0}.", Name)); } else { ArrayList workFunctionValues = ParseConfiguredWorkFunctionValues(parameters); if (workFunctionValues.Count == 0) { // Log exception that the configured work function values could not be parsed. Log.Warn(ServiceConfiguration.Name, string.Format("Unable to read work function parameter values needed by {0}.", Name)); } else { // Get the design XML. XmlDocument doc = actionData.GetDesignXml(); if (doc == null) { // Log error that the attempt to get the design xml failed Log.Warn(ServiceConfiguration.Name, string.Format("Unable to get design xml for action handler {0}.", Name)); } else { // Delete any objects as appropriate. success = DeleteObjectsByWorkFunction(doc, actionData.Version, workFunctionValues, actionData.PxNode.Id); // Log an informational message about the success or failure of the previous call if (success) { Log.Info(ServiceConfiguration.Name, string.Format("Deleted objects by Work Function for version {0}.", versionName)); } else { Log.Info(ServiceConfiguration.Name, string.Format("Unable to delete objects by Work Function for version {0}.", versionName)); } } } } } catch (Exception e) { // Log exception that the action handler failed Log.Error(ServiceConfiguration.Name, string.Format("Error deleting objects by Work Function from version {0}: {1).", versionName, e.Message), e); } } return success; } #endregion #region private methods /// <summary> /// Sets default parameters for this action handler. /// </summary> /// <returns>An array of default parameters.</returns> /// <remarks>See the PROCESS.MM_WMS_WORK_FUNCTION table for the particular values that would make /// sense for your implementation. It's fine if the default values are not an exact match for the /// implementation. Ultimately, whatever has been configured is what will be honored when the action /// handler executes.</remarks> private GdbmParameter[] GetDefaultParameters() { GdbmParameter[] parameters = new GdbmParameter[5]; try { // Add default Work Function values to be deleted, such as Remove, Retire, Abandon, Scrap, etc. int[] workFunctionValues = new int[5] { 2, 4, 8, 32, 64 }; int i = 0; foreach (int workFunctionValue in workFunctionValues) { GdbmParameter parameter = new GdbmParameter(); parameter.Name = WorkFunction; parameter.Value = workFunctionValue.ToString(); parameters[i] = parameter; i++; } } catch (Exception e) { // Log exception that a problem occurred getting the default parameters // Note that the Log object has been extended to take a service name as the first parameter. Log.Error(ServiceConfiguration.Name, string.Format("Error getting default parameters for Delete By Work Function action handler: {0}.", e.Message), e); parameters = null; } return parameters; } /// <summary> /// Populates an array list of deletable work function values from the configured parameters. /// </summary> /// <param name="parameters">Parameters set from configuration.</param> /// <returns>Array list of deletable work function values.</returns> private ArrayList ParseConfiguredWorkFunctionValues(GdbmParameter[] parameters) { ArrayList workFunctionValues = new ArrayList(); foreach (GdbmParameter parameter in parameters) { if (parameter.Name.Equals(WorkFunction, StringComparison.OrdinalIgnoreCase)) { int workFunction = Convert.ToInt32(parameter.Value); if (!workFunctionValues.Contains(workFunction)) { workFunctionValues.Add(workFunction); } } } return workFunctionValues; } /// <summary> /// Deletes objects from any modified classes in the specified version using WorkFunction and DesignID values. /// </summary> /// <param name="version">The version to be edited.</param> /// <param name="workFunctionValues">List of work function values to be deleted.</param> /// <param name="designId">The ID of the design, used to restrict object deletions.</param> /// <returns>Boolean indicating if objects were deleted by Work Function successfully.</returns> private bool DeleteObjectsByWorkFunction(XmlDocument designXML, IVersion version, ArrayList workFunctionValues, int designId) { bool success = true; try { string versionName = version.VersionName; IFeatureWorkspace featWorkspace = (IFeatureWorkspace)version; string whereClause = GetWhereClause(workFunctionValues, designId); ArrayList modifiedClasses = GetModifiedDesignTables(designXML); foreach (string modifiedClassName in modifiedClasses) { ITable table = null; try { table = featWorkspace.OpenTable(modifiedClassName); if (ValidateTable(table)) { IQueryFilter qFilter = new QueryFilterClass(); qFilter.WhereClause = whereClause; ((IWorkspaceEdit)version).StartEditOperation(); table.DeleteSearchedRows(qFilter); ((IWorkspaceEdit)version).StopEditOperation(); // Optionally, log informational message that rows were deleted from the modified table // Note that the Log object has been extended to take a service name as the first parameter. Log.Debug(ServiceConfiguration.Name, string.Format("Deleted rows from {0} where {1}." , modifiedClassName, whereClause)); } } catch (Exception e) { // Log exception that delete objects by work function failed Log.Error(ServiceConfiguration.Name, string.Format("Error deleting objects by Work Function from class {0} in version {1}: {2}.", modifiedClassName, versionName, e.Message), e); success = false; break; } } } catch (Exception e) { // Log exception that delete by work function setup failed Log.Error(ServiceConfiguration.Name, string.Format("Error deleting objects by Work Function: {0}.", e.Message), e); success = false; } return success; } /// <summary> /// Constructs the where clause to use from the list of work function values. /// </summary> /// <param name="workFunctionValues">List of the work function values to delete.</param> /// <returns>Where clause string.</returns> private string GetWhereClause(ArrayList workFunctionValues, int designId) { string startOfWhere = string.Format("{0} = '{1}' AND ({2} = ", DesignIdFieldName, designId, WorkFunction); StringBuilder builder = new StringBuilder(startOfWhere); int counter = 0; foreach (int wf in workFunctionValues) { if (counter == 0) { builder.Append(wf.ToString()); } else { builder.Append(" OR "); builder.Append(WorkFunction); builder.Append(" = "); builder.Append(wf.ToString()); } counter++; } builder.Append(")"); return builder.ToString(); } /// <summary> /// Parses the design XML and builds a list of any table names associated with GUs in the design. /// </summary> /// <param name="designXml">The design XML.</param> /// <returns>Array list of the GU table names.</returns> private ArrayList GetModifiedDesignTables(XmlDocument designXml) { // Build a list of all table names associated with GUs in the design XML. ArrayList designTables = new ArrayList(); XmlNodeList nodeList = designXml.SelectNodes(GisUnitXPath); foreach (XmlNode node in nodeList) { string tableName = string.Empty; int oid = 0; XmlNode dataNode = node.SelectSingleNode(TableNameXPath); if (dataNode != null) { tableName = dataNode.InnerText; } dataNode = node.SelectSingleNode(OidXPath); if (dataNode != null) { oid = Convert.ToInt32(dataNode.InnerText); } if (tableName != string.Empty & oid != 0) { // Add to the array list. if (!designTables.Contains(tableName)) designTables.Add(tableName); } } return designTables; } /// <summary> /// Validates that the specified table has the necessary fields used in the deletion process. /// </summary> /// <param name="table">The table to be validated.</param> /// <returns>Boolean indicating if the table is valid to process.</returns> private bool ValidateTable(ITable table) { bool valid = false; if ((table.Fields.FindField(DesignIdFieldName) != -1) && (table.Fields.FindField(WorkFunction) != -1)) valid = true; return valid; } #endregion } } |