PointConverter.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements. See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership. The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License. You may obtain a copy of the License at
  9.  *
  10.  * http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing,
  13.  * software distributed under the License is distributed on an
  14.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15.  * KIND, either express or implied. See the License for the
  16.  * specific language governing permissions and limitations
  17.  * under the License.
  18.  */
  19. package org.apache.commons.beanutils2.converters;

  20. import java.awt.Point;
  21. import java.util.regex.Pattern;

  22. /**
  23.  * {@link org.apache.commons.beanutils2.Converter} implementation that handles conversion to and from {@link Point}.
  24.  *
  25.  * @since 2.0.0
  26.  */
  27. public class PointConverter extends AbstractConverter<Point> {

  28.     /** Pattern used to split the {@link Point#x} and {@link Point#y} coordinate. */
  29.     private static final Pattern POINT_SPLIT = Pattern.compile("\\s*,\\s*");

  30.     /**
  31.      * Construct a <strong>{@link Point}</strong> <em>Converter</em> that throws a {@code ConversionException} if an error occurs.
  32.      */
  33.     public PointConverter() {
  34.     }

  35.     /**
  36.      * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a conversion error occurs.
  37.      *
  38.      * @param defaultValue The default value to be returned if the value to be converted is missing or an error occurs converting the value.
  39.      */
  40.     public PointConverter(final Point defaultValue) {
  41.         super(defaultValue);
  42.     }

  43.     /**
  44.      * Converts the specified input object into an output object of the specified type.
  45.      *
  46.      * @param type  Data type to which this value should be converted.
  47.      * @param value The {@link String} property value to convert.
  48.      * @return A {@link Point} represented by the x and y coordinate of the input.
  49.      * @throws NullPointerException     If the value is null.
  50.      * @throws IllegalArgumentException If the configuration value is an invalid representation of a {@link Point}.
  51.      * @throws NumberFormatException    If a one of coordinates cannot be parsed to an {@link Integer}.
  52.      */
  53.     @Override
  54.     protected <T> T convertToType(final Class<T> type, final Object value) throws Throwable {
  55.         if (Point.class.isAssignableFrom(type)) {
  56.             final String stringValue = toString(value);

  57.             if (stringValue.isEmpty()) {
  58.                 throw new IllegalArgumentException("A point cannot be empty.");
  59.             }

  60.             final int lastCharIndex = stringValue.length() - 1;

  61.             if (stringValue.charAt(0) != '(' || stringValue.charAt(lastCharIndex) != ')') {
  62.                 throw new IllegalArgumentException("Point coordinates must be enclosed in brackets.");
  63.             }

  64.             final String coordinates = stringValue.substring(1, lastCharIndex);
  65.             final String[] xy = POINT_SPLIT.split(coordinates);

  66.             if (xy.length != 2) {
  67.                 throw new IllegalArgumentException("Point must have an x coordinate, and y coordinate only, " + "expecting the following format: (40, 200)");
  68.             }

  69.             final int x = Integer.parseInt(xy[0]);
  70.             final int y = Integer.parseInt(xy[1]);
  71.             return type.cast(new Point(x, y));
  72.         }

  73.         throw conversionException(type, value);
  74.     }

  75.     /**
  76.      * Gets the default type this {@code Converter} handles.
  77.      *
  78.      * @return The default type this {@code Converter} handles.
  79.      * @since 2.0.0
  80.      */
  81.     @Override
  82.     protected Class<Point> getDefaultType() {
  83.         return Point.class;
  84.     }
  85. }