Custom Java Geoprocessing Tool - Delete Features
arcgissamples\geoprocessing\customtool\DeleteFeatures.java
/* Copyright 2010 ESRI
* 
* All rights reserved under the copyright laws of the United States
* and applicable international laws, treaties, and conventions.
* 
* You may freely redistribute and use this sample code, with or
* without modification, provided you include the original copyright
* notice and use restrictions.
* 
* See the use restrictions.
* 
*/
package arcgissamples.geoprocessing.customtool;

import java.io.IOException;

import com.esri.arcgis.datasourcesfile.*;
import com.esri.arcgis.geodatabase.*;
import com.esri.arcgis.geoprocessing.*;
import com.esri.arcgis.interop.*;
import com.esri.arcgis.system.*;

public class DeleteFeatures extends BaseGeoprocessingTool {
  private String toolName = "DeleteFeatures";
  private String displayName = "Java DeleteFeatures Tool";
  private String metadataFileName = toolName + ".xml";

  /**
   * Empty Constructor
   */
  public DeleteFeatures() {
  }

  /**
   * Returns the name (string) of the tool. Should be unique. Used by the GP
   * framework. This name appears when executing the tool at the command line or
   * in scripting. This name should be unique to each toolbox and must not
   * contain spaces.
   */
  public String getName() throws IOException, AutomationException {
    return toolName;
  }

  /**
   * Returns Display Name (string) of the tool, as seen in ArcToolbox.
   */
  public String getDisplayName() throws IOException, AutomationException {
    return displayName;
  }

  /**
   * Returns the full name (IName) of the tool
   */
  public IName getFullName() throws IOException, AutomationException {
    return (IName) new DFFunctionFactory().getFunctionName(toolName);
  }

  /**
   * Returns an array of parameters. This is where the tool's input and output
   * parameters are defined. This property returns an IArray of parameter
   * objects (IGPParameter). These objects define the characteristics of the
   * input and output parameters.
   */
  public IArray getParameterInfo() throws IOException, AutomationException {
    IArray parameters = new Array();

    // a composite data type for input param, so that fc, layer file and map
    // layer can be used as input
    GPCompositeDataType compositeDataType = new GPCompositeDataType();
    compositeDataType.addDataType(new GPFeatureLayerType());
    compositeDataType.addDataType(new DEFeatureClassType());
    compositeDataType.addDataType(new GPLayerType());
    compositeDataType.addDataType(new DELayerType());
    compositeDataType.addDataType(new GPFeatureRecordSetLayerType());

    // Input Features - the fc/layer from which features will be deleted
    GPParameter inFeaturesParameter1 = new GPParameter();
    inFeaturesParameter1.setDataTypeByRef(compositeDataType);
    inFeaturesParameter1.setValueByRef(new GPFeatureLayer());
    inFeaturesParameter1.setDirection(esriGPParameterDirection.esriGPParameterDirectionInput);
    inFeaturesParameter1.setDisplayName("Input Features");
    inFeaturesParameter1.setName("in_features");
    inFeaturesParameter1.setParameterType(esriGPParameterType.esriGPParameterTypeRequired);
    parameters.add(inFeaturesParameter1);

    // where clause - to determine which features to delete
    GPParameter inexpressionParameter2 = new GPParameter();
    inexpressionParameter2.setDataTypeByRef(new GPSQLExpressionType());
    inexpressionParameter2.setValueByRef(new GPSQLExpression());
    inexpressionParameter2.setDirection(esriGPParameterDirection.esriGPParameterDirectionInput);
    inexpressionParameter2.setDisplayName("Expression");
    inexpressionParameter2.setName("in_expression");
    inexpressionParameter2.setParameterType(esriGPParameterType.esriGPParameterTypeRequired);
    inexpressionParameter2.addDependency("in_features");
    parameters.add(inexpressionParameter2);

    // Derived Output Features
    GPParameter outFeaturesParameter = new GPParameter();
    outFeaturesParameter.setDataTypeByRef(new DEFeatureClassType());
    outFeaturesParameter.setValueByRef(new DEFeatureClass());
    outFeaturesParameter.setDirection(esriGPParameterDirection.esriGPParameterDirectionOutput);
    outFeaturesParameter.setDisplayName("Output Features");
    outFeaturesParameter.setName("out_features");
    outFeaturesParameter.setParameterType(esriGPParameterType.esriGPParameterTypeDerived);
    outFeaturesParameter.addDependency("in_features");

    GPFeatureSchema featureSchema = new GPFeatureSchema();
    featureSchema.setCloneDependency(true);

    outFeaturesParameter.setSchemaByRef(featureSchema);

    parameters.add(outFeaturesParameter);

    return parameters;
  }

  /**
   * This updates the output data of the tool, which extremely useful for
   * building models. Called each time the user changes a parameter in the tool
   * dialog or Command Line. After returning from UpdateParameters(), the GP
   * framework calls its internal validation routine to check that a given set
   * of parameter values are of the appropriate number, DataType, and value.
   */
  public void updateParameters(IArray paramvalues, IGPEnvironmentManager envMgr) {

  }

  /**
   * Updates GPMessages after GP framework validates tool's parameters
   * internally. User can specify custom messages. Called from the internal
   * validation routine. You can examine the messages created from internal
   * validation and change them if desired.
   */
  public void updateMessages(IArray paramvalues, IGPEnvironmentManager envMgr, IGPMessages gpMessages) {
    try {
      if (gpMessages.getMaxSeverity() == esriGPMessageSeverity.esriGPMessageSeverityError) {
        System.out.println("updateMessages in " + toolName + ": ");
        for (int i = 0; i < gpMessages.getCount(); i++) {
          System.out.println(gpMessages.getMessage(i).getDescription());
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Uses input parameters and executes business logic to produce output
   * parameters(s)
   */
  public void execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages messages)
    throws IOException, AutomationException {
    // Input Features
    IGPParameter inputFeaturesParameter = (IGPParameter) paramvalues.getElement(0);
    IGPValue inputFeaturesValue = gpUtilities.unpackGPValue(inputFeaturesParameter);
    String inputFeatures = inputFeaturesValue.getAsText();
    messages.addMessage("inputFeatures - " + inputFeatures);

    // Expression
    IGPParameter expressionParameter = (IGPParameter) paramvalues.getElement(1);
    IGPValue expressionValue = gpUtilities.unpackGPValue(expressionParameter);
    String expression = expressionValue.getAsText();
    messages.addMessage("expression - " + expression);

    // Output Features
    IGPParameter outputFeaturesParameter = (IGPParameter) paramvalues.getElement(2);
    IGPValue outputFeaturesValue = gpUtilities.unpackGPValue(outputFeaturesParameter);
    
    String outputFC = outputFeaturesValue.getAsText();
    messages.addMessage("outputFeaturesValue getAsTest: " + outputFC + "\nOutput FC Value Datatype: "
      + outputFeaturesValue.IGPValue_getDataType().getName());

    // retrieve input as a FeatureClass
    IFeatureClass[] ifc = new IFeatureClass[1];
    ifc[0] = new IFeatureClassProxy();

    gpUtilities.decodeFeatureLayer(inputFeaturesValue, ifc, null);

    FeatureClass inputFC = new FeatureClass(ifc[0]);

    messages.addMessage("\tDeleting selected feature(s)...");
    Workspace wsEdit = null;

    try {
      wsEdit = new Workspace(inputFC.getWorkspace());

      wsEdit.startEditing(false);
      wsEdit.startEditOperation();

      messages.addMessage("Num features before delete operation -  " + inputFC.featureCount(null));

      // use where clause to determine feature to delete
      QueryFilter deleteFilter = new QueryFilter();
      deleteFilter.setWhereClause(expression);
      inputFC.deleteSearchedRows(deleteFilter);

      messages.addMessage("Num features after delete operation -  " + inputFC.featureCount(null));

      wsEdit.stopEditOperation();
      wsEdit.stopEditing(true);
      messages.addMessage("Done.");
    } catch (Exception e) {
      if (wsEdit != null && wsEdit.isBeingEdited()) {
        wsEdit.stopEditing(false);
      }

      e.printStackTrace();
    }
  }

  /**
   * Returns metadata file. This contains metadata for the tool and its
   * parameters
   */
  public String getMetadataFile() throws IOException, AutomationException {
    return metadataFileName;
  }

  /**
   * Returns status of license
   */
  public boolean isLicensed() throws IOException, AutomationException {
    return true;
  }
}