diff --git a/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java b/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java
index e3bd53819..1d1a4d51a 100644
--- a/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java
+++ b/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java
@@ -17,10 +17,14 @@
package org.apache.commons.beanutils2;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Point;
import java.io.File;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.net.InetAddress;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
@@ -40,7 +44,9 @@
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Collection;
+import java.util.Locale;
import java.util.UUID;
+import java.util.regex.Pattern;
import org.apache.commons.beanutils2.converters.ArrayConverter;
import org.apache.commons.beanutils2.converters.BigDecimalConverter;
@@ -50,23 +56,29 @@
import org.apache.commons.beanutils2.converters.CalendarConverter;
import org.apache.commons.beanutils2.converters.CharacterConverter;
import org.apache.commons.beanutils2.converters.ClassConverter;
+import org.apache.commons.beanutils2.converters.ColorConverter;
import org.apache.commons.beanutils2.converters.ConverterFacade;
import org.apache.commons.beanutils2.converters.DateConverter;
+import org.apache.commons.beanutils2.converters.DimensionConverter;
import org.apache.commons.beanutils2.converters.DoubleConverter;
import org.apache.commons.beanutils2.converters.DurationConverter;
import org.apache.commons.beanutils2.converters.EnumConverter;
import org.apache.commons.beanutils2.converters.FileConverter;
import org.apache.commons.beanutils2.converters.FloatConverter;
+import org.apache.commons.beanutils2.converters.InetAddressConverter;
import org.apache.commons.beanutils2.converters.IntegerConverter;
import org.apache.commons.beanutils2.converters.LocalDateConverter;
import org.apache.commons.beanutils2.converters.LocalDateTimeConverter;
+import org.apache.commons.beanutils2.converters.LocaleConverter;
import org.apache.commons.beanutils2.converters.LocalTimeConverter;
import org.apache.commons.beanutils2.converters.LongConverter;
import org.apache.commons.beanutils2.converters.MonthDayConverter;
import org.apache.commons.beanutils2.converters.OffsetDateTimeConverter;
import org.apache.commons.beanutils2.converters.OffsetTimeConverter;
import org.apache.commons.beanutils2.converters.PathConverter;
+import org.apache.commons.beanutils2.converters.PatternConverter;
import org.apache.commons.beanutils2.converters.PeriodConverter;
+import org.apache.commons.beanutils2.converters.PointConverter;
import org.apache.commons.beanutils2.converters.ShortConverter;
import org.apache.commons.beanutils2.converters.StringConverter;
import org.apache.commons.beanutils2.converters.URIConverter;
@@ -97,6 +109,8 @@
*
byte and java.lang.Byte (default to zero)
* char and java.lang.Character (default to a space)
* java.lang.Class (no default value)
+ * java.awt.Color (no default value)
+ * java.awt.Dimension (no default value)
* double and java.lang.Double (default to zero)
* float and java.lang.Float (default to zero)
* int and java.lang.Integer (default to zero)
@@ -105,6 +119,8 @@
* java.lang.String (default to null)
* java.lang.Enum (default to null)
* java.io.File (no default value)
+ * java.net.InetAddress (no default value)
+ * java.util.Locale (no default value)
* java.nio.file.Path (no default value)
* java.net.URL (no default value)
* java.net.URI (no default value)
@@ -120,7 +136,9 @@
* java.time.ZonedDateTime (no default value)
* java.time.Duration (no default value)
* java.time.MonthDay (no default value)
+ * java.util.regex.Pattern (no default value)
* java.time.Period (no default value)
+ * java.awt.Point (no default value)
* java.time.Year (no default value)
* java.time.YearMonth (no default value)
* java.time.ZoneId (no default value)
@@ -541,10 +559,13 @@ private void registerArrays(final boolean throwException, final int defaultArray
// Other
registerArrayConverter(Class.class, new ClassConverter(), throwException, defaultArraySize);
+ registerArrayConverter(Color.class, new ColorConverter(), throwException, defaultArraySize);
registerArrayConverter(Enum.class, new EnumConverter(), throwException, defaultArraySize);
registerArrayConverter(java.util.Date.class, new DateConverter(), throwException, defaultArraySize);
registerArrayConverter(Calendar.class, new CalendarConverter(), throwException, defaultArraySize);
+ registerArrayConverter(Dimension.class, new DimensionConverter(), throwException, defaultArraySize);
registerArrayConverter(File.class, new FileConverter(), throwException, defaultArraySize);
+ registerArrayConverter(InetAddress.class, new InetAddressConverter(), throwException, defaultArraySize);
registerArrayConverter(Path.class, new PathConverter(), throwException, defaultArraySize);
registerArrayConverter(java.sql.Date.class, new SqlDateConverter(), throwException, defaultArraySize);
registerArrayConverter(java.sql.Time.class, new SqlTimeConverter(), throwException, defaultArraySize);
@@ -555,12 +576,15 @@ private void registerArrays(final boolean throwException, final int defaultArray
registerArrayConverter(LocalDate.class, new LocalDateConverter(), throwException, defaultArraySize);
registerArrayConverter(LocalDateTime.class, new LocalDateTimeConverter(), throwException, defaultArraySize);
registerArrayConverter(LocalTime.class, new LocalTimeConverter(), throwException, defaultArraySize);
+ registerArrayConverter(Locale.class, new LocaleConverter(), throwException, defaultArraySize);
registerArrayConverter(OffsetDateTime.class, new OffsetDateTimeConverter(),throwException, defaultArraySize);
registerArrayConverter(OffsetTime.class, new OffsetTimeConverter(), throwException, defaultArraySize);
registerArrayConverter(ZonedDateTime.class, new ZonedDateTimeConverter(), throwException, defaultArraySize);
registerArrayConverter(Duration.class, new DurationConverter(), throwException, defaultArraySize);
registerArrayConverter(MonthDay.class, new MonthDayConverter(), throwException, defaultArraySize);
+ registerArrayConverter(Pattern.class, new PatternConverter(), throwException, defaultArraySize);
registerArrayConverter(Period.class, new PeriodConverter(), throwException, defaultArraySize);
+ registerArrayConverter(Point.class, new PointConverter(), throwException, defaultArraySize);
registerArrayConverter(Year.class, new YearConverter(), throwException, defaultArraySize);
registerArrayConverter(YearMonth.class, new YearMonthConverter(), throwException, defaultArraySize);
registerArrayConverter(ZoneId.class, new ZoneIdConverter(), throwException, defaultArraySize);
@@ -606,10 +630,13 @@ private void registerArrays(final boolean throwException, final int defaultArray
private void registerOther(final boolean throwException) {
// @formatter:off
register(Class.class, throwException ? new ClassConverter<>() : new ClassConverter<>(null));
+ register(Color.class, throwException ? new ColorConverter() : new ColorConverter(null));
register(Enum.class, throwException ? new EnumConverter() : new EnumConverter(null));
register(java.util.Date.class, throwException ? new DateConverter() : new DateConverter(null));
+ register(Dimension.class, throwException ? new DimensionConverter() : new DimensionConverter(null));
register(Calendar.class, throwException ? new CalendarConverter() : new CalendarConverter(null));
register(File.class, throwException ? new FileConverter() : new FileConverter(null));
+ register(InetAddress.class, throwException ? new InetAddressConverter() : new InetAddressConverter(null));
register(Path.class, throwException ? new PathConverter() : new PathConverter(null));
register(java.sql.Date.class, throwException ? new SqlDateConverter() : new SqlDateConverter(null));
register(java.sql.Time.class, throwException ? new SqlTimeConverter() : new SqlTimeConverter(null));
@@ -620,12 +647,15 @@ private void registerOther(final boolean throwException) {
register(LocalDate.class, throwException ? new LocalDateConverter() : new LocalDateConverter(null));
register(LocalDateTime.class, throwException ? new LocalDateTimeConverter() : new LocalDateTimeConverter(null));
register(LocalTime.class, throwException ? new LocalTimeConverter() : new LocalTimeConverter(null));
+ register(Locale.class, throwException ? new LocaleConverter() : new LocaleConverter(null));
register(OffsetDateTime.class, throwException ? new OffsetDateTimeConverter() : new OffsetDateTimeConverter(null));
register(OffsetTime.class, throwException ? new OffsetTimeConverter() : new OffsetTimeConverter(null));
register(ZonedDateTime.class, throwException ? new ZonedDateTimeConverter() : new ZonedDateTimeConverter(null));
register(Duration.class, throwException ? new DurationConverter() : new DurationConverter(null));
register(MonthDay.class, throwException ? new MonthDayConverter() : new MonthDayConverter(null));
+ register(Pattern.class, throwException ? new PatternConverter() : new PatternConverter(null));
register(Period.class, throwException ? new PeriodConverter() : new PeriodConverter(null));
+ register(Point.class, throwException ? new PointConverter() : new PointConverter(null));
register(Year.class, throwException ? new YearConverter() : new YearConverter(null));
register(YearMonth.class, throwException ? new YearMonthConverter() : new YearMonthConverter(null));
register(ZoneId.class, throwException ? new ZoneIdConverter() : new ZoneIdConverter(null));
diff --git a/src/main/java/org/apache/commons/beanutils2/converters/ColorConverter.java b/src/main/java/org/apache/commons/beanutils2/converters/ColorConverter.java
new file mode 100644
index 000000000..20d94bb9f
--- /dev/null
+++ b/src/main/java/org/apache/commons/beanutils2/converters/ColorConverter.java
@@ -0,0 +1,262 @@
+/*
+ * 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.commons.beanutils2.converters;
+
+import java.awt.Color;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Converts a configuration property into a Java {@link Color} object.
+ *
+ *
+ * Compatible with web color formats supported by browsers with CSS, such as:
+ *
+ *
+ *
+ * - #RGB
+ * - #RGBA
+ * - #RRGGBBAA
+ *
+ *
+ *
+ * This converter will use the web based hexadecimal interpretations if the value is prefixed with
+ * {@link #HEX_COLOR_PREFIX}.
+ *
+ * If using a literal number, or {@link Color#decode(String)} is desired, you must prefix your value with
+ * 0x
instead of {@link #HEX_COLOR_PREFIX}.
+ *
+ *
+ * @since 2.0.0
+ */
+public class ColorConverter extends AbstractConverter {
+
+ /** Web based hexadecimal color must be prefixed with this. */
+ private static final String HEX_COLOR_PREFIX = "#";
+
+ /** A regular expression matching the output of {@link Color#toString()} and similar outputs. */
+ 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})\\]?$");
+
+ /**
+ * Construct a {@link Color} Converter that throws a {@code ConversionException} if an error occurs.
+ */
+ public ColorConverter() {
+ super();
+ }
+
+ /**
+ * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a
+ * conversion error occurs.
+ *
+ * @param defaultValue The default value to be returned if the value to be converted is missing or an error occurs
+ * converting the value.
+ */
+ public ColorConverter(final Color defaultValue) {
+ super(defaultValue);
+ }
+
+ /**
+ * Gets the default type this {@code Converter} handles.
+ *
+ * @return The default type this {@code Converter} handles.
+ * @since 2.0.0
+ */
+ @Override
+ protected Class getDefaultType() {
+ return Color.class;
+ }
+
+ /**
+ * Converts the configuration value to a Java {@link Color} object, by reading the hexadecimal {@link String} and
+ * converting each component.
+ *
+ *
+ * This can also interpret raw color names based on the standard colors defined in Java, such as the following:
+ *
+ *
+ *
+ * - {@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}
+ *
+ *
+ * We avoid the use of {@link Color#decode(String)} for hexadecimal {@link String}s starting with
+ * {@link #HEX_COLOR_PREFIX} as it doesn't provide the desired result. The {@link Color#decode(String)} method uses
+ * {@link Integer#decode(String)} to convert the input to a number, so #FFF
gets interpreted
+ * unexpectedly, as it's literally converted to the number 0xFFF
, rather than the color,
+ * #FFFFFF
which it is short hand for. It also doesn't work for #FFFFFFFF
due to it being
+ * unable to parse as an {@link Integer}. If this is desired, then this method falls back to using
+ * {@link Color#decode(String)}, so for literal hexadecimal values you prefix it with 0x
instead of
+ * {@link #HEX_COLOR_PREFIX}.
+ *
+ * @param value The String property value to convert.
+ * @return A {@link Color} which represents the compiled configuration property.
+ * @throws NullPointerException If the value is null.
+ * @throws NumberFormatException If an invalid number is provided.
+ */
+ @Override
+ protected T convertToType(final Class type, final Object value) throws Throwable {
+ if (Color.class.isAssignableFrom(type)) {
+ final String stringValue = toString(value);
+
+ switch (toLowerCase(stringValue)) {
+ case "black":
+ return type.cast(Color.BLACK);
+ case "blue":
+ return type.cast(Color.BLUE);
+ case "cyan":
+ return type.cast(Color.CYAN);
+ case "darkgray":
+ case "darkgrey":
+ case "dark_gray":
+ case "dark_grey":
+ return type.cast(Color.DARK_GRAY);
+ case "gray":
+ case "grey":
+ return type.cast(Color.GRAY);
+ case "green":
+ return type.cast(Color.GREEN);
+ case "lightgray":
+ case "lightgrey":
+ case "light_gray":
+ case "light_grey":
+ return type.cast(Color.LIGHT_GRAY);
+ case "magenta":
+ return type.cast(Color.MAGENTA);
+ case "orange":
+ return type.cast(Color.ORANGE);
+ case "pink":
+ return type.cast(Color.PINK);
+ case "red":
+ return type.cast(Color.RED);
+ case "white":
+ return type.cast(Color.WHITE);
+ case "yellow":
+ return type.cast(Color.YELLOW);
+ default:
+ // Do nothing.
+ }
+
+ if (stringValue.startsWith(HEX_COLOR_PREFIX)) {
+ return type.cast(parseWebColor(stringValue));
+ }
+
+ if (stringValue.contains(",")) {
+ return type.cast(parseToStringColor(stringValue));
+ }
+
+ return type.cast(Color.decode(stringValue));
+ }
+
+ throw conversionException(type, value);
+ }
+
+ /**
+ * Parses the Color based on how 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 matches 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}; not a {@link Number} or {@link String} for
+ * {@link Color#decode(String)} as it is not capable of supporting a color alpha channel due to the
+ * limited range of an {@link Integer}.
+ *
+ * @param value The web friendly hexadecimal {@link String}.
+ * @return The Java friendly {@link Color} this color represents.
+ * @throws NumberFormatException If the hexadecimal input contains non parsable characters.
+ */
+ private 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("Invalid hexadecimal color provided, if literal value decoding " +
+ "is required, specify 0x instead of #, otherwise expecting 3, 4, 6, or 8 characters only.");
+ }
+ }
+}
diff --git a/src/main/java/org/apache/commons/beanutils2/converters/DimensionConverter.java b/src/main/java/org/apache/commons/beanutils2/converters/DimensionConverter.java
new file mode 100644
index 000000000..a5e9341da
--- /dev/null
+++ b/src/main/java/org/apache/commons/beanutils2/converters/DimensionConverter.java
@@ -0,0 +1,106 @@
+/*
+ * 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.commons.beanutils2.converters;
+
+import java.awt.Dimension;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Converting configuration 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 {@link Integer} values.
+ *
+ * @since 2.0.0
+ */
+public class DimensionConverter extends AbstractConverter {
+
+ /** Pattern used to validate and tokenizer the {@link String}. */
+ private static final Pattern DIMENSION_PATTERN = Pattern.compile("(\\d+)(?:x(\\d+))?");
+
+ /**
+ * Construct a {@link Dimension} Converter that throws a {@code ConversionException} if an error
+ * occurs.
+ */
+ public DimensionConverter() {
+ super();
+ }
+
+ /**
+ * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a
+ * conversion error occurs.
+ *
+ * @param defaultValue The default value to be returned if the value to be converted is missing or an error occurs
+ * converting the value.
+ */
+ public DimensionConverter(final Dimension defaultValue) {
+ super(defaultValue);
+ }
+
+ /**
+ * Gets the default type this {@code Converter} handles.
+ *
+ * @return The default type this {@code Converter} handles.
+ * @since 2.0.0
+ */
+ @Override
+ protected Class getDefaultType() {
+ return Dimension.class;
+ }
+
+ /**
+ * Converts the specified input object into an output object of the specified type.
+ *
+ * @param value The String property value to convert.
+ * @return A {@link Dimension} which represents the configuration property 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
+ protected T convertToType(final Class type, final Object value) throws Throwable {
+ if (Dimension.class.isAssignableFrom(type)) {
+ final String stringValue = toString(value);
+
+ if (stringValue.isEmpty()) {
+ throw new IllegalArgumentException("Dimensions can not be empty.");
+ }
+
+ Matcher matcher = DIMENSION_PATTERN.matcher(stringValue);
+
+ if (!matcher.matches()) {
+ throw new IllegalArgumentException(
+ "Dimension doesn't 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 type.cast(new Dimension(xValue, yValue));
+ }
+
+ throw conversionException(type, value);
+ }
+}
diff --git a/src/main/java/org/apache/commons/beanutils2/converters/InetAddressConverter.java b/src/main/java/org/apache/commons/beanutils2/converters/InetAddressConverter.java
new file mode 100644
index 000000000..a8f7464b9
--- /dev/null
+++ b/src/main/java/org/apache/commons/beanutils2/converters/InetAddressConverter.java
@@ -0,0 +1,84 @@
+/*
+ * 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.commons.beanutils2.converters;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Converts configuration property values to an IP address.
+ *
+ * @since 2.0.0
+ * @see IP Address on Wikipedia
+ */
+public class InetAddressConverter extends AbstractConverter {
+
+ /**
+ * Construct a {@link InetAddress} Converter that throws a {@code ConversionException} if an error
+ * occurs.
+ */
+ public InetAddressConverter() {
+ super();
+ }
+
+ /**
+ * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a
+ * conversion error occurs.
+ *
+ * @param defaultValue The default value to be returned if the value to be converted is missing or an error occurs
+ * converting the value.
+ */
+ public InetAddressConverter(final InetAddress defaultValue) {
+ super(defaultValue);
+ }
+
+ /**
+ * Gets the default type this {@code Converter} handles.
+ *
+ * @return The default type this {@code Converter} handles.
+ * @since 2.0.0
+ */
+ @Override
+ protected Class getDefaultType() {
+ return InetAddress.class;
+ }
+
+ /**
+ * Converts the specified input object into an output object of the specified type.
+ *
+ * @param value The String property value to convert.
+ * @return An {@link InetAddress} which represents the configuration property 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
+ protected T convertToType(final Class type, final Object value) throws Throwable {
+ if (InetAddress.class.isAssignableFrom(type)) {
+ final String stringValue = toString(value);
+
+ try {
+ return type.cast(InetAddress.getByName(stringValue));
+ } catch (UnknownHostException ex) {
+ throw new IllegalArgumentException("Unable to get IP address of the named host.", ex);
+ }
+ }
+
+ throw conversionException(type, value);
+ }
+}
diff --git a/src/main/java/org/apache/commons/beanutils2/converters/LocaleConverter.java b/src/main/java/org/apache/commons/beanutils2/converters/LocaleConverter.java
new file mode 100644
index 000000000..1b276c91f
--- /dev/null
+++ b/src/main/java/org/apache/commons/beanutils2/converters/LocaleConverter.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.commons.beanutils2.converters;
+
+import java.util.Locale;
+
+/**
+ * Converts a localization pattern into a Java {@link Locale} object.
+ *
+ * @since 2.0.0
+ */
+public class LocaleConverter extends AbstractConverter {
+
+ /**
+ * Construct a {@link Locale} Converter that throws a {@code ConversionException} if an error occurs.
+ */
+ public LocaleConverter() {
+ super();
+ }
+
+ /**
+ * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a
+ * conversion error occurs.
+ *
+ * @param defaultValue The default value to be returned if the value to be converted is missing or an error occurs
+ * converting the value.
+ */
+ public LocaleConverter(final Locale defaultValue) {
+ super(defaultValue);
+ }
+
+ /**
+ * Gets the default type this {@code Converter} handles.
+ *
+ * @return The default type this {@code Converter} handles.
+ * @since 2.0.0
+ */
+ @Override
+ protected Class getDefaultType() {
+ return Locale.class;
+ }
+
+ /**
+ * Converts the specified input object into an output object of the specified type.
+ *
+ * @param value The String property value to convert.
+ * @return A {@link Locale} which represents the configuration property value.
+ * @throws NullPointerException If the value is null.
+ */
+ @Override
+ protected T convertToType(final Class type, final Object value) throws Throwable {
+ if (Locale.class.isAssignableFrom(type)) {
+ final String stringValue = toString(value);
+ return type.cast(Locale.forLanguageTag(stringValue));
+ }
+
+ throw conversionException(type, value);
+ }
+}
diff --git a/src/main/java/org/apache/commons/beanutils2/converters/PatternConverter.java b/src/main/java/org/apache/commons/beanutils2/converters/PatternConverter.java
new file mode 100644
index 000000000..3bd6fc68f
--- /dev/null
+++ b/src/main/java/org/apache/commons/beanutils2/converters/PatternConverter.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.commons.beanutils2.converters;
+
+import java.util.regex.Pattern;
+
+/**
+ * Converts a regular expression into a Java {@link Pattern} object.
+ *
+ * @since 2.0.0
+ */
+public class PatternConverter extends AbstractConverter {
+
+ /**
+ * Construct a {@link Pattern} Converter that throws a {@code ConversionException} if an error occurs.
+ */
+ public PatternConverter() {
+ super();
+ }
+
+ /**
+ * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a
+ * conversion error occurs.
+ *
+ * @param defaultValue The default value to be returned if the value to be converted is missing or an error occurs
+ * converting the value.
+ */
+ public PatternConverter(final Pattern defaultValue) {
+ super(defaultValue);
+ }
+
+ /**
+ * Gets the default type this {@code Converter} handles.
+ *
+ * @return The default type this {@code Converter} handles.
+ * @since 2.0.0
+ */
+ @Override
+ protected Class getDefaultType() {
+ return Pattern.class;
+ }
+
+ /**
+ * Converts the specified input object into an output object of the specified type.
+ *
+ * @param value The String property value to convert.
+ * @return A {@link Pattern} which represents the compiled configuration property.
+ * @throws NullPointerException If the value is null.
+ * @throws java.util.regex.PatternSyntaxException If the regular expression {@link String} provided is malformed.
+ */
+ @Override
+ protected T convertToType(final Class type, final Object value) throws Throwable {
+ if (Pattern.class.isAssignableFrom(type)) {
+ final String stringValue = toString(value);
+ return type.cast(Pattern.compile(stringValue));
+ }
+
+ throw conversionException(type, value);
+ }
+}
diff --git a/src/main/java/org/apache/commons/beanutils2/converters/PointConverter.java b/src/main/java/org/apache/commons/beanutils2/converters/PointConverter.java
new file mode 100644
index 000000000..5ab727950
--- /dev/null
+++ b/src/main/java/org/apache/commons/beanutils2/converters/PointConverter.java
@@ -0,0 +1,101 @@
+/*
+ * 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.commons.beanutils2.converters;
+
+import java.awt.Point;
+import java.util.regex.Pattern;
+
+/**
+ * @since 2.0.0
+ */
+public class PointConverter extends AbstractConverter {
+
+ /** Pattern used to split the {@link Point#x} and {@link Point#y} coordinate. */
+ private static final Pattern POINT_SPLIT = Pattern.compile("\\s*,\\s*");
+
+ /**
+ * Construct a {@link Point} Converter that throws a {@code ConversionException} if an error occurs.
+ */
+ public PointConverter() {
+ super();
+ }
+
+ /**
+ * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a
+ * conversion error occurs.
+ *
+ * @param defaultValue The default value to be returned
+ * if the value to be converted is missing or an error
+ * occurs converting the value.
+ */
+ public PointConverter(final Point defaultValue) {
+ super(defaultValue);
+ }
+
+ /**
+ * Gets the default type this {@code Converter} handles.
+ *
+ * @return The default type this {@code Converter} handles.
+ * @since 2.0.0
+ */
+ @Override
+ protected Class getDefaultType() {
+ return Point.class;
+ }
+
+ /**
+ * Converts the specified input object into an output object of the specified type.
+ *
+ * @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 configuration 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
+ protected T convertToType(final Class type, final Object value) throws Throwable {
+ if (Point.class.isAssignableFrom(type)) {
+ final String stringValue = toString(value);
+
+ if (stringValue.isEmpty()) {
+ throw new IllegalArgumentException("A point can not be empty.");
+ }
+
+ final int lastCharIndex = stringValue.length() - 1;
+
+ if (stringValue.charAt(0) != '(' || stringValue.charAt(lastCharIndex) != ')') {
+ throw new IllegalArgumentException("Point coordinates must be enclosed in brackets.");
+ }
+
+ final String coordinates = stringValue.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 type.cast(new Point(x, y));
+ }
+
+ throw conversionException(type, value);
+ }
+}
diff --git a/src/test/java/org/apache/commons/beanutils2/converters/ColorConverterTestCase.java b/src/test/java/org/apache/commons/beanutils2/converters/ColorConverterTestCase.java
new file mode 100644
index 000000000..732f2dbfd
--- /dev/null
+++ b/src/test/java/org/apache/commons/beanutils2/converters/ColorConverterTestCase.java
@@ -0,0 +1,161 @@
+/*
+ * 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.commons.beanutils2.converters;
+
+import org.apache.commons.beanutils2.ConversionException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.awt.Color;
+
+/**
+ * Tests {@link ColorConverter}.
+ *
+ * @since 2.0.0
+ */
+public class ColorConverterTestCase {
+
+ private ColorConverter converter;
+
+ @Before
+ public void before() {
+ converter = new ColorConverter();
+ }
+
+ @Test
+ public void testConvertingPattern() {
+ final Color expected = Color.BLACK;
+ final Color actual = converter.convert(Color.class, "#000000");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingPatternWithAlpha() {
+ final Color expected = Color.LIGHT_GRAY;
+ final Color actual = converter.convert(Color.class, "#C0C0C0FF");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingPattern3Digit() {
+ final Color expected = Color.WHITE;
+ final Color actual = converter.convert(Color.class, "#FFF");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingPattern4Digit() {
+ final Color expected = Color.YELLOW;
+ final Color actual = converter.convert(Color.class, "#FF0F");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingLiteralHex() {
+ final Color expected = Color.BLUE;
+ final Color actual = converter.convert(Color.class, "0x0000FF");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingColorName() {
+ final Color expected = Color.WHITE;
+ final Color actual = converter.convert(Color.class, "white");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingColorNameCaps() {
+ final Color expected = Color.LIGHT_GRAY;
+ final Color actual = converter.convert(Color.class, "LIGHTGRAY");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingJavaColorStringFull() {
+ final Color expected = Color.WHITE;
+ final Color actual = converter.convert(Color.class, "java.awt.Color[r=255,g=255,b=255]");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * Color can be extended without the {@link Override overriding} the {@link Color#toString()} method.
+ * This tests that it can continue to parse the {@link String} from an inherited class.
+ */
+ @Test
+ public void testConvertingJavaExtendsColorString() {
+ final Color expected = Color.MAGENTA;
+ final Color actual = converter.convert(Color.class, "org.apache.ExtendedColor[r=255,g=0,b=255]");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingJavaColorStringWithoutPackage() {
+ final Color expected = Color.GREEN;
+ final Color actual = converter.convert(Color.class, "[r=0,g=255,b=0]");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingJavaColorStringWithoutBrackets() {
+ final Color expected = Color.DARK_GRAY;
+ final Color actual = converter.convert(Color.class, "r=64,g=64,b=64");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingJavaColorStringWithoutColorPrefixes() {
+ final Color expected = Color.PINK;
+ final Color actual = converter.convert(Color.class, "255,175,175");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testInvalidNumber3() {
+ converter.convert(Color.class, "#FFZ");
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testInvalidNumber4() {
+ converter.convert(Color.class, "#FFFY");
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testColorBlank() {
+ converter.convert(Color.class, "#");
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testColorInvalidLength() {
+ converter.convert(Color.class, "#F");
+ }
+}
diff --git a/src/test/java/org/apache/commons/beanutils2/converters/DimensionConverterTestCase.java b/src/test/java/org/apache/commons/beanutils2/converters/DimensionConverterTestCase.java
new file mode 100644
index 000000000..94a3a6717
--- /dev/null
+++ b/src/test/java/org/apache/commons/beanutils2/converters/DimensionConverterTestCase.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.commons.beanutils2.converters;
+
+import org.apache.commons.beanutils2.ConversionException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.awt.Dimension;
+
+/**
+ * Tests {@link DimensionConverter}.
+ *
+ * @since 2.0.0
+ */
+public class DimensionConverterTestCase {
+
+ 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(Dimension.class, "1920x1080");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingSquare() {
+ final Dimension expected = new Dimension(512, 512);
+ final Dimension actual = converter.convert(Dimension.class, "512");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testInvalidDimensions() {
+ converter.convert(Dimension.class, "512n512");
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testInvalidNumberFormatException() {
+ converter.convert(Dimension.class, "3000000000x100");
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testNegativeDimension() {
+ converter.convert(Dimension.class, "-512x512");
+ }
+}
diff --git a/src/test/java/org/apache/commons/beanutils2/converters/InetAddressConverterTestCase.java b/src/test/java/org/apache/commons/beanutils2/converters/InetAddressConverterTestCase.java
new file mode 100644
index 000000000..803f8e604
--- /dev/null
+++ b/src/test/java/org/apache/commons/beanutils2/converters/InetAddressConverterTestCase.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.commons.beanutils2.converters;
+
+import org.apache.commons.beanutils2.ConversionException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests {@link InetAddressConverter}.
+ *
+ * @since 2.0.0
+ */
+public class InetAddressConverterTestCase {
+
+ 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(InetAddress.class, "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(InetAddress.class, "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(InetAddress.class, "localhost");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testText() {
+ converter.convert(InetAddress.class, "Hello, world!");
+ }
+
+ @Test(expected = ConversionException.class)
+ public void testInvalidIp() {
+ converter.convert(InetAddress.class, "512.512.512.512");
+ }
+}
diff --git a/src/test/java/org/apache/commons/beanutils2/converters/LocaleConverterTestCase.java b/src/test/java/org/apache/commons/beanutils2/converters/LocaleConverterTestCase.java
new file mode 100644
index 000000000..3d419d2fd
--- /dev/null
+++ b/src/test/java/org/apache/commons/beanutils2/converters/LocaleConverterTestCase.java
@@ -0,0 +1,56 @@
+/*
+ * 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.commons.beanutils2.converters;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Locale;
+
+/**
+ * Tests {@link LocaleConverter}.
+ *
+ * @since 2.0.0
+ */
+public class LocaleConverterTestCase {
+
+ private LocaleConverter converter;
+
+ @Before
+ public void before() {
+ converter = new LocaleConverter();
+ }
+
+ @Test
+ public void testConvertStandardLocale() {
+ final Locale expected = Locale.ENGLISH;
+ final Locale actual = converter.convert(Locale.class, "en");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertCustomLocale() {
+ final Locale expected = Locale.forLanguageTag("en-owo");
+ final Locale actual = converter.convert(Locale.class, "en-owo");
+
+ Assert.assertEquals(expected, actual);
+ }
+}
diff --git a/src/test/java/org/apache/commons/beanutils2/converters/PatternConverterTestCase.java b/src/test/java/org/apache/commons/beanutils2/converters/PatternConverterTestCase.java
new file mode 100644
index 000000000..cadce68d6
--- /dev/null
+++ b/src/test/java/org/apache/commons/beanutils2/converters/PatternConverterTestCase.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.commons.beanutils2.converters;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.regex.Pattern;
+
+/**
+ * Tests {@link PatternConverter}.
+ *
+ * @since 2.0.0
+ */
+public class PatternConverterTestCase {
+
+ 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(Pattern.class, "(?i)Ow.+O").toString();
+
+ Assert.assertEquals(expected, actual);
+ }
+}
diff --git a/src/test/java/org/apache/commons/beanutils2/converters/PointConverterTestCase.java b/src/test/java/org/apache/commons/beanutils2/converters/PointConverterTestCase.java
new file mode 100644
index 000000000..8813ee0cc
--- /dev/null
+++ b/src/test/java/org/apache/commons/beanutils2/converters/PointConverterTestCase.java
@@ -0,0 +1,56 @@
+/*
+ * 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.commons.beanutils2.converters;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.awt.Point;
+
+/**
+ * Tests {@link PointConverter}.
+ *
+ * @since 2.0.0
+ */
+public class PointConverterTestCase {
+
+ 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(Point.class, "(100, 200)");
+
+ Assert.assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testConvertingNoSpace() {
+ final Point expected = new Point(100, 200);
+ final Point actual = converter.convert(Point.class, "(100,200)");
+
+ Assert.assertEquals(expected, actual);
+ }
+}