Creating a custom function factory class


Summary
There are three essential tasks to creating a custom geoprocessing function tool: creating a custom function factory class, creating a custom function tool class, and deploying the classes to ArcGIS. This topic explains the first task, creating a function factory class that hosts and manages the custom geoprocessing function tool.

In this topic


About creating a custom function factory class 

The geoprocessing framework inherently has many function factories to allow logical grouping of tools. Each function factory manages one or more tools. A custom function factory must be created to manage one or more of your custom geoprocessing function tools. 

Create a Java class

A custom function factory is a simple Plain Old Java Object (POJO) that must be annotated with @ArcGISExtension annotation and deployed to ArcGIS. To create a custom function factory class, you first need to create a Java class that implements IGPFunctionFactory, annotate the class with @ArcGISExtension annotation, and set the category attribute of the ArcGIS extension to ArcGISCategories.GPFunctionFactories as shown in the following code:
[Java]
//Annotate the function factory.
@ArcGISExtension(categories = {
    ArcGISCategories.GPFunctionFactories
}

)
//Create a Java class that implements IGPFunctionFactory.
class CustomFunctionFactory implements IGPFunctionFactory{
    //Implement the methods.

}

Implement the methods

The necessary tasks that implement the IGPFunctionFactory methods are described in this section.

Define a name for the factory

Define the name of the function factory using the getName() method as shown in the following code snippet. The name of the function factory is listed in the Add Tool dialog box when you add a tool to the toolbox in ArcToolbox as shown in the following screen shot:
[Java]
public String getName()throws IOException, AutomationException{
    return "JavaExtensionsTools";
}

Define a FunctionName object for the tools

The FunctionFactory object manages the function tools based on the FunctionName object. The factory object associates each function tool with a corresponding FunctionName object as shown in the following diagram:
A FunctionName object defines the name, display name, description, category, and required extension of the associated tool. You need to create a FunctionName object for each custom function tool.
The getFunctionName() method creates a FunctionName object for each function tool based on the input tool name. The getFunctionNames() method creates and returns an enumeration of the FunctionName object that corresponds to the tools that the factory supports. The geoprocessing framework invokes these methods when needed—for example, the getFunctionNames() method is invoked to list the available function tools in the Add Tool dialog box as shown in the following screen shot:
For information on creating a function tool, see Creating a custom function tool class.
The following code snippet shows how to create FunctionName objects for the Java Calculate Area and Java Build Pyramids custom function tools. It also shows the implementation of the getFunctionName() and getFunctionNames() methods of the IGPFunctionFactory interface.
[Java]
//Declare class variables.
private String toolNameBuildPyramid = "JavaBuildPyramid";
;
private String toolNameCalcArea = "JavaCalculateArea";

//Define a FunctionName object for the specified function tool.
public IGPName getFunctionName(String name)throws IOException, AutomationException{
    GPFunctionName functionName = new GPFunctionName();
    if (name.equalsIgnoreCase(toolNameCalcArea)){
        //Create a FunctionName object for the Java Calculate Area tool.
        functionName.setCategory("JavaExtensions");
        functionName.setDescription("Java Calculate Area for FeatureClass");
        functionName.setDisplayName("Java Calculate Area");
        //The name of the FunctionName object should be the same as the
        //tool name defined by the BaseGeoprocessingTool.getName() method.
        functionName.setName(toolNameCalcArea);
        functionName.setFactoryByRef(this);
    }
    else if (name.equalsIgnoreCase(toolNameBuildPyramid)){
        //Create a FunctionName object for the Java Build Pyramids tool.
        functionName.setCategory("JavaExtensions");
        functionName.setDescription("Java Tool for Build Pyramids");
        functionName.setDisplayName("Java Build Pyramids");
        //The name of the FunctionName object should be the same as the tool name.
        functionName.setName(toolNameBuildPyramid);
        functionName.setFactoryByRef(this);
    }
    else{
        System.out.println("Returning null");
    }
    return null;
}

//Create an enumeration of the FunctionName object for the associated tools.

public IEnumGPName getFunctionNames()throws IOException, AutomationException{

    EnumGPName nameArray = new EnumGPName();
    //Create and add a FunctionName object for the Java Calculate Area tool.
    nameArray.add(getFunctionName(toolNameCalcArea));
    //Create and add a FunctionName object for the Java Build Pyramid tool.
    nameArray.add(getFunctionName(toolNameBuildPyramid));
    return nameArray;
}
Ensure that the name of the FunctionName object defined by GPFunctionName.setName() is the same as the tool name defined by the BaseGeoprocessingTool.getName() method.

Define the function tools

The geoprocessing framework invokes the getFunction() method to create function tools when needed. The tool reference that must be returned by the method is based on the name of the FunctionName object passed in as a parameter. The general convention is that the tool's name must also be the name of it's corresponding FunctionName object defined by the getFunctionName() method. The following code snippet describes the implementation of the getFunction() method of IGPFunctionFactory that creates function tools:
[Java]
//Declare class variables.
private String toolNameBuildPyramid = "JavaBuildPyramid";
;
private String toolNameCalcArea = "JavaCalculateArea";

//Create function tools based on the function name.
public IGPFunction getFunction(String name)throws IOException, AutomationException{

    if (name.equalsIgnoreCase(toolNameCalcArea)){
        //Create the CalculateArea geoprocessing function tool.
        GPCalculateArea gpCustomTool = new GPCalculateArea();
        return gpCustomTool;
    }
    else if (name.equalsIgnoreCase(toolNameBuildPyramid)){
        //Create the BuildPyramid geoprocessing function tool.
        JBuildPyramids gpCustomTool = new JBuildPyramids();
        return gpCustomTool;
    }
    return null;
}

//Implement other methods.
}

Define the CLSID

The geoprocessing framework invokes the getClsid() method to find the class identifier (CLSID) that's associated with the FunctionFactory object. All Component Object Model (COM) classes have an associated CLSID that uniquely identifies them. The following code snippet provides the implementation to generate the CLSID for the FunctionFactory object:
[Java]
//Define the CLSID. A similar implementation is used for all custom function factories.
//Do not modify the code.
public IUID getCLSID()throws IOException, AutomationException{
    UID uid = new UID();
    uid.setValue("{" + UUID.nameUUIDFromBytes(this.getClass().getName().getBytes()) 
        + "}");
    return uid;
}
A similar implementation is used for all custom function factories. Do not modify the code.

Define the environment settings

You can associate environment settings with each function tool created by the function factory. The getFunctionEnvironments() method creates and returns an enumeration of the GPEnvironment object that provide new environment settings for each tool.

What's next

Once the custom function tool class and the custom function factory class are created, their corresponding Java .class files must be bundled in a Java Archive (JAR) file and deployed to ArcGIS by placing the JAR file in the <ArcGIS Install Dir>/java/lib/ext folder. After deployment, the custom geoprocessing function tool can be accessed as follows:
For more information about accessing and consuming custom geoprocessing tools in ArcToolbox and in ArcGIS Engine and ArcGIS Server applications, see the following topics:
An ArcGIS application (ArcGIS Engine, ArcMap, ArcCatalog, and ArcGIS Server) recognizes the custom geoprocessing function tool when the application is started. If the ArcGIS application is already running, then it needs to be restarted after deployment. While testing the tool, if you modify the code in the Java classes bundled in the JAR file, the JAR file must be recreated and redeployed. You also need to restart the ArcGIS application after redeployment.


See Also:

How to build custom geoprocessing tools
Creating a custom function tool class




Development licensingDeployment licensing
Engine Developer KitEngine
ServerServer
ArcGIS for Desktop BasicArcGIS for Desktop Basic
ArcGIS for Desktop StandardArcGIS for Desktop Standard
ArcGIS for Desktop AdvancedArcGIS for Desktop Advanced