How to implement a class extension


In this topic


About implementing a class extension

Class extensions are implemented to define complex custom data behavior in a geodatabase. Class extensions are Java extension classes that are developed using the ArcObjects application programming interface (API) and deployed to ArcGIS. Class extensions that are deployed to ArcGIS must be applied to object classes (tables) or feature classes in a geodatabase programmatically to enforce the custom data behavior.
For more information about class extensions, see Getting started with class extensions.  

Develop a class extension

A class extension is a Plain Old Java Object (POJO) that implements specific interfaces and is annotated with @ArcGISExtension. This section describes how to develop a class extension.

Create a Java class

Create a Java Class for a class extension that implements, at a minimum, the IClassExtension and IObjectClassExtension interfaces. If the extension is designed for feature classes, implement the IFeatureClassExtension interface too. IClassExtension is the only required interface; IObjectClassExtension and IFeatureClassExtension are indicator interfaces that do not have method definitions to implement. 
The custom data behavior of a class extension is defined by implementing additional interfaces. The Java class must implement one or more of the following interfaces depending on the custom behavior implemented by the class extension:
For more information about implementing these interfaces, see the following topics:

Annotate a Java class

When the class extension is developed and deployed to an ArcGIS client, the ArcGIS runtime recognizes the Java class as a custom object by its @ArcGISExtension annotation. It is essential that you annotate the Java class with @ArcGISExtension annotation and set its category attribute as ArcGISCategories.GeoObjectClassExtensions. 
The following code snippet shows how the Java class is annotated with @ArcGISExtension:
[Java]
//Create a Java class.
//Annotate the Java class.
@ArcGISExtension(categories = {
    ArcGISCategories.GeoObjectClassExtensions
}

)public class FirstClassExtension implements IClassExtension, IObjectClassExtension,
    IFeatureClassExtension{}

Add implementation code

Add implementation code to the init and shutdown methods of the IClassExtension interface. These methods are described as follows:
A class extension is instantiated and disposed of in parallel with the lifespan of the object or feature class to which it is applied in memory.
The following code snippet implements a skeleton class extension. The data behavior of the class extension is implemented through interfaces such as IObjectClassValidation, IObjectClassEvents, IRelatedObjectClassEvents, and IRelatedObjectClassEvents2 and is not shown in the code. The code snippet does show the following in the init() method implementation: 
[Java]
//Declare class variables.
// The property set keys are used to get and set the extension properties.
public final static String CREATED_FIELD_PROPERTY = "CREATION_FIELDNAME";
public final static String MODIFIED_FIELD_PROPERTY = "MODIFICATION_FIELDNAME";

// Use the default field names as timestamp fields if none are defined when the
//class extension is applied.
private final static String DEFAULT_CREATED_FIELD = "CREATED";
private final static String DEFAULT_MODIFIED_FIELD = "MODIFIED";

/**
 * The indexes of the timestamp fields in the extension class. A value of -1 indicates
 * that the field is not used or could not be found during initialization.
 */
private int createdFieldIndex =  - 1;
private int modifiedFieldIndex =  - 1;

/************************************************************************************************
 * IClassExtension members
 ************************************************************************************************/

// Initialize the extension, passing in a reference to its class helper and its extension properties.

public void init(IClassHelper classHelper, IPropertySet extensionProperties)throws
    IOException, AutomationException{
    // Get a reference to the extension's object class.
    IClass baseClass = classHelper.esri_getClass();
    // Make sure a valid property set is provided.
    if (extensionProperties != null && extensionProperties.getCount() != 0){
        // Get the field names from the property set.
        Object createdFieldProperty = extensionProperties.getProperty
            (CREATED_FIELD_PROPERTY);
        Object modifiedFieldProperty = extensionProperties.getProperty
            (MODIFIED_FIELD_PROPERTY);

        // Get the created field index.
        if (createdFieldProperty != null){
            createdFieldIndex = baseClass.findField(createdFieldProperty.toString());
        }
        // Get the modified field index.
        if (modifiedFieldProperty != null){
            modifiedFieldIndex = baseClass.findField(modifiedFieldProperty.toString()
                );
        }
    }
    else{
        // If the extension properties are null or empty, assume the class has
        // been created without extension properties. Apply the default property values.
        ISchemaLock schemaLock = null;
        try{
            // Attempt to acquire an exclusive schema lock. If this fails, an
            // AutomationException will be raised.
            schemaLock = new ISchemaLockProxy(classHelper.esri_getClass());
            schemaLock.changeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
            // Create a default set of extension properties.
            IPropertySet propertySet = new PropertySet();
            propertySet.setProperty(CREATED_FIELD_PROPERTY, DEFAULT_CREATED_FIELD);
            propertySet.setProperty(MODIFIED_FIELD_PROPERTY, DEFAULT_MODIFIED_FIELD);
            // Use the IClassSchemaEdit2 interface to persist a new set of extension properties.
            IClassSchemaEdit2 classSchemaEdit2 = new IClassSchemaEdit2Proxy
                (classHelper.esri_getClass());
            classSchemaEdit2.alterClassExtensionProperties(propertySet);
        }
        catch (AutomationException autoExc){
            // An exclusive schema lock could not be acquired. Allow the extension to
            // finish initializing; no custom behavior will occur.
        }
        finally{
            try{
                // Ensure that the schema lock is shared.
                if (schemaLock != null)
                    schemaLock.changeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
            }
            catch (Exception exc){
                // Ignore any errors at this point.
            }
        }
    }
}

/**
 * Called when the extension's class is being disposed of from memory.
 */
public void shutdown()throws IOException, AutomationException{
    // Do nothing.
}

Export as a JAR file

The class extension Java class must be deployed to ArcGIS. To deploy the class extension, the class files of the Java classes are bundled as a Java Archive (JAR) file.
For more information about creating a JAR file, see How to export a custom geoprocessing tool.

Deploy a class extension

To deploy the class extension to ArcGIS for Desktop (ArcMap or ArcCatalog), copy the JAR file containing the extension to <ArcGIS Desktop Install Dir>/java/lib/ext folder and restart the Desktop application. To deploy class extension to ArcGIS for Server, place the file in <ArcGIS Server Install Dir>/usr/lib/ext folder and restart Server. This will deploy the extension to the appropriate ArcGIS environment.
The class extension must then be enabled or applied on the geodatabase feature class of choice programmatically (as described in the following section). If the class extension source is modified at any time, it must then be redeployed following above mentioned steps, for the changes to take effect. 

Enabling a class extension

When the class extension is developed and deployed, there are a couple of ways to apply the extension to an object class (table) or feature class, depending on whether the class already exists and whether the extension is applied through an application or programmatically. Use one of the following options to apply a class extension: 
The ArcObjects Java SDK includes several samples that demonstrate enabling class extensions. Please consult any one of the following samples to understand API usage:
Note that when executing class extensions in Server environment, the esriLicenseProductCode.esriLicenseProductCodeArcServer license must be used.
As a note of caution, any geodatabase that includes a feature class with a class extension enabled will remain accessible only when the class extension is present and registered. Therefore, if you move a feature class with a class extension enabled to another ArcGIS environment (for ex: Server to Desktop or Engine) or geodatabase, ensure that the destination environment or geodatabase too has the class extension registered.
A class extension can be applied to one or more objects or feature classes in a geodatabase; however, only one class extension can be applied to an object or feature class at any given time.


See Also:

Customize attribute validation
Customize object event behavior
Customize relationship behavior
Apply class extensions




Development licensingDeployment licensing
Engine Developer KitArcInfo
ArcEditor
ArcView
Engine Runtime
Server