Skip to content

Conversation

@newtork
Copy link
Owner

@newtork newtork commented May 14, 2025

Original PR SAP#748


Context

https://github.com/SAP/ai-sdk-java-backlog/issues/171

  • Refactor generator customizations
  • Make generator customizations accessible from outside of plugin.
Improve maintenance

image

Demo for external plugin extensions:

Feature scope:

Example for generator customization that could even be provided by user by implementing their own class and register it via ServiceLoader.

@Getter
public class FixAdditionalProperties implements GeneratorCustomization.UpdateModelForObject
{
    private final String configKey = "fixAdditionalProperties";
    private final String configValueDefault = "true";

    @SuppressWarnings( "rawtypes" )
    @Override
    public void updateModelForObject(
        @Nonnull final ChainElementVoid<UpdateModelForObject> chain,
        @Nonnull final CodegenModel m,
        @Nonnull final Schema schema )
    {
        // Disable additional attributes to prevent model classes from extending "HashMap"
        // SAP Cloud SDK offers custom field APIs to handle additional attributes already
        schema.setAdditionalProperties(Boolean.FALSE);

        chain.doNext(next -> next.get().updateModelForObject(next, m, schema));
    }
}

Constraints:

  • A customization may implement one or more generator override methods, e.g.
    UseFloatArrays -> GeneratorCustomization.ToDefaultValue, GeneratorCustomization.UpdatePropertyForArray

  • A generator override method may be implemented by one or more customization, e.g.
    GeneratorCustomization.PreProcessOpenAPI <- UseExcludePaths, UseExcludeProperties, FixRedundantComponents

    • If multiple customizations run on the same generator method, order of execution becomes relevant:
      • Order of execution is handled via invocation chain.
      • One customization (element in the invocation chain) may dynamically decide to:
        • run before rest of chain.
        • run after rest of chain.
        • not run the chain at all.

(This solution is inspired by Servlet FilterChain API)

  • Refactor generator customization API
    • Capable to chain multiple customizations
    • Capable to access customization API from outside of plugin

Definition of Done

  • Functionality scope stated & covered
  • Tests cover the scope above
  • Error handling created / updated & covered by the tests above
  • Documentation updated
  • Release notes updated

a-d and others added 30 commits February 25, 2025 17:07
…elGeneratorIntegrationTest/openai-2024-10-21/output/com/sap/cloud/sdk/services/openai/api/DefaultApi.java
…d/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java
…f-bigdecimal-list

# Conflicts:
#	datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java
#	datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GeneratorCustomProperties.java
#	datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java
#	datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/api-class-for-ai-sdk/output/com/sap/cloud/sdk/services/builder/model/Soda.java
…l-list' into float-array-instead-of-bigdecimal-list
…ation

# Conflicts:
#	datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java
#	datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GeneratorCustomProperties.java
This reverts commit 2cb2e39.
…ensions

# Conflicts:
#	datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java
#	datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GeneratorCustomProperties.java
/**
* Optional feature toggles, may be used internally only.
*/
public interface GeneratorCustomization
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Comment)

This interface is a little complex. A good chunk of this API is static and serves API contracts, the rest is dynamic - it will grow over time depending on new customizations requiring new overrides.

The interfaces serves the following features:

(Static) Represent a generic generator customization.
  • A customization has logic to control whether it's active or not:
    • getConfigKey() (default: null) to identify a feature toggle from the configuration properties.
    • getConfigValueDefault() (default: null) to indicate default setting for active or not.
    • getConfigValue( config ) can be overloaded.
    • isConfigEnabled( config ) can be overloaded.
  • Static helper methods to load instances from runtime to a List
    • getCustomizations() returns a list of all available customization instances.
    • getCustomizations( config ) returns a filtered list of active customization.
(Static) Contains API to chain customizations.
  • ChainElement has get() to access current value and config() to access generator configuration.
  • ChainElementVoid extends ChainElement offers invocation chaining without returned objects
  • ChainElementReturn extends ChainElement offers invocation chaining with returned objects.
  • ChainableVoid and ChainableReturn are marker interfaces to indicate chaining capabilities.
(Dynamic) Contains API to override specific generator methods.
  • UpdatePropertyForArray
    • used by UseFloatArrays
  • ToDefaultValue
    • used by UseFloatArrays
  • ToBooleanGetter
    • used by FixRedundantIsBooleanPrefix
  • UpdateModelForComposedSchema
    • used by UseOneOfCreators
  • PostProcessOperationsWithModels
    • used by FixReturnNullable
  • UpdateModelForObject
    • used by FixAdditionalProperties
  • PreProcessOpenAPI
    • used by UseExcludePaths
    • used by UseExcludeProperties
    • used by FixRedundantComponents

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants