Adyen / Adyen/adyen-java-api-library

Approach for centralizing unknown enum handling

Open
#1,910 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

do not stale Feature
Dominant language
Java
Stars
148
Forks
158
Avg merge
3d 3h
Merged PRs (30d)
10

Description

Approach for centralizing unknown enum handling

The handling of enums can be improved by centralizing the fromValue logic.

1. New EnumUtils utility (hand-written, non-generated)

src/main/java/com/adyen/util/EnumUtils.java

public final class EnumUtils {
    private static final Logger LOG = Logger.getLogger(EnumUtils.class.getName());

    private EnumUtils() {}

    public static <T extends Enum<T>> T fromValue(
            Class<T> enumClass, String value, Function<T, String> getValue) {
        for (T b : enumClass.getEnumConstants()) {
            if (getValue.apply(b).equals(value)) return b;
        }
        LOG.warning(String.format("%s: unexpected enum value '%s' - Supported values are %s",
            enumClass.getSimpleName(), value, Arrays.toString(enumClass.getEnumConstants())));
        return null;
    }
}
2. Template changes (modelEnum.mustache + modelInnerEnum.mustache)

Gated behind a useEnumUtils flag — same pattern as useReflectionEqualsHashCode, handleNullableProperties, and useNullForUnknownEnumValue already in the templates.

Imports — drop Logger when flag is on:

{{^useEnumUtils}}
import java.util.logging.Logger;
{{/useEnumUtils}}

Enum body — drop the LOG field when flag is on:

{{^useEnumUtils}}
  private static final Logger LOG = Logger.getLogger({{{datatypeWithEnum}}}.class.getName());
{{/useEnumUtils}}

fromValue — delegate to the utility:

  public static {{{datatypeWithEnum}}} fromValue({{{dataType}}} value) {
{{#useEnumUtils}}
    return com.adyen.util.EnumUtils.fromValue(
        {{{datatypeWithEnum}}}.class, value, {{{datatypeWithEnum}}}::getValue);
{{/useEnumUtils}}
{{^useEnumUtils}}
    for ({{{datatypeWithEnum}}} b : {{{datatypeWithEnum}}}.values()) {
      if (b.value.equals(value)) return b;
    }
    LOG.warning(String.format(
        "{{{datatypeWithEnum}}}: unexpected enum value '%s' - Supported values are %s",
        value, Arrays.toString({{{datatypeWithEnum}}}.values())));
    return null;
{{/useEnumUtils}}
  }
3. Scope — TAPI-only vs global

Both options are feasible:

  • TAPI-only: Set useEnumUtils: true only in the TAPI config in adyen-sdk-automation. Safe and scoped to this PR, but leaves an inconsistency: TAPI enums use EnumUtils, all other services keep the per-enum Logger.
  • Global (recommended): Set the flag across all service configs in adyen-sdk-automation, re-generate all services. Eliminates Logger from every generated enum consistently — which seems to be the intent of the original suggestion.

TAPI-only is a one-liner per config file in the automation repo and easy to do now; globally applying it later is equally straightforward since it's just a flag flip.


Also: the String.format() suggestion applies to the fallback (non-useEnumUtils) path in the template as well — worth fixing there too regardless of which direction we go.

Originally posted by @thomasc-adyen in https://github.com/Adyen/adyen-java-api-library/issues/1906#issuecomment-4238296755

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/main/java/com/adyen/util/EnumUtils.java, modelEnum.mustache, and modelInnerEnum.mustache, then inspect the existing flag patterns and service configuration files in adyen-sdk-automation. Determine whether the flag is applied to TAPI only or globally; done means the selected generated enums use the centralized handling consistently and the fallback template path includes the noted String.format change.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, backend
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.