Skip to content

Extending and overriding translations #1083

@SimonCockx

Description

@SimonCockx

See parent issue: #1077

When extending a model involved in a translation, whether it is the input of the translation or the output, it is usually required to adjust the translation itself too. Two examples:

  • A business participant may extend the input schema XSD with their own specific data, such as a new type of Product. This product will need to be mapped in a different way.
  • A business participant may extend the CDM with additional attributes. These attributes will need to be populated by the translation function.

Of course, both types of extension may happen at the same time.

In such a scenario, we want to reuse as much as possible from the original translation, while being able to override the specific parts to handle extensions. Since a translation often consists of multiple functions calling each other, we want to be able to replace the implementation of a single function without having to modify any of its callers. To achieve this, we introduce the concept of a scope.

A scope allows a modeller to override the implementation of certain functions. As an example, suppose we want to implement a new case in above MapProduct function:

namespace cdm.mappings.extended
scope MyScope

import cdm.mappings.*

func ExtendedMapProduct extends MapProduct:
  inputs:
    product Product (1..1)
  output:
    result Foo (1..1)
  
  set result:
    product switch
      BondContract then MapBondContract,
      default super

Three things are going on here:

  1. At the top of the file, we define a scope called MyScope, for which all function overrides in this files will be bound in.
  2. We introduce the extends keyword to extend a function and bind the new implementation to the original function within this scope. Note that the inputs and output of the overridden function are required to be equal to the original function.
  3. Within the expression of the function, we call the original function by using the keyword super(...). This is similar to the super keyword in object oriented languages.

Given such a scope, a modeller can specify that a translation, or any other transformation, is using this scope by using the [scope ...] annotation.

func MapXToY:
  [scope MyScope]
  ...

In Java, generated code uses the dependency injection framework Guice to decide which implementation of a function to run. Within this framework, a scope corresponds to a Guice module, in which specific implementations are bound to function interfaces.

Currently, no other code generators implement functions, so this requires no additional generator work aside from Java.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsubject: code generationThis issue is about code generationsubject: model validationThis issue is about validation of Rosetta models, such as the type systemsubject: syntaxThis issue is about the syntax of Rosetta

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions