forked from quarkusio/quarkus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(configuration): add ConvertWith and DefaultConverter annotations.
Adds a default enum converter for hyphenated values to override implicit enum default converter. Fixes quarkusio#2678
- Loading branch information
Showing
6 changed files
with
183 additions
and
7 deletions.
There are no files selected for viewing
27 changes: 27 additions & 0 deletions
27
core/runtime/src/main/java/io/quarkus/runtime/annotations/ConvertWith.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package io.quarkus.runtime.annotations; | ||
|
||
import static java.lang.annotation.ElementType.FIELD; | ||
import static java.lang.annotation.ElementType.PARAMETER; | ||
import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.Target; | ||
|
||
import org.eclipse.microprofile.config.spi.Converter; | ||
|
||
/** | ||
* Defines a {@link Converter} to be used for conversion of a config property. | ||
* This will override the default converter on the target config item. | ||
*/ | ||
@Retention(RUNTIME) | ||
@Target({ FIELD, PARAMETER }) | ||
@Documented | ||
public @interface ConvertWith { | ||
/** | ||
* Specify the relative name of the configuration item. | ||
* | ||
* @return the name | ||
*/ | ||
Class<? extends Converter<?>> value(); | ||
} |
19 changes: 19 additions & 0 deletions
19
core/runtime/src/main/java/io/quarkus/runtime/annotations/DefaultConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package io.quarkus.runtime.annotations; | ||
|
||
import static java.lang.annotation.ElementType.FIELD; | ||
import static java.lang.annotation.ElementType.PARAMETER; | ||
import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Indicates that a config item should be converted using a default converter: built-in/implicit converters or a custom | ||
* converter. | ||
*/ | ||
@Retention(RUNTIME) | ||
@Target({ FIELD, PARAMETER }) | ||
@Documented | ||
public @interface DefaultConverter { | ||
} |
54 changes: 54 additions & 0 deletions
54
core/runtime/src/main/java/io/quarkus/runtime/configuration/HyphenateEnumConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package io.quarkus.runtime.configuration; | ||
|
||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
import org.eclipse.microprofile.config.spi.Converter; | ||
|
||
/** | ||
* A converter for enums that are hyphenated | ||
*/ | ||
final public class HyphenateEnumConverter implements Converter<Enum> { | ||
private static final String HYPHEN = "-"; | ||
private static final Pattern PATTERN = Pattern.compile("([-_]+)"); | ||
|
||
private final Class<? extends Enum> enumType; | ||
|
||
public HyphenateEnumConverter(Class<? extends Enum> enumType) { | ||
this.enumType = enumType; | ||
} | ||
|
||
@Override | ||
public Enum convert(String value) { | ||
if (value == null || value.trim().isEmpty()) { | ||
return null; | ||
} | ||
|
||
final Enum[] enums = enumType.getEnumConstants(); | ||
|
||
for (Enum enumValue : enums) { | ||
final String name = enumValue.name(); | ||
final String hyphenated = hyphenate(name); | ||
if (name.equals(value) || hyphenated.equals(value)) { | ||
return enumValue; | ||
} | ||
} | ||
|
||
try { | ||
return Enum.valueOf(enumType, value); | ||
} catch (Exception e) { | ||
throw new IllegalArgumentException(String.format("Cannot convert %s to enum %s", value, enumType)); | ||
} | ||
} | ||
|
||
private String hyphenate(String value) { | ||
StringBuffer target = new StringBuffer(); | ||
String hyphenate = io.quarkus.runtime.util.StringUtil.hyphenate(value); | ||
Matcher matcher = PATTERN.matcher(hyphenate); | ||
while (matcher.find()) { | ||
matcher.appendReplacement(target, HYPHEN); | ||
} | ||
matcher.appendTail(target); | ||
return target.toString(); | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
...o/quarkus/deployment/util/StringUtil.java → ...a/io/quarkus/runtime/util/StringUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
core/runtime/src/test/java/io/quarkus/runtime/configuration/HyphenateEnumConverterTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package io.quarkus.runtime.configuration; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
public class HyphenateEnumConverterTest { | ||
enum MyEnum { | ||
DISCARD, | ||
READ_UNCOMMITTED, | ||
SIGUSR1, | ||
TrendBreaker, | ||
MAKING_LifeDifficult, | ||
YeOldeJBoss, | ||
} | ||
|
||
enum MyOtherEnum { | ||
makingLifeDifficult, | ||
READ__UNCOMMITTED | ||
} | ||
|
||
HyphenateEnumConverter hyphenateEnumConverter; | ||
|
||
@Before | ||
public void setUp() throws Exception { | ||
|
||
} | ||
|
||
@Test | ||
public void convertMyEnum() { | ||
hyphenateEnumConverter = new HyphenateEnumConverter(MyEnum.class); | ||
MyEnum myEnum = (MyEnum) hyphenateEnumConverter.convert("DISCARD"); | ||
Assert.assertEquals(myEnum, MyEnum.DISCARD); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("discard"); | ||
Assert.assertEquals(myEnum, MyEnum.DISCARD); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("READ_UNCOMMITTED"); | ||
Assert.assertEquals(myEnum, MyEnum.READ_UNCOMMITTED); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("read-uncommitted"); | ||
Assert.assertEquals(myEnum, MyEnum.READ_UNCOMMITTED); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("SIGUSR1"); | ||
Assert.assertEquals(myEnum, MyEnum.SIGUSR1); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("sigusr1"); | ||
Assert.assertEquals(myEnum, MyEnum.SIGUSR1); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("TrendBreaker"); | ||
Assert.assertEquals(myEnum, MyEnum.TrendBreaker); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("trend-breaker"); | ||
Assert.assertEquals(myEnum, MyEnum.TrendBreaker); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("MAKING_LifeDifficult"); | ||
Assert.assertEquals(myEnum, MyEnum.MAKING_LifeDifficult); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("making-life-difficult"); | ||
Assert.assertEquals(myEnum, MyEnum.MAKING_LifeDifficult); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("YeOldeJBoss"); | ||
Assert.assertEquals(myEnum, MyEnum.YeOldeJBoss); | ||
myEnum = (MyEnum) hyphenateEnumConverter.convert("ye-olde-jboss"); | ||
Assert.assertEquals(myEnum, MyEnum.YeOldeJBoss); | ||
} | ||
|
||
@Test | ||
public void convertMyOtherEnum() { | ||
hyphenateEnumConverter = new HyphenateEnumConverter(MyOtherEnum.class); | ||
MyOtherEnum myOtherEnum = (MyOtherEnum) hyphenateEnumConverter.convert("makingLifeDifficult"); | ||
Assert.assertEquals(myOtherEnum, MyOtherEnum.makingLifeDifficult); | ||
myOtherEnum = (MyOtherEnum) hyphenateEnumConverter.convert("making-life-difficult"); | ||
Assert.assertEquals(myOtherEnum, MyOtherEnum.makingLifeDifficult); | ||
myOtherEnum = (MyOtherEnum) hyphenateEnumConverter.convert("READ__UNCOMMITTED"); | ||
Assert.assertEquals(myOtherEnum, MyOtherEnum.READ__UNCOMMITTED); | ||
myOtherEnum = (MyOtherEnum) hyphenateEnumConverter.convert("read-uncommitted"); | ||
Assert.assertEquals(myOtherEnum, MyOtherEnum.READ__UNCOMMITTED); | ||
} | ||
|
||
@Test(expected = IllegalArgumentException.class) | ||
public void testIllegalEnumConfigUtilConversion() { | ||
hyphenateEnumConverter = new HyphenateEnumConverter(MyEnum.class); | ||
hyphenateEnumConverter.convert("READ__UNCOMMITTED"); | ||
} | ||
} |
12 changes: 6 additions & 6 deletions
12
...s/deployment/util/StringUtilTestCase.java → ...rkus/runtime/util/StringUtilTestCase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters