DimensionConverter.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.Dimension;
  21. import java.util.regex.Matcher;
  22. import java.util.regex.Pattern;

  23. /**
  24.  * {@link org.apache.commons.beanutils2.Converter} implementation that handles conversion to and from {@link Dimension}.
  25.  *
  26.  * <p>
  27.  * Accepts a single {@link Integer} value, or two {@link Integer} values separated by the character {@code x}.
  28.  * </p>
  29.  *
  30.  * <p>
  31.  * The dimensions must consist of non-negative {@link Integer} values only.
  32.  * </p>
  33.  *
  34.  * @since 2.0.0
  35.  */
  36. public class DimensionConverter extends AbstractConverter<Dimension> {

  37.     /** Pattern used to validate and tokenizer the {@link String}. */
  38.     private static final Pattern DIMENSION_PATTERN = Pattern.compile("(\\d+)(?:x(\\d+))?");

  39.     /**
  40.      * Construct a <strong>{@link Dimension}</strong> <em>Converter</em> that throws a {@code ConversionException} if an error occurs.
  41.      */
  42.     public DimensionConverter() {
  43.     }

  44.     /**
  45.      * Constructs a {@link org.apache.commons.beanutils2.Converter} that will return the specified default value if a conversion error occurs.
  46.      *
  47.      * @param defaultValue The default value to be returned if the value to be converted is missing or an error occurs converting the value.
  48.      */
  49.     public DimensionConverter(final Dimension defaultValue) {
  50.         super(defaultValue);
  51.     }

  52.     /**
  53.      * Converts the input object into an output object of the specified type.
  54.      *
  55.      * @param type  Data type to which this value should be converted.
  56.      * @param value String property value to convert.
  57.      * @return A {@link Dimension} which represents the configuration property value.
  58.      * @throws NullPointerException  If the value is null.
  59.      * @throws NumberFormatException If the {@link Dimension} width or height is bigger than {@link Integer#MAX_VALUE}.
  60.      */
  61.     @Override
  62.     protected <T> T convertToType(final Class<T> type, final Object value) throws Throwable {
  63.         if (Dimension.class.isAssignableFrom(type)) {
  64.             final String stringValue = toString(value);

  65.             if (stringValue.isEmpty()) {
  66.                 throw new IllegalArgumentException("Dimensions cannot be empty.");
  67.             }

  68.             final Matcher matcher = DIMENSION_PATTERN.matcher(stringValue);

  69.             if (!matcher.matches()) {
  70.                 throw new IllegalArgumentException("Dimension doesn't match format: {width/height} or {width}x{height}");
  71.             }

  72.             final String x = matcher.group(1);
  73.             final String y = matcher.group(2);

  74.             final int xValue = Integer.parseInt(x);
  75.             final int yValue = y == null || x.equals(y) ? xValue : Integer.parseInt(y);

  76.             return type.cast(new Dimension(xValue, yValue));
  77.         }

  78.         throw conversionException(type, value);
  79.     }

  80.     /**
  81.      * Gets the default type this {@code Converter} handles.
  82.      *
  83.      * @return The default type this {@code Converter} handles.
  84.      * @since 2.0.0
  85.      */
  86.     @Override
  87.     protected Class<Dimension> getDefaultType() {
  88.         return Dimension.class;
  89.     }
  90. }