From cb054fa2cee2d09c9f8375711e80d3b2ef1971fe Mon Sep 17 00:00:00 2001
From: Seth Falco
Date: Fri, 1 Oct 2021 21:26:28 +0200
Subject: [PATCH] feat: add converters for standard objects
---
.../config/converter/CharacterConverter.java | 77 +++++++
.../impl/config/converter/ColorConverter.java | 218 ++++++++++++++++++
.../config/converter/DimensionConverter.java | 75 ++++++
.../config/converter/DurationConverter.java | 79 +++++++
.../impl/config/converter/EnumConverter.java | 146 ++++++++++++
.../impl/config/converter/FileConverter.java | 48 ++++
.../converter/InetAddressConverter.java | 55 +++++
.../config/converter/InstantConverter.java | 46 ++++
.../config/converter/LocaleConverter.java | 44 ++++
.../config/converter/PatternConverter.java | 45 ++++
.../config/converter/PeriodConverter.java | 54 +++++
.../impl/config/converter/PointConverter.java | 72 ++++++
.../impl/config/converter/UriConverter.java | 59 +++++
.../impl/config/converter/UrlConverter.java | 98 ++++++++
.../impl/config/converter/UuidConverter.java | 45 ++++
.../converter/CharacterConverterTest.java | 129 +++++++++++
.../config/converter/ColorConverterTest.java | 127 ++++++++++
.../converter/DimensionConverterTest.java | 76 ++++++
.../converter/DurationConverterTest.java | 68 ++++++
.../config/converter/EnumConverterTest.java | 98 ++++++++
.../config/converter/FileConverterTest.java | 61 +++++
.../converter/InetAddressConverterTest.java | 80 +++++++
.../converter/InstantConverterTest.java | 62 +++++
.../config/converter/LocaleConverterTest.java | 58 +++++
.../converter/PatternConverterTest.java | 47 ++++
.../config/converter/PeriodConverterTest.java | 62 +++++
.../config/converter/PointConverterTest.java | 58 +++++
.../config/converter/UriConverterTest.java | 79 +++++++
.../config/converter/UrlConverterTest.java | 79 +++++++
.../config/converter/UuidConverterTest.java | 48 ++++
.../src/main/asciidoc/configuration.adoc | 28 ++-
31 files changed, 2320 insertions(+), 1 deletion(-)
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/CharacterConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/ColorConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/DimensionConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/DurationConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/EnumConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/FileConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/InetAddressConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/InstantConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/LocaleConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PatternConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PeriodConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PointConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UriConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UrlConverter.java
create mode 100644 deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UuidConverter.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/CharacterConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/ColorConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/DimensionConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/DurationConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/EnumConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/FileConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/InetAddressConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/InstantConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/LocaleConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PatternConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PeriodConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PointConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UriConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UrlConverterTest.java
create mode 100644 deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UuidConverterTest.java
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/CharacterConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/CharacterConverter.java
new file mode 100644
index 000000000..3755f4ee0
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/CharacterConverter.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.util.Objects;
+
+/**
+ * Converts a character or numeric value representing a character into a
+ * Java {@link Character} object.
+ *
+ *
+ * This converter may also accept hexadecimal {@link String}s if obtaining
+ * a character from it's numeric value is desired.
+ *
+ * Intended for cases where there are concerns regarding the environment,
+ * such as system/file encodings between clients, applications, and servers.
+ *
+ *
+ * @since 2.0.0
+ */
+public class CharacterConverter implements ConfigResolver.Converter
+{
+
+ /** Determines if an input is a hexadecimal {@link String}. */
+ private static final String HEX_PREFIX = "0x";
+
+ /**
+ * @param value Value to convert.
+ * @return A {@link Character} which represents the value.
+ * @throws NullPointerException If the value is null.
+ * @throws IllegalArgumentException If an empty string is provided as the value.
+ * @throws NumberFormatException If a hexadecimal {@link String} is provided, but
+ * can not be parsed as an {@link Integer}.
+ */
+ @Override
+ public Character convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+
+ if (value.isEmpty())
+ {
+ throw new IllegalArgumentException("Value must not be empty.");
+ }
+
+ if (value.length() == 1)
+ {
+ return value.charAt(0);
+ }
+
+ if (value.substring(0, 2).equalsIgnoreCase(HEX_PREFIX))
+ {
+ final String substring = value.substring(HEX_PREFIX.length());
+ final int hex = Integer.parseInt(substring, 16);
+ return (char)hex;
+ }
+
+ throw new IllegalArgumentException("Value can't be represented as a character.");
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/ColorConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/ColorConverter.java
new file mode 100644
index 000000000..1a0932265
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/ColorConverter.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.awt.Color;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Converts a value into a {@link Color} object.
+ *
+ *
+ * Will interpret hexadecimal colors similar to CSS engines, for example #RGB is interpreted as
+ * #RRGGBB. If using the literal hexadecimal value is desired, the value should be prefixed with 0x
+ * instead of {@link #HEX_COLOR_PREFIX #}.
+ *
+ *
+ * @since 2.0.0
+ */
+public class ColorConverter implements ConfigResolver.Converter
+{
+ /** Prefix for hexadecimal color notation. */
+ private static final String HEX_COLOR_PREFIX = "#";
+
+ /** Regular expression matching the output of {@link Color#toString()}. */
+ private static final Pattern JAVA_COLOR_PATTERN =
+ Pattern.compile("^(?:[A-Za-z\\d._]+)??\\[?(?:r=)?(\\d{1,3}),(?:g=)?(\\d{1,3}),(?:b=)?(\\d{1,3})\\]?$");
+
+ /**
+ * Converts a {@link Color} into a {@link String}.
+ *
+ *
+ * Supports hexadecimal colors like #RGB, #RRGGBB, #RGBA, and #RRGGBBAA, and interprets raw color names based
+ * on the colors defined in Java, such as:
+ *
+ *
+ *
+ * - {@link Color#BLACK}
+ * - {@link Color#BLUE}
+ * - {@link Color#CYAN}
+ * - {@link Color#DARK_GRAY}
+ * - {@link Color#GRAY}
+ * - {@link Color#GREEN}
+ * - {@link Color#LIGHT_GRAY}
+ * - {@link Color#MAGENTA}
+ * - {@link Color#ORANGE}
+ * - {@link Color#PINK}
+ * - {@link Color#RED}
+ * - {@link Color#WHITE}
+ * - {@link Color#YELLOW}
+ *
+ *
+ * @param value Value to convert.
+ * @return {@link Color} which represents the compiled value.
+ * @throws NullPointerException If the value is null.
+ * @throws NumberFormatException If an invalid number is provided.
+ */
+ @Override
+ public Color convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+
+ switch (value.toLowerCase(Locale.ROOT))
+ {
+ case "black":
+ return Color.BLACK;
+ case "blue":
+ return Color.BLUE;
+ case "cyan":
+ return Color.CYAN;
+ case "darkgray":
+ case "darkgrey":
+ case "dark_gray":
+ case "dark_grey":
+ return Color.DARK_GRAY;
+ case "gray":
+ case "grey":
+ return Color.GRAY;
+ case "green":
+ return Color.GREEN;
+ case "lightgray":
+ case "lightgrey":
+ case "light_gray":
+ case "light_grey":
+ return Color.LIGHT_GRAY;
+ case "magenta":
+ return Color.MAGENTA;
+ case "orange":
+ return Color.ORANGE;
+ case "pink":
+ return Color.PINK;
+ case "red":
+ return Color.RED;
+ case "white":
+ return Color.WHITE;
+ case "yellow":
+ return Color.YELLOW;
+ default:
+ // Do nothing.
+ }
+
+ if (value.startsWith(HEX_COLOR_PREFIX))
+ {
+ return parseWebColor(value);
+ }
+
+ if (value.contains(","))
+ {
+ return parseToStringColor(value);
+ }
+
+ return Color.decode(value);
+ }
+
+ /**
+ * Parses the Color based on the result of the {@link Color#toString()} method.
+ *
+ * Accepts the following values:
+ *
+ * java.awt.Color[r=255,g=255,b=255]
+ * [r=255,g=255,b=255]
+ * r=255,g=255,b=255
+ * 255,255,255
+ *
+ *
+ * @param value A color as represented by {@link Color#toString()}.
+ * @return The Java friendly {@link Color} this color represents.
+ * @throws IllegalArgumentException If the input can't be matched by the {@link #JAVA_COLOR_PATTERN}
+ * or a {@link Color} component specified is over 255.
+ */
+ private Color parseToStringColor(final String value)
+ {
+ Objects.requireNonNull(value);
+
+ Matcher matcher = JAVA_COLOR_PATTERN.matcher(value);
+
+ if (!matcher.matches())
+ {
+ throw new IllegalArgumentException("Invalid Color String provided. Could not parse.");
+ }
+
+ final int red = Integer.parseInt(matcher.group(1));
+ final int green = Integer.parseInt(matcher.group(2));
+ final int blue = Integer.parseInt(matcher.group(3));
+
+ if (red > 255 || green > 255 || blue > 255)
+ {
+ throw new IllegalArgumentException("Color component integers must be between 0 and 255.");
+ }
+
+ return new Color(red, green, blue);
+ }
+
+ /**
+ * Returns a {@link Color} for hexadecimal colors.
+ *
+ * @param value Hexadecimal representation of a color.
+ * @return The converted value.
+ * @throws NumberFormatException If the hexadecimal input contains non parsable characters.
+ */
+ public Color parseWebColor(final String value)
+ {
+ Objects.requireNonNull(value);
+
+ switch (value.length())
+ {
+ case 4:
+ return new Color(
+ Integer.parseInt(value.substring(1, 2), 16) * 17,
+ Integer.parseInt(value.substring(2, 3), 16) * 17,
+ Integer.parseInt(value.substring(3, 4), 16) * 17
+ );
+ case 5:
+ return new Color(
+ Integer.parseInt(value.substring(1, 2), 16) * 17,
+ Integer.parseInt(value.substring(2, 3), 16) * 17,
+ Integer.parseInt(value.substring(3, 4), 16) * 17,
+ Integer.parseInt(value.substring(4, 5), 16) * 17
+ );
+ case 7:
+ return new Color(
+ Integer.parseInt(value.substring(1, 3), 16),
+ Integer.parseInt(value.substring(3, 5), 16),
+ Integer.parseInt(value.substring(5, 7), 16)
+ );
+ case 9:
+ return new Color(
+ Integer.parseInt(value.substring(1, 3), 16),
+ Integer.parseInt(value.substring(3, 5), 16),
+ Integer.parseInt(value.substring(5, 7), 16),
+ Integer.parseInt(value.substring(7, 9), 16)
+ );
+ default:
+ throw new IllegalArgumentException("Value is an malformed hexadecimal color, if literal value decoding " +
+ "is required, prefix with 0x instead of #, otherwise expecting 3, 4, 6, or 8 characters only.");
+ }
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/DimensionConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/DimensionConverter.java
new file mode 100644
index 000000000..ad735346c
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/DimensionConverter.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.awt.Dimension;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Converts values to a {@link Dimension}.
+ *
+ *
+ * Accepts a single {@link Integer} value, or two {@link Integer} values separated by the character x
.
+ *
+ *
+ * The dimensions must consist of non-negative {@ink Integer} values.
+ *
+ * @since 2.0.0
+ */
+public class DimensionConverter implements ConfigResolver.Converter
+{
+ /** Pattern to validate and tokenize the {@link String}. */
+ private static final Pattern DIMENSION_PATTERN = Pattern.compile("(\\d+)(?:x(\\d+))?");
+
+ /**
+ * @param value Value to convert.
+ * @return A {@link Dimension} which represents the value.
+ * @throws NullPointerException If the value is null.
+ * @throws NumberFormatException If the {@link Dimension} width or height is bigger than {@link Integer#MAX_VALUE}.
+ */
+ @Override
+ public Dimension convert(final String value)
+ {
+ Objects.requireNonNull(value, "Dimensions can not be null.");
+
+ if (value.isEmpty())
+ {
+ throw new IllegalArgumentException("Dimensions can not be empty.");
+ }
+
+ Matcher matcher = DIMENSION_PATTERN.matcher(value);
+
+ if (!matcher.matches())
+ {
+ throw new IllegalArgumentException("Dimension must match format: {width/height} or {width}x{height}");
+ }
+
+ String x = matcher.group(1);
+ String y = matcher.group(2);
+
+ int xValue = Integer.parseInt(x);
+ int yValue = (y == null || x.equals(y)) ? xValue : Integer.parseInt(y);
+
+ return new Dimension(xValue, yValue);
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/DurationConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/DurationConverter.java
new file mode 100644
index 000000000..7685ccede
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/DurationConverter.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.time.Duration;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.TemporalUnit;
+import java.util.Objects;
+
+/**
+ * Converts a duration of time to the {@link Duration} type.
+ *
+ * @since 2.0.0
+ */
+public class DurationConverter implements ConfigResolver.Converter
+{
+ /** If a literal number is provided, parse it as this {@link TemporalUnit}. */
+ private final TemporalUnit unit;
+
+ public DurationConverter()
+ {
+ this(null);
+ }
+
+ /**
+ * @param unit The unit to use if a literal {@link Number} is provided
+ * rather than a {@link Duration} {@link String}.
+ */
+ public DurationConverter(final TemporalUnit unit)
+ {
+ this.unit = unit;
+ }
+
+ /**
+ * @param value Value to convert.
+ * @return A {@link Duration} which represents the value.
+ * @throws NullPointerException If the value is null.
+ * @throws IllegalArgumentException If the value is not a valid {@link Duration} {@link String},
+ * and isn't a valid {@link Long} value to be used with the defined {@link #unit}.
+ */
+ @Override
+ public Duration convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+
+ try
+ {
+ return Duration.parse(value);
+ }
+ catch (DateTimeParseException ex)
+ {
+ if (unit != null)
+ {
+ long number = Long.parseLong(value);
+ return Duration.of(number, unit);
+ }
+
+ throw new IllegalArgumentException("Value is not a valid duration String.");
+ }
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/EnumConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/EnumConverter.java
new file mode 100644
index 000000000..eaf944273
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/EnumConverter.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Converts an {@link Enum} {@link String} into a Java {@link Enum} object.
+ *
+ *
+ * This accepts values such as:
+ *
+ * -
+ *
java.util.concurrent.TimeUnit.NANOSECONDS
+ *
+ * -
+ *
java.time.DayOfWeek#MONDAY
+ *
+ *
+ *
+ *
+ * @since 2.0.0
+ */
+public class EnumConverter implements ConfigResolver.Converter
+{
+
+ /** Matches if a given input is an enum string. */
+ private static final Pattern ENUM_PATTERN = Pattern.compile(
+ "((?:[a-z\\d.]+)*)\\.([A-Za-z\\d]+)[#.]([A-Z\\d_]+)"
+ );
+
+ /** The enum type required by the converter. */
+ private final Class extends Enum> requiredEnumType;
+
+ /**
+ * Initialize the {@link EnumConverter} to accept any {@link Enum} constant.
+ */
+ public EnumConverter()
+ {
+ this(Enum.class);
+ }
+
+ /**
+ * Initialize the {@link EnumConverter} to accept enum constants for the specific enum type.
+ *
+ * It's possible to use this by extending this class and calling the super constructor, for example:
+ *
+ *
+ * public class TimeUnitConverter extends EnumConverter
+ * {
+ *
+ * public TimeUnitConverter()
+ * {
+ * super(TimeUnit.class);
+ * }
+ * }
+ *
+ *
+ *
+ * This allows the use of the non-qualified {@link Enum} constant name instead,
+ * and provides validation of the type of enum loaded, so an {@link IllegalArgumentException}
+ * can be thrown instead of a {@link ClassCastException}.
+ *
+ *
+ * @param requiredEnumType An enum class, such as {@link java.util.concurrent.TimeUnit},
+ * or {@link java.time.DayOfWeek}.
+ */
+ public EnumConverter(Class extends Enum> requiredEnumType)
+ {
+ this.requiredEnumType = Objects.requireNonNull(requiredEnumType);
+ }
+
+ /**
+ * @param value Value to convert.
+ * @return A {@link Enum} constant which represents the value.
+ * @throws NullPointerException If the value is null.
+ * @throws IllegalArgumentException If the value can not be mapped to an {@link Enum} constant.
+ */
+ @Override
+ public Enum convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+
+ if (requiredEnumType != null)
+ {
+ try
+ {
+ return Enum.valueOf(requiredEnumType, value);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ // Continue to check fully qualified name.
+ }
+ }
+
+ Matcher matcher = ENUM_PATTERN.matcher(value);
+
+ if (!matcher.matches())
+ {
+ throw new IllegalArgumentException("Value does not follow Java naming conventions, expecting input " +
+ "like: java.time.DayOfWeek.MONDAY");
+ }
+
+ try
+ {
+ String className = matcher.group(1) + "." + matcher.group(2);
+ Class type = Class.forName(className);
+
+ if (!type.isEnum())
+ {
+ throw new IllegalArgumentException("Value provided isn't an enumerated type.");
+ }
+
+ if (!requiredEnumType.isAssignableFrom(type))
+ {
+ throw new IllegalArgumentException("Class provided is not the required type.");
+ }
+
+ return Enum.valueOf(type, matcher.group(3));
+ }
+ catch (ClassNotFoundException ex)
+ {
+ throw new IllegalArgumentException("Class specified doesn't exist.", ex);
+ }
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/FileConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/FileConverter.java
new file mode 100644
index 000000000..f74b58512
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/FileConverter.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.io.File;
+import java.util.Objects;
+
+/**
+ * @since 2.0.0
+ */
+public class FileConverter implements ConfigResolver.Converter
+{
+ /**
+ * @param value Value to convert.
+ * @return A {@link File} which represents the value.
+ * @throws NullPointerException If the value is null.
+ */
+ @Override
+ public File convert(String value)
+ {
+ Objects.requireNonNull(value, "File name can not be null.");
+
+ if (value.isEmpty())
+ {
+ throw new IllegalArgumentException("File name can not be empty.");
+ }
+
+ return new File(value);
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/InetAddressConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/InetAddressConverter.java
new file mode 100644
index 000000000..f37561137
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/InetAddressConverter.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Objects;
+
+/**
+ * Converts values to an IP address.
+ *
+ * @since 2.0.0
+ * @see IP Address on Wikipedia
+ */
+public class InetAddressConverter implements ConfigResolver.Converter
+{
+ /**
+ * @param value Value to convert.
+ * @return An {@link InetAddress} which represents the value.
+ * @throws NullPointerException If the value is null.
+ * @throws IllegalArgumentException If a host name was specified and the IP address couldn't be obtained.
+ */
+ @Override
+ public InetAddress convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+
+ try
+ {
+ return InetAddress.getByName(value);
+ }
+ catch (UnknownHostException ex)
+ {
+ throw new IllegalArgumentException("Unable to get IP address of the named host.", ex);
+ }
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/InstantConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/InstantConverter.java
new file mode 100644
index 000000000..7a7f9f319
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/InstantConverter.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.time.Instant;
+import java.util.Objects;
+
+/**
+ * Converter to parse the time using the {@link java.time.format.DateTimeFormatter#ISO_INSTANT}
+ * format.
+ *
+ * @since 2.0.0
+ */
+public class InstantConverter implements ConfigResolver.Converter
+{
+ /**
+ * @param value Value to convert.
+ * @return An {@link Instant} which represents the value.
+ * @throws NullPointerException If the value is null.
+ * @throws DateTimeParseException If the value can't be parsed as an {@link Instant}.
+ */
+ @Override
+ public Instant convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+ return Instant.parse(value);
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/LocaleConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/LocaleConverter.java
new file mode 100644
index 000000000..d0f946507
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/LocaleConverter.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * Converts a localization pattern into a Java {@link Locale} object.
+ *
+ * @since 2.0.0
+ */
+public class LocaleConverter implements ConfigResolver.Converter
+{
+ /**
+ * @param value Value to convert.
+ * @return A {@link Locale} which represents the value.
+ * @throws NullPointerException If the value is null.
+ */
+ @Override
+ public Locale convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+ return Locale.forLanguageTag(value);
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PatternConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PatternConverter.java
new file mode 100644
index 000000000..64ed306d0
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PatternConverter.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.util.Objects;
+import java.util.regex.Pattern;
+
+/**
+ * Converts a regular expression into a Java {@link Pattern} object.
+ *
+ * @since 2.0.0
+ */
+public class PatternConverter implements ConfigResolver.Converter
+{
+ /**
+ * @param value Value to convert.
+ * @return A {@link Pattern} which represents the compiled value.
+ * @throws NullPointerException If the value is null.
+ * @throws PatternSyntaxException If the pattern is malformed.
+ */
+ @Override
+ public Pattern convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+ return Pattern.compile(value);
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PeriodConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PeriodConverter.java
new file mode 100644
index 000000000..dd295785b
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PeriodConverter.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.time.Period;
+import java.util.Objects;
+
+/**
+ * Converts a period of time to the {@link Period} type.
+ *
+ *
+ * Accepts the following:
+ *
+ * -
+ * {@link Period} {@link String} format, for example
+ *
P2Y
(2 {@link java.time.temporal.ChronoUnit#YEARS}).
+ *
+ *
+ *
+ *
+ * @since 2.0.0
+ */
+public class PeriodConverter implements ConfigResolver.Converter
+{
+ /**
+ * @param value Value to convert.
+ * @return The value represented as a{@link Period}.
+ * @throws NullPointerException If the value is null.
+ */
+ @Override
+ public Period convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+ return Period.parse(value);
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PointConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PointConverter.java
new file mode 100644
index 000000000..d5eec97e4
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/PointConverter.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.awt.Point;
+import java.util.Objects;
+import java.util.regex.Pattern;
+
+/**
+ * @since 2.0.0
+ */
+public class PointConverter implements ConfigResolver.Converter
+{
+ /** Pattern used to split the {@link Point#x} and {@link Point#y} coordinate. */
+ private static final Pattern POINT_SPLIT = Pattern.compile("\\s*,\\s*");
+
+ /**
+ * @param value The {@link String} property value to convert.
+ * @return A {@link Point} represented by the x and y coordinate of the input.
+ * @throws NullPointerException If the value is null.
+ * @throws IllegalArgumentException If the value is an invalid representation of a {@link Point}.
+ * @throws NumberFormatException If a one of coordinates can not be parsed to an {@link Integer}.
+ */
+ @Override
+ public Point convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+
+ if (value.isEmpty())
+ {
+ throw new IllegalArgumentException("A point can not be empty.");
+ }
+
+ final int lastCharIndex = value.length() - 1;
+
+ if (value.charAt(0) != '(' || value.charAt(lastCharIndex) != ')')
+ {
+ throw new IllegalArgumentException("Point coordinates must be enclosed in brackets.");
+ }
+
+ final String coordinates = value.substring(1, lastCharIndex);
+ final String[] xy = POINT_SPLIT.split(coordinates);
+
+ if (xy.length != 2)
+ {
+ throw new IllegalArgumentException("Point must have an x coordinate, and y coordinate only, " +
+ "expecting the following format: (40, 200)");
+ }
+
+ final int x = Integer.parseInt(xy[0]);
+ final int y = Integer.parseInt(xy[1]);
+ return new Point(x, y);
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UriConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UriConverter.java
new file mode 100644
index 000000000..d05e69117
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UriConverter.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Objects;
+
+/**
+ * Converts a {@link String} to a Java {@link URI} instance.
+ *
+ * @since 2.0.0
+ */
+public class UriConverter implements ConfigResolver.Converter
+{
+ /**
+ * @param value Value to convert.
+ * @return A {@link URI} which represents the value.
+ * @throws NullPointerException If the value is null.
+ * @throws IllegalArgumentException If the value is not a valid {@link URI}.
+ */
+ @Override
+ public URI convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+
+ if (value.isEmpty())
+ {
+ throw new IllegalArgumentException("Value must not be empty.");
+ }
+
+ try
+ {
+ return new URI(value);
+ }
+ catch (URISyntaxException ex)
+ {
+ throw new IllegalArgumentException("Value must be a valid URI.", ex);
+ }
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UrlConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UrlConverter.java
new file mode 100644
index 000000000..b18889df0
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UrlConverter.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Converts url to a Java {@link URL} instance.
+ * This also can be extended to support filtering of URL components
+ * such as {@link URL#getProtocol()} for more specialized use or validation.
+ *
+ * @since 2.0.0
+ */
+public class UrlConverter implements ConfigResolver.Converter
+{
+
+ /** A list of allowed protocols, or null to disable this. */
+ private final Set allowedProtocols;
+
+ public UrlConverter()
+ {
+ this(null);
+ }
+
+ /**
+ * @param allowedProtocols An array of allowed protocols, or null to disable checking.
+ */
+ public UrlConverter(Collection allowedProtocols)
+ {
+ if (allowedProtocols != null)
+ {
+ this.allowedProtocols = allowedProtocols.stream()
+ .map(String::toLowerCase)
+ .collect(Collectors.toSet());
+ }
+ else
+ {
+ this.allowedProtocols = null;
+ }
+ }
+
+ /**
+ * @param value Value to convert.
+ * @return A {@link URL} which represents the value.
+ * @throws NullPointerException If the value is null.
+ * @throws IllegalArgumentException If the value is not a valid {@link URL}.
+ */
+ @Override
+ public URL convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+
+ try
+ {
+ URL url = new URL(value);
+
+ if (allowedProtocols != null)
+ {
+ String protocol = url.getProtocol().toLowerCase();
+
+ if (!allowedProtocols.contains(protocol))
+ {
+ throw new IllegalArgumentException("URL must specify one of the following protocols: " +
+ String.join(", ", allowedProtocols));
+ }
+ }
+
+ return url;
+ }
+ catch (MalformedURLException ex)
+ {
+ throw new IllegalArgumentException("Value is not a valid URL, or uses an unknown protocol.", ex);
+ }
+ }
+}
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UuidConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UuidConverter.java
new file mode 100644
index 000000000..1f0a99332
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/UuidConverter.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.core.impl.config.converter;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * Convert a value to a {@link UUID}.
+ *
+ * @since 2.0.0
+ */
+public class UuidConverter implements ConfigResolver.Converter
+{
+ /**
+ * @param value Value to convert.
+ * @return A {@link UUID} which represents the value.
+ * @throws NullPointerException If the value is null.
+ * @throws IllegalArgumentException If the value is not a valid {@link UUID}.
+ */
+ @Override
+ public UUID convert(String value)
+ {
+ Objects.requireNonNull(value, "Value must not be null.");
+ return UUID.fromString(value);
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/CharacterConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/CharacterConverterTest.java
new file mode 100644
index 000000000..43d2ce2db
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/CharacterConverterTest.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.CharacterConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @since 2.0.0
+ */
+public class CharacterConverterTest
+{
+ private CharacterConverter converter;
+
+ @Before
+ public void before()
+ {
+ converter = new CharacterConverter();
+ }
+
+ @Test
+ public void testConvertingSingleCharacterString()
+ {
+ final char expected = 'a';
+ final char actual = converter.convert("a");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingSingleCharacterSpace()
+ {
+ final char expected = ' ';
+ final char actual = converter.convert(" ");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingSingleNumber()
+ {
+ final char expected = '1';
+ final char actual = converter.convert("1");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertSymbol()
+ {
+ final char expected = '$';
+ final char actual = converter.convert("$");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * If a hexadecimal value is provided, we'll convert it to a
+ * a character if possible.
+ */
+ @Test
+ public void testConvertHex()
+ {
+ final char expected = 'A';
+ final char actual = converter.convert("0x41");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testEmptyString()
+ {
+ converter.convert("");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testHelloWorld()
+ {
+ converter.convert("Hello, world!");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testWhiteSpace()
+ {
+ converter.convert(" ");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testAa()
+ {
+ converter.convert("AA");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void test11()
+ {
+ converter.convert("11");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void test00()
+ {
+ converter.convert("00");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testXx()
+ {
+ converter.convert("XX");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/ColorConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/ColorConverterTest.java
new file mode 100644
index 000000000..24417ba6f
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/ColorConverterTest.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.ColorConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.awt.*;
+
+/**
+ * @since 2.0.0
+ */
+public class ColorConverterTest
+{
+ private ColorConverter converter;
+
+ @Before
+ public void before()
+ {
+ converter = new ColorConverter();
+ }
+
+ @Test
+ public void testConvertingPattern()
+ {
+ final Color expected = Color.BLACK;
+ final Color actual = converter.convert("#000000");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingPatternWithAlpha()
+ {
+ final Color expected = Color.LIGHT_GRAY;
+ final Color actual = converter.convert("#C0C0C0FF");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingPattern3Digit()
+ {
+ final Color expected = Color.WHITE;
+ final Color actual = converter.convert("#FFF");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingPattern4Digit()
+ {
+ final Color expected = Color.YELLOW;
+ final Color actual = converter.convert("#FF0F");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingLiteralHex()
+ {
+ final Color expected = Color.BLUE;
+ final Color actual = converter.convert("0x0000FF");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingColorName()
+ {
+ final Color expected = Color.WHITE;
+ final Color actual = converter.convert("white");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingColorNameCaps()
+ {
+ final Color expected = Color.LIGHT_GRAY;
+ final Color actual = converter.convert("LIGHTGRAY");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void testInvalidNumber3()
+ {
+ converter.convert("#FFZ");
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void testInvalidNumber4()
+ {
+ converter.convert("#FFFY");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testColorBlank()
+ {
+ converter.convert("#");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testColorInvalidLength()
+ {
+ converter.convert("#F");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/DimensionConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/DimensionConverterTest.java
new file mode 100644
index 000000000..bf78c4c1f
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/DimensionConverterTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.DimensionConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.awt.*;
+
+/**
+ * @since 2.0.0
+ */
+public class DimensionConverterTest
+{
+ private DimensionConverter converter;
+
+ @Before
+ public void before()
+ {
+ converter = new DimensionConverter();
+ }
+
+ @Test
+ public void testConvertingDimension()
+ {
+ final Dimension expected = new Dimension(1920, 1080);
+ final Dimension actual = converter.convert("1920x1080");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingSquare()
+ {
+ final Dimension expected = new Dimension(512, 512);
+ final Dimension actual = converter.convert("512");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidDimensions()
+ {
+ converter.convert("512n512");
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void testInvalidNumberFormatException()
+ {
+ converter.convert("3000000000x100");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNegativeDimension()
+ {
+ converter.convert("-512x512");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/DurationConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/DurationConverterTest.java
new file mode 100644
index 000000000..3f7773150
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/DurationConverterTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.DurationConverter;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+
+/**
+ * @since 2.0.0
+ */
+public class DurationConverterTest
+{
+ @Test
+ public void testConvertingDurationString()
+ {
+ DurationConverter converter = new DurationConverter();
+
+ final Duration expected = Duration.ofMinutes(3064);
+ final Duration actual = converter.convert("P2DT3H4M");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingCustomTemporal()
+ {
+ DurationConverter converter = new DurationConverter(ChronoUnit.SECONDS);
+
+ final Duration expected = Duration.ofSeconds(4);
+ final Duration actual = converter.convert("4");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConvertingLocalizedNumber()
+ {
+ DurationConverter converter = new DurationConverter();
+ converter.convert("1,000");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConvertingWords()
+ {
+ DurationConverter converter = new DurationConverter();
+ converter.convert("Hello, world!");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/EnumConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/EnumConverterTest.java
new file mode 100644
index 000000000..c2bcacb69
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/EnumConverterTest.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.EnumConverter;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.time.DayOfWeek;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @since 2.0.0
+ */
+public class EnumConverterTest
+{
+ @Test
+ public void testConvertTimeUnit()
+ {
+ EnumConverter converter = new EnumConverter();
+
+ final TimeUnit expected = TimeUnit.NANOSECONDS;
+ final Enum actual = converter.convert("java.util.concurrent.TimeUnit.NANOSECONDS");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertDayOfWeek()
+ {
+ EnumConverter converter = new EnumConverter();
+
+ final DayOfWeek expected = DayOfWeek.MONDAY;
+ final Enum actual = converter.convert("java.time.DayOfWeek#MONDAY");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * When the {@link EnumConverter} is constructed with a type,
+ * it's permissible to only pass the {@link Enum} constant
+ * name without the package or class name.
+ */
+ @Test
+ public void testEnumNameOnlyFromTypedInstance()
+ {
+ EnumConverter converter = new EnumConverter(DayOfWeek.class);
+
+ final DayOfWeek expected = DayOfWeek.MONDAY;
+ final Enum actual = converter.convert("MONDAY");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConvertWroteEnumType()
+ {
+ EnumConverter converter = new EnumConverter(TimeUnit.class);
+ converter.convert("java.time.DayOfWeek#MONDAY");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBrokenNamingConvention()
+ {
+ EnumConverter converter = new EnumConverter();
+ converter.convert("JAVA-TIME-DAYOFWEEK#MONDAY");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNonEnumClasses()
+ {
+ EnumConverter converter = new EnumConverter();
+ converter.convert("java.lang.String#MONDAY");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNonExistingClasses()
+ {
+ EnumConverter converter = new EnumConverter();
+ converter.convert("java.lang.does.not.exist#MONDAY");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/FileConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/FileConverterTest.java
new file mode 100644
index 000000000..accd33572
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/FileConverterTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.FileConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+/**
+ * @since 2.0.0
+ */
+public class FileConverterTest
+{
+ private FileConverter converter;
+
+ @Before
+ public void before()
+ {
+ converter = new FileConverter();
+ }
+
+ @Test
+ public void testConvertingFile()
+ {
+ final File expected = new File("/");
+ final File actual = converter.convert("/");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testConvertingNull()
+ {
+ converter.convert(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConvertingEmpty()
+ {
+ converter.convert("");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/InetAddressConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/InetAddressConverterTest.java
new file mode 100644
index 000000000..6a00690e1
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/InetAddressConverterTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.InetAddressConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * @since 2.0.0
+ */
+public class InetAddressConverterTest
+{
+ private InetAddressConverter converter;
+
+ @Before
+ public void before()
+ {
+ converter = new InetAddressConverter();
+ }
+
+ @Test
+ public void testConvertingIpv4() throws UnknownHostException
+ {
+ final InetAddress expected = InetAddress.getByName("192.168.0.1");
+ final InetAddress actual = converter.convert("192.168.0.1");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingIpv6() throws UnknownHostException
+ {
+ final InetAddress expected = InetAddress.getByName("2001:db8:0:1234:0:567:8:1");
+ final InetAddress actual = converter.convert("2001:db8:0:1234:0:567:8:1");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingLocalhost() throws UnknownHostException
+ {
+ final InetAddress expected = InetAddress.getByName("127.0.0.1");
+ final InetAddress actual = converter.convert("localhost");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testText()
+ {
+ converter.convert("Hello, world!");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidIp()
+ {
+ converter.convert("512.512.512.512");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/InstantConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/InstantConverterTest.java
new file mode 100644
index 000000000..2f3831cac
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/InstantConverterTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.InstantConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.time.Instant;
+import java.time.format.DateTimeParseException;
+
+/**
+ * @since 2.0.0
+ */
+public class InstantConverterTest
+{
+ private InstantConverter converter;
+
+ @Before
+ public void before()
+ {
+ converter = new InstantConverter();
+ }
+
+ @Test
+ public void testConvertingInstantString()
+ {
+ final Instant expected = Instant.ofEpochMilli(1196676930000L);
+ final Instant actual = converter.convert("2007-12-03T10:15:30.00Z");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = DateTimeParseException.class)
+ public void testText()
+ {
+ converter.convert("Hello, world!");
+ }
+
+ @Test(expected = DateTimeParseException.class)
+ public void testLocalizedNumber()
+ {
+ converter.convert("200,000,000,000");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/LocaleConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/LocaleConverterTest.java
new file mode 100644
index 000000000..4bad0c119
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/LocaleConverterTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.LocaleConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Locale;
+
+/**
+ * @since 2.0.0
+ */
+public class LocaleConverterTest
+{
+ private LocaleConverter converter;
+
+ @Before
+ public void before()
+ {
+ converter = new LocaleConverter();
+ }
+
+ @Test
+ public void testConvertStandardLocale()
+ {
+ final Locale expected = Locale.ENGLISH;
+ final Locale actual = converter.convert("en");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertCustomLocale()
+ {
+ final Locale expected = Locale.forLanguageTag("en-owo");
+ final Locale actual = converter.convert("en-owo");
+
+ Assert.assertEquals(expected, actual);
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PatternConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PatternConverterTest.java
new file mode 100644
index 000000000..ff3c1f605
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PatternConverterTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.PatternConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @since 2.0.0
+ */
+public class PatternConverterTest
+{
+ private PatternConverter converter;
+
+ @Before
+ public void before()
+ {
+ converter = new PatternConverter();
+ }
+
+ @Test
+ public void testConvertingPattern()
+ {
+ final String expected = "(?i)Ow.+O";
+ final String actual = converter.convert("(?i)Ow.+O").toString();
+
+ Assert.assertEquals(expected, actual);
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PeriodConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PeriodConverterTest.java
new file mode 100644
index 000000000..48022e027
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PeriodConverterTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.PeriodConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.time.Period;
+import java.time.format.DateTimeParseException;
+
+/**
+ * @since 2.0.0
+ */
+public class PeriodConverterTest
+{
+ private PeriodConverter converter;
+
+ @Before
+ public void before()
+ {
+ converter = new PeriodConverter();
+ }
+
+ @Test
+ public void testConvertingDurationString()
+ {
+ final Period expected = Period.parse("P1Y2M3D");
+ final Period actual = converter.convert("P1Y2M3D");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = DateTimeParseException.class)
+ public void testConvertingLocalizedNumber()
+ {
+ converter.convert("1,000");
+ }
+
+ @Test(expected = DateTimeParseException.class)
+ public void testLetter()
+ {
+ converter.convert("Z");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PointConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PointConverterTest.java
new file mode 100644
index 000000000..603c8ede8
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/PointConverterTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.PointConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.awt.Point;
+
+/**
+ * @since 2.0.0
+ */
+public class PointConverterTest
+{
+ private PointConverter converter;
+
+ @Before
+ public void before()
+ {
+ converter = new PointConverter();
+ }
+
+ @Test
+ public void testConvertingPoint()
+ {
+ final Point expected = new Point(100, 200);
+ final Point actual = converter.convert("(100, 200)");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingNoSpace()
+ {
+ final Point expected = new Point(100, 200);
+ final Point actual = converter.convert("(100,200)");
+
+ Assert.assertEquals(expected, actual);
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UriConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UriConverterTest.java
new file mode 100644
index 000000000..a1f453839
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UriConverterTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.UriConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * @since 2.0.0
+ */
+public class UriConverterTest
+{
+ private UriConverter converter;
+
+ @Before
+ public void before() {
+ converter = new UriConverter();
+ }
+
+ @Test
+ public void testUrl() throws URISyntaxException
+ {
+ final URI expected = new URI("https://apache.org/");
+ final URI actual = converter.convert("https://apache.org/");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testMailto() throws URISyntaxException
+ {
+ final URI expected = new URI("mailto:java-net@java.sun.com");
+ final URI actual = converter.convert("mailto:java-net@java.sun.com");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testSteamUrl() throws URISyntaxException
+ {
+ final URI expected = new URI("steam://connect/192.0.2.1:27015");
+ final URI actual = converter.convert("steam://connect/192.0.2.1:27015");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testEmpty()
+ {
+ converter.convert("");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testWhitespace()
+ {
+ converter.convert(" ");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UrlConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UrlConverterTest.java
new file mode 100644
index 000000000..b82e5d6d0
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UrlConverterTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.UrlConverter;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @since 2.0.0
+ */
+public class UrlConverterTest
+{
+ @Test
+ public void testConvertingNormalUrl() throws MalformedURLException
+ {
+ UrlConverter converter = new UrlConverter();
+
+ final URL expected = new URL("https://gitlab.com/");
+ final URL actual = converter.convert("https://gitlab.com/");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testFilteredProtocolPass() throws MalformedURLException, URISyntaxException
+ {
+ List protocols = new ArrayList<>();
+ protocols.add("http");
+ protocols.add("https");
+
+ UrlConverter converter = new UrlConverter(protocols);
+
+ final URI expected = new URL("https://gitlab.com/").toURI();
+ final URI actual = converter.convert("https://gitlab.com/").toURI();
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBadProtocol()
+ {
+ List protocols = new ArrayList<>();
+ protocols.add("https");
+
+ UrlConverter converter = new UrlConverter(protocols);
+ converter.convert("http://gitlab.com/");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidProtocol()
+ {
+ UrlConverter converter = new UrlConverter();
+ converter.convert(":invalid.protocol");
+ }
+}
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UuidConverterTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UuidConverterTest.java
new file mode 100644
index 000000000..0ca92cab6
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/config/converter/UuidConverterTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.deltaspike.test.core.impl.config.converter;
+
+import org.apache.deltaspike.core.impl.config.converter.UuidConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.UUID;
+
+/**
+ * @since 2.0.0
+ */
+public class UuidConverterTest
+{
+ private UuidConverter converter;
+
+ @Before
+ public void before() {
+ converter = new UuidConverter();
+ }
+
+ @Test
+ public void testConvertingPattern()
+ {
+ final UUID expected = UUID.fromString("cebfb280-a7b0-4561-bc75-f71a1a08f66b");
+ final UUID actual = converter.convert("cebfb280-a7b0-4561-bc75-f71a1a08f66b");
+
+ Assert.assertEquals(expected, actual);
+ }
+}
diff --git a/documentation/src/main/asciidoc/configuration.adoc b/documentation/src/main/asciidoc/configuration.adoc
index 6ccd2d0e4..89bb2d05e 100644
--- a/documentation/src/main/asciidoc/configuration.adoc
+++ b/documentation/src/main/asciidoc/configuration.adoc
@@ -203,7 +203,33 @@ Integer dbPort = ConfigResolver
==== Supported types
-The types supported out of the box include: String, Integer, Long, Float, Double, Boolean, Class.
+The table shows the types supported by Deltaspike already:
+
+|===
+| Type | Requires Producer
+| String | No
+| Integer | No
+| Long | No
+| Float | No
+| Double | No
+| Boolean | No
+| Class | No
+| Character | `CharacterConverter`
+| Color | `ColorConverter`
+| Dimensions | `DimensionsConverter`
+| Duration | `DurationConverter`
+| Enum | `EnumConverter`
+| File | `FileConverter`
+| InetAddress | `InetAddressConverter`
+| Instant | `InstantConverter`
+| Locale | `LocaleConverter`
+| Period | `PeriodConverter`
+| Point | `PointConverter`
+| URI | `URIConverter`
+| URL | `URLConverter`
+| UUID | `UUIDConverter`
+|===
+
Custom types can be supported by providing an implementation of the `ConfigResolver.Converter` interface.
[source,java]