From e475de6a99eb727717294ade5e57a02e65f53410 Mon Sep 17 00:00:00 2001 From: Seth Falco Date: Tue, 3 Nov 2020 14:56:48 +0100 Subject: [PATCH] feat: added converters for color, dimension, inetaddress, locale, pattern, and point. --- .../commons/beanutils2/ConvertUtilsBean.java | 30 ++ .../beanutils2/converters/ColorConverter.java | 262 ++++++++++++++++++ .../converters/DimensionConverter.java | 106 +++++++ .../converters/InetAddressConverter.java | 84 ++++++ .../converters/LocaleConverter.java | 75 +++++ .../converters/PatternConverter.java | 76 +++++ .../beanutils2/converters/PointConverter.java | 101 +++++++ .../converters/ColorConverterTestCase.java | 161 +++++++++++ .../DimensionConverterTestCase.java | 72 +++++ .../InetAddressConverterTestCase.java | 76 +++++ .../converters/LocaleConverterTestCase.java | 56 ++++ .../converters/PatternConverterTestCase.java | 48 ++++ .../converters/PointConverterTestCase.java | 56 ++++ 13 files changed, 1203 insertions(+) create mode 100644 src/main/java/org/apache/commons/beanutils2/converters/ColorConverter.java create mode 100644 src/main/java/org/apache/commons/beanutils2/converters/DimensionConverter.java create mode 100644 src/main/java/org/apache/commons/beanutils2/converters/InetAddressConverter.java create mode 100644 src/main/java/org/apache/commons/beanutils2/converters/LocaleConverter.java create mode 100644 src/main/java/org/apache/commons/beanutils2/converters/PatternConverter.java create mode 100644 src/main/java/org/apache/commons/beanutils2/converters/PointConverter.java create mode 100644 src/test/java/org/apache/commons/beanutils2/converters/ColorConverterTestCase.java create mode 100644 src/test/java/org/apache/commons/beanutils2/converters/DimensionConverterTestCase.java create mode 100644 src/test/java/org/apache/commons/beanutils2/converters/InetAddressConverterTestCase.java create mode 100644 src/test/java/org/apache/commons/beanutils2/converters/LocaleConverterTestCase.java create mode 100644 src/test/java/org/apache/commons/beanutils2/converters/PatternConverterTestCase.java create mode 100644 src/test/java/org/apache/commons/beanutils2/converters/PointConverterTestCase.java 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: + *

    + * + * + * + *

    + * 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); + } +}