All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.helidon.config.EnumMapperProvider Maven / Gradle / Ivy

There is a newer version: 4.1.1
Show newest version
/*
 * Copyright (c) 2023 Oracle and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.helidon.config;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

import io.helidon.common.Weight;
import io.helidon.common.Weighted;
import io.helidon.config.spi.ConfigMapperProvider;

/**
 * Built-in mapper for {@code enum}s.
 *
 * 

* This mapper attempts to match strings in the config source to enum values as follows: *

    *
  • The mapper treats hyphens ('-') in config strings as underscores when comparing to enum value names.
  • *
  • If the matcher finds a case-sensitive match with an enum value name, then that enum value matches.
  • *
  • If the matcher finds exactly one case-insensitive match, that enum value matches.
  • *
  • If the matcher finds no matches or multiple matches, throw a * {@link io.helidon.config.ConfigMappingException} with a message explaining the problem.
  • *
* These conversions are intended to maximize ease-of-use for authors of config sources so the values need not be * upper-cased nor punctuated with underscores rather than the more conventional (in config at least) hyphen. *

*

* The only hardship this imposes is if a confusingly-designed enum has values which differ only in case and the * string in the config source does not exactly match one of the enum value names. In such cases * the mapper will be unable to choose which enum value matches an ambiguous string. A developer faced with this * problem can simply provide her own explicit config mapping for that enum, for instance as a function parameter to * {@code Config#as}. *

* */ @Weight(EnumMapperProvider.WEIGHT) class EnumMapperProvider implements ConfigMapperProvider { /** * Priority with which the enum mapper provider is added to the collection of providers (user- and Helidon-provided). */ static final double WEIGHT = Weighted.DEFAULT_WEIGHT; @Override public Map, Function> mappers() { return Map.of(); } @Override public Optional> mapper(Class type) { if (!type.isEnum()) { return Optional.empty(); } return Optional.of(enumMapper((Class>) type)); } private Function enumMapper(Class> enumType) { return config -> { if (!config.hasValue() || !config.exists()) { throw MissingValueException.create(config.key()); } if (!config.isLeaf()) { throw new ConfigMappingException(config.key(), enumType, "config node must be a leaf but is not"); } String value = config.asString().get(); String convertedValue = value.replace('-', '_'); List> caseInsensitiveMatches = new ArrayList<>(); for (Enum candidate : enumType.getEnumConstants()) { // Check for an exact match first, with or without hyphen conversion. if (candidate.name().equals(convertedValue) || candidate.name().equals(value)) { return (T) candidate; } if (candidate.name().equalsIgnoreCase(value) || candidate.name().equalsIgnoreCase(convertedValue)) { caseInsensitiveMatches.add(candidate); } } if (caseInsensitiveMatches.size() == 1) { return (T) caseInsensitiveMatches.get(0); } String problem; if (caseInsensitiveMatches.size() == 0) { problem = "no match"; } else { problem = "ambiguous matches with " + caseInsensitiveMatches; } throw new ConfigMappingException(config.key(), enumType, String.format("cannot map value '%s' to enum values %s: %s", value, Arrays.asList(enumType.getEnumConstants()), problem)); }; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy