# How Custom Extensions Work in Ossie Datasets: Bidirectional Conversion Guide

> Learn how custom extensions work in Ossie datasets. Easily store vendor-specific fields and leverage bidirectional conversion for seamless data management.

- Repository: [The Apache Software Foundation/ossie](https://github.com/apache/ossie)
- Tags: how-to-guide
- Published: 2026-07-19

---

**Custom extensions in Ossie datasets store vendor-specific fields that fall outside the standard OSSIE semantic model, automatically persisting them under the `custom_extensions` key during bidirectional conversion between Salesforce and OSSIE.**

Apache OSSIE (Open Source Semantic Information Exchange) provides a flexible mechanism for handling vendor-specific data through custom extensions. When integrating with external systems like Salesforce, these extensions ensure that unmapped properties are preserved rather than discarded during model transformation. This article examines the architectural implementation of custom extensions in Ossie datasets based on the Salesforce converter source code.

## Detecting and Storing Unmapped Properties

The conversion process begins when the OSSIE platform ingests Salesforce JSON payloads. The `CustomExtensionHandler` class identifies properties that lack predefined mappings and isolates them for extension storage.

### Identifying Unmapped Salesforce Fields

During the Salesforce-to-OSSIE conversion, the system compares incoming properties against handled mapping rules. In [`CustomExtensionHandler.java`](https://github.com/apache/ossie/blob/main/CustomExtensionHandler.java), the `storeUnmappedProperties` method initiates this process by delegating to `storeArrayLevelUnmappedProperties` when targeting dataset-level elements:

```java
// Located in converters/salesforce/src/main/java/org/apache/ossie/converter/CustomExtensionHandler.java
handler.storeUnmappedProperties(
    outputData,
    sfData,
    handledProps,
    ConverterConstants.Level.DATASETS
);

```

This method collects every property present in the Salesforce payload but absent from the `handledProps` set, ensuring no vendor-specific data is lost during ingestion.

### Packing Extensions into the Dataset Structure

Once isolated, unmapped properties undergo transformation into a standardized extension format. The `addCustomExtension` method (lines 74-96) wraps the property map as a JSON string and injects it into the `custom_extensions` array:

```java
Map<String, Object> dataset = new LinkedHashMap<>();
Map<String, Object> extraProps = Map.of(
    "externalId", "SF-12345",
    "region",     "EMEA"
);

handler.addCustomExtension(dataset, extraProps);

```

Each extension receives a `vendor_name` identifier set to `"SENDORCE"` (defined in [`ConverterConstants.java`](https://github.com/apache/ossie/blob/main/ConverterConstants.java) as `VENDOR_NAME_VALUE`), ensuring vendor isolation within the OSSIE model. The extension becomes a permanent component of the dataset object before persistence to the OSSIE datastore.

## Restoring Custom Extensions on Reverse Conversion

When converting Ossie datasets back to Salesforce format, the system reverses the process to maintain data integrity across round-trip operations.

### Merging Extensions Back to Salesforce

The restoration workflow begins with `restoreCustomExtensionsAtLevel`, which targets the dataset level using `Level.DATASETS`. This method invokes `restoreArrayLevelExtensions`, subsequently calling `restoreSalesforceCustomExtension` (lines 108-123) to locate extensions where `vendor_name` equals `"SALESFORCE"`:

```java
handler.restoreCustomExtensionsAtLevel(
    semanticModel,
    sourceData,
    ConverterConstants.Level.DATASETS
);

```

The handler extracts the JSON payload from matching `custom_extensions` entries and merges these properties directly into the resulting Salesforce representation. This bidirectional safety guarantees that vendor-specific fields survive complete conversion cycles without corruption or loss.

## Key Implementation Components

The custom extension architecture relies on three primary source files that manage the dataset conversion lifecycle:

- **[`CustomExtensionHandler.java`](https://github.com/apache/ossie/blob/main/CustomExtensionHandler.java)** – Contains the central logic for `storeUnmappedProperties`, `addCustomExtension`, and `restoreCustomExtensionsAtLevel`, handling datasets through the `sourceArrayKey = "datasets"` and `targetArrayKey = "semanticDataObjects"` parameters.
- **[`ConverterConstants.java`](https://github.com/apache/ossie/blob/main/ConverterConstants.java)** – Defines the `CUSTOM_EXTENSIONS` key, `VENDOR_NAME_VALUE` constant (`"SALESFORCE"`), and the `Level` enum used to specify dataset-level operations.
- **[`DataStructureUtils.java`](https://github.com/apache/ossie/blob/main/DataStructureUtils.java)** – Provides utility methods including `getList`, `asList`, and `streamMaps` that enable safe navigation of nested maps and lists within dataset structures.

## Summary

- **Custom extensions in Ossie datasets** preserve vendor-specific fields under the `custom_extensions` key, preventing data loss during system integration.
- The `CustomExtensionHandler` class manages bidirectional conversion through `storeUnmappedProperties` (Salesforce to OSSIE) and `restoreCustomExtensionsAtLevel` (OSSIE to Salesforce).
- **Vendor isolation** is enforced via the `VENDOR_NAME_VALUE` constant, ensuring only matching vendor extensions are processed during restoration.
- The implementation supports datasets, relationships, and metrics through generic methods parameterized by `Level.DATASETS` and array key mappings.
- Round-trip conversion safety ensures unmapped Salesforce properties survive complete transformation cycles intact.

## Frequently Asked Questions

### What are custom extensions in Ossie datasets?

Custom extensions are JSON objects stored within the `custom_extensions` array of an OSSIE dataset that contain vendor-specific properties falling outside the standard OSSIE semantic model. According to the Apache OSSIE source code, these extensions capture unmapped fields from external systems like Salesforce, wrapping them with a vendor identifier to ensure proper isolation and retrieval during subsequent conversions.

### How does OSSIE prevent vendor extension conflicts?

The platform prevents conflicts through strict vendor namespacing using the `VENDOR_NAME_VALUE` constant defined in [`ConverterConstants.java`](https://github.com/apache/ossie/blob/main/ConverterConstants.java). When processing conversions, the `restoreSalesforceCustomExtension` method filters extensions by matching the `vendor_name` field against `"SALESFORCE"`, ensuring that extensions from different vendors remain segregated and only relevant data merges into the target representation.

### Can custom extensions be used outside of Salesforce integration?

While the current implementation in [`CustomExtensionHandler.java`](https://github.com/apache/ossie/blob/main/CustomExtensionHandler.java) specifically targets Salesforce through the `VENDOR_NAME_VALUE` constant, the architecture is generic and supports multiple levels including datasets, relationships, and metrics. The same `addCustomExtension` and restoration methods could theoretically support additional vendors by extending the vendor identification logic and constants, though the existing source code primarily demonstrates Salesforce integration patterns.

### What happens to unmapped properties during round-trip conversion?

Unmapped properties undergo complete preservation through the bidirectional conversion process. During the initial Salesforce-to-OSSIE conversion, `storeArrayLevelUnmappedProperties` captures these fields into `custom_extensions`. When converting back to Salesforce, `restoreCustomExtensionsAtLevel` locates the vendor-specific extension and merges its contents back into the output payload, ensuring no data loss occurs during the full conversion cycle.