
org.apache.commons.beanutils2.converters.ArrayConverter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of commons-beanutils2 Show documentation
Show all versions of commons-beanutils2 Show documentation
Apache Commons BeanUtils provides an easy-to-use but flexible wrapper around reflection and introspection.
The newest version!
/*
* 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
*
* https://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.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import org.apache.commons.beanutils2.ConversionException;
import org.apache.commons.beanutils2.Converter;
/**
* Generic {@link Converter} implementation that handles conversion to and from array objects.
*
* Can be configured to either return a default value or throw a {@code ConversionException} if a conversion error occurs.
*
* The main features of this implementation are:
*
* - Element Conversion - delegates to a {@link Converter}, appropriate for the type, to convert individual elements of the array. This
* leverages the power of existing converters without having to replicate their functionality for converting to the element type and removes the need to create
* a specific array type converters.
* - Arrays or Collections - can convert from either arrays or Collections to an array, limited only by the capability of the delegate
* {@link Converter}.
* - Delimited Lists - can Convert to and from a delimited list in String format.
* - Conversion to String - converts an array to a {@code String} in one of two ways: as a delimited list or by converting the first
* element in the array to a String - this is controlled by the {@link ArrayConverter#setOnlyFirstToString(boolean)} parameter.
* - Multi Dimensional Arrays - it is possible to convert a {@code String} to a multi-dimensional arrays, by embedding {@link ArrayConverter}
* within each other - see example below.
* - Default Value
*
* - No Default - use the {@link ArrayConverter#ArrayConverter(Class, Converter)} constructor to create a converter which throws a
* {@link ConversionException} if the value is missing or invalid.
* - Default values - use the {@link ArrayConverter#ArrayConverter(Class, Converter, int)} constructor to create a converter which
* returns a default value. The defaultSize parameter controls the default value in the following way:
*
* - defaultSize < 0 - default is {@code null}
* - defaultSize = 0 - default is an array of length zero
* - defaultSize > 0 - default is an array with a length specified by {@code defaultSize} (elements in the array will be {@code null})
*
*
*
*
*
*
* Parsing Delimited Lists
This implementation can convert a delimited list in {@code String} format into an array of the appropriate type. By default,
* it uses a comma as the delimiter but the following methods can be used to configure parsing:
*
* - {@code setDelimiter(char)} - allows the character used as the delimiter to be configured [default is a comma].
* - {@code setAllowedChars(char[])} - adds additional characters (to the default alphabetic/numeric) to those considered to be valid token characters.
*
*
* Multi Dimensional Arrays
It is possible to convert a {@code String} to multi-dimensional arrays by using {@link ArrayConverter} as the element
* {@link Converter} within another {@link ArrayConverter}.
*
* For example, the following code demonstrates how to construct a {@link Converter} to convert a delimited {@code String} into a two dimensional integer array:
*
*
*
* // Construct an Integer Converter
* IntegerConverter integerConverter = new IntegerConverter();
*
* // Construct an array Converter for an integer array (i.e. int[]) using
* // an IntegerConverter as the element converter.
* // Uses the default comma (i.e. ",") as the delimiter between individual numbers
* ArrayConverter arrayConverter = new ArrayConverter(int[].class, integerConverter);
*
* // Construct a "Matrix" Converter which converts arrays of integer arrays using
* // the preceding ArrayConverter as the element Converter.
* // Uses a semicolon (i.e. ";") as the delimiter to separate the different sets of numbers.
* // Also the delimiter used by the first ArrayConverter needs to be added to the
* // "allowed characters" for this one.
* ArrayConverter matrixConverter = new ArrayConverter(int[][].class, arrayConverter);
* matrixConverter.setDelimiter(';');
* matrixConverter.setAllowedChars(new char[] { ',' });
*
* // Do the Conversion
* String matrixString = "11,12,13 ; 21,22,23 ; 31,32,33 ; 41,42,43";
* int[][] result = (int[][]) matrixConverter.convert(int[][].class, matrixString);
*
*
* @param The converter type.
* @since 1.8.0
*/
public class ArrayConverter extends AbstractConverter {
private final Class defaultType;
private final Converter elementConverter;
private int defaultSize;
private char delimiter = ',';
private char[] allowedChars = { '.', '-' };
private boolean onlyFirstToString = true;
/**
* Constructs an array {@code Converter} with the specified component {@code Converter} that throws a
* {@code ConversionException} if an error occurs.
*
* @param defaultType The default array type this {@code Converter} handles
* @param elementConverter Converter used to convert individual array elements.
*/
public ArrayConverter(final Class defaultType, final Converter elementConverter) {
Objects.requireNonNull(defaultType, "defaultType");
if (!defaultType.isArray()) {
throw new IllegalArgumentException("Default type must be an array.");
}
this.elementConverter = Objects.requireNonNull(elementConverter, "elementConverter");
this.defaultType = defaultType;
}
/**
* Constructs an array {@code Converter} with the specified component {@code Converter} that returns a default array of
* the specified size (or {@code null}) if an error occurs.
*
* @param defaultType The default array type this {@code Converter} handles
* @param elementConverter Converter used to convert individual array elements.
* @param defaultSize Specifies the size of the default array value or if less than zero indicates that a {@code null} default value should be used.
*/
public ArrayConverter(final Class defaultType, final Converter elementConverter, final int defaultSize) {
this(defaultType, elementConverter);
this.defaultSize = defaultSize;
C defaultValue = null;
if (defaultSize >= 0) {
defaultValue = (C) Array.newInstance(defaultType.getComponentType(), defaultSize);
}
setDefaultValue(defaultValue);
}
/**
* Returns the value unchanged.
*
* @param value The value to convert
* @return The value unchanged
*/
@Override
protected Object convertArray(final Object value) {
return value;
}
/**
* Converts non-array values to a Collection prior to being converted either to an array or a String.
*
* - {@link Collection} values are returned unchanged
* - {@link Number}, {@link Boolean} and {@link java.util.Date} values returned as a the only element in a List.
* - All other types are converted to a String and parsed as a delimited list.
*
*
* N.B. The method is called by both the {@link ArrayConverter#convertToType(Class, Object)} and
* {@link ArrayConverter#convertToString(Object)} methods for non-array types.
*
* @param value value to be converted
* @return Collection elements.
*/
protected Collection> convertToCollection(final Object value) {
if (value instanceof Collection) {
return (Collection>) value;
}
if (value instanceof Number || value instanceof Boolean || value instanceof Date) {
final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy