# What Are Custom Extensions in OSSIE? A Complete Guide to Vendor-Specific Attributes

> Understand custom extensions in OSSIE. Learn how this vendor-agnostic mechanism preserves proprietary metadata for lossless round-tripping of vendor specific attributes.

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

---

**Custom extensions in OSSIE provide a vendor-agnostic mechanism that captures proprietary metadata before conversion and restores it after generic mapping, ensuring lossless round-tripping of vendor-specific attributes.**

Apache OSSIE (Open Source Semantic Integration Engine) defines a strict, vendor-neutral core schema for semantic data models. To accommodate proprietary fields that fall outside this standardized structure, OSSIE implements **custom extensions**—a flexible JSON/YAML container that preserves vendor-specific attributes throughout the bidirectional conversion process.

## Understanding Custom Extensions in OSSIE

Custom extensions serve as a safe harbor for data that exceeds the OSSIE core specification. Located at the top-level of an OSSIE project's semantic model under the key `ConverterConstants.CUSTOM_EXTENSIONS`, this section stores opaque vendor payloads without polluting the standardized schema. When converters encounter attributes like Salesforce's `ai_context` or `businessPreferences`—fields absent from the core OSSIE spec—the system extracts these values and deposits them into the custom extensions block before applying generic mappings.

## Structure and Scope of Custom Extensions

### Core Components

Each custom extension entry contains two required fields:

- **`vendor_name`** – A string identifier for the originating system (e.g., `SALESFORCE`).
- **`data`** – An opaque JSON object containing any vendor-specific attributes needed for downstream processing.

### Scope Levels

The `ConverterConstants.Level` enum defines where custom extensions can attach within the model hierarchy:

- **SEMANTIC_MODEL** – Applies to the entire semantic model.
- **DATASETS** – Attaches to individual dataset definitions.
- **RELATIONSHIPS** – Associates with specific relationship mappings.
- **METRICS** – Links to metric-level metadata.

The scope determines the granularity at which the `CustomExtensionHandler` processes the vendor data during conversion.

## The Conversion Pipeline: Store and Restore Lifecycle

According to the source code in [`SemanticModelMappingHandler.java`](https://github.com/apache/ossie/blob/main/SemanticModelMappingHandler.java), custom extensions operate within a specific lifecycle embedded in the conversion pipeline:

1. **Storage Phase** (lines 89‑90): Before generic mappings begin, `storeCustomExtensions` extracts vendor-specific payloads from the source JSON and writes them into the `custom_extensions` section of the in-memory OSSIE model.
2. **Generic Mapping**: Standard OSSIE transformations execute on the core schema.
3. **Restoration Phase** (lines 72‑73): After conversions complete, `restoreCustomExtensions` injects the saved payload back into the target representation.

This sequence guarantees that proprietary metadata survives the round-trip from source → OSSIE model → target format.

## Implementation: The CustomExtensionHandler Class

The [`CustomExtensionHandler.java`](https://github.com/apache/ossie/blob/main/CustomExtensionHandler.java) file orchestrates the technical implementation of this mechanism through two primary methods:

- **`storeCustomExtensions`** – Parses the source JSON, identifies vendor-specific fields, and encapsulates them under the `custom_extensions` node with the appropriate vendor identifier.
- **`restoreCustomExtensions`** – Retrieves the stored extension data and re-injects it into the target format after generic processing concludes.

Both methods accept a `ConverterConstants.Level` parameter to specify whether the operation targets the model, dataset, relationship, or metric level.

## Practical Example: Salesforce Vendor Attributes

When converting Salesforce exports containing non-standard fields, the implementation follows this pattern:

```java
// Storing vendor-specific data before conversion
JSONObject source = ...;  // Original Salesforce JSON
JSONObject custom = new JSONObject();
custom.put(ConverterConstants.VENDOR_NAME, ConverterConstants.VENDOR_NAME_VALUE);
custom.put(ConverterConstants.DATA, source.get("vendorSpecificData"));
ossieModel.put(ConverterConstants.CUSTOM_EXTENSIONS, custom);

```

After generic OSSIE mappings transform the core model, the restoration process retrieves the original attributes:

```java
// Restoring extensions to the target format
JSONObject custom = (JSONObject) ossieModel.get(ConverterConstants.CUSTOM_EXTENSIONS);
if (custom != null && ConverterConstants.VENDOR_NAME_VALUE.equals(custom.getString(ConverterConstants.VENDOR_NAME))) {
    JSONObject vendorData = custom.getJSONObject(ConverterConstants.DATA);
    targetJson.put("vendorSpecificData", vendorData);
}

```

To target specific scopes, such as dataset-level extensions:

```java
CustomExtensionHandler.handle(
    sourceModel,
    targetModel,
    ConverterConstants.Level.DATASETS   // Scope specification
);

```

## Key Source Files

- **[`converters/salesforce/src/main/java/org/apache/ossie/converter/ConverterConstants.java`](https://github.com/apache/ossie/blob/main/converters/salesforce/src/main/java/org/apache/ossie/converter/ConverterConstants.java)** – Defines the `CUSTOM_EXTENSIONS` key, vendor name constants, and the `Level` enum.
- **[`converters/salesforce/src/main/java/org/apache/ossie/converter/CustomExtensionHandler.java`](https://github.com/apache/ossie/blob/main/converters/salesforce/src/main/java/org/apache/ossie/converter/CustomExtensionHandler.java)** – Implements the core storage and restoration logic.
- **[`converters/salesforce/src/main/java/org/apache/ossie/converter/SemanticModelMappingHandler.java`](https://github.com/apache/ossie/blob/main/converters/salesforce/src/main/java/org/apache/ossie/converter/SemanticModelMappingHandler.java)** – Documents the custom extension integration points in the conversion pipeline.

## Summary

- **Custom extensions in OSSIE** provide a standardized container for vendor-specific attributes that exceed the core schema.
- The mechanism uses a **store-and-restore pattern** managed by `CustomExtensionHandler` to ensure metadata survives bidirectional conversions.
- Extensions support **four scope levels** (SEMANTIC_MODEL, DATASETS, RELATIONSHIPS, METRICS) controlled by the `ConverterConstants.Level` enum.
- Implementation requires specifying a **vendor name** and **data payload**, enabling converters like Salesforce or Polaris to round-trip proprietary fields such as `ai_context` and `businessPreferences`.

## Frequently Asked Questions

### Where are custom extensions stored in the OSSIE model?

Custom extensions reside at the top-level of the semantic model under the `custom_extensions` key, as defined in `ConverterConstants.CUSTOM_EXTENSIONS`. This location ensures vendor data remains accessible throughout the conversion pipeline while remaining separate from standardized OSSIE schema elements.

### Which vendors can utilize custom extensions?

Any vendor converter can implement custom extensions by defining a unique `vendor_name` constant in [`ConverterConstants.java`](https://github.com/apache/ossie/blob/main/ConverterConstants.java) and utilizing the `CustomExtensionHandler` class. The architecture is vendor-agnostic, allowing Salesforce, Polaris, or any future converter to store proprietary metadata without modifying the core OSSIE specification.

### How do custom extensions maintain data integrity during conversion?

The `SemanticModelMappingHandler` orchestrates a strict lifecycle: extensions are **stored** before generic mappings modify the model, then **restored** after transformations complete. This separation ensures vendor-specific data never interferes with standard OSSIE transformations while remaining available for re-injection into the target format.

### Can custom extensions target specific parts of the model?

Yes. The `ConverterConstants.Level` enum supports four distinct scopes—SEMANTIC_MODEL, DATASETS, RELATIONSHIPS, and METRICS—allowing developers to attach custom extensions to the entire model or restrict them to specific datasets, relationships, or individual metrics as required by the vendor system.