/*
 * Copyright 2016 Andrew Rucker Jones.
 *
 * Licensed 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 com.opencsv.bean;

import com.opencsv.ICSVParser;
import com.opencsv.exceptions.CsvDataTypeMismatchException;
import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.locale.LocaleConvertUtilsBean;
import org.apache.commons.lang3.StringUtils;

import java.util.Locale;
import java.util.ResourceBundle;

This class wraps fields from the reflection API in order to handle translation of primitive types and to add a "required" flag.
Author:Andrew Rucker Jones
Since:4.2 (previously BeanFieldPrimitiveTypes since 3.8)
/** * This class wraps fields from the reflection API in order to handle * translation of primitive types and to add a "required" flag. * * @author Andrew Rucker Jones * @since 4.2 (previously BeanFieldPrimitiveTypes since 3.8) */
public class ConverterPrimitiveTypes extends AbstractCsvConverter {
The formatter for all inputs to wrapped and unwrapped primitive types when a specific locale is not required.

Either this or readLocaleConverter should be used, and the other should always be null.

It is absolutely critical that access to this member variable is always synchronized!

/** * The formatter for all inputs to wrapped and unwrapped primitive * types when a specific locale is not required. * <p>Either this or {@link #readLocaleConverter} should be used, and the * other should always be {@code null}.</p> * <p><em>It is absolutely critical that access to this member variable is * always synchronized!</em></p> */
protected final ConvertUtilsBean readConverter;
The formatter for all inputs to wrapped and unwrapped primitive types when a specific locale is required.

Either this or readConverter should be used, and the other should always be null.

It is absolutely critical that access to this member variable is always synchronized!

/** * The formatter for all inputs to wrapped and unwrapped primitive * types when a specific locale is required. * <p>Either this or {@link #readConverter} should be used, and the other * should always be {@code null}.</p> * <p><em>It is absolutely critical that access to this member variable is * always synchronized!</em></p> */
protected final LocaleConvertUtilsBean readLocaleConverter;
The formatter for all inputs from wrapped and unwrapped primitive types when a specific locale is not required.

Either this or writeLocaleConverter should be used, and the other should always be null.

It is absolutely critical that access to this member variable is always synchronized!

/** * The formatter for all inputs from wrapped and unwrapped primitive * types when a specific locale is not required. * <p>Either this or {@link #writeLocaleConverter} should be used, and the * other should always be {@code null}.</p> * <p><em>It is absolutely critical that access to this member variable is * always synchronized!</em></p> */
protected final ConvertUtilsBean writeConverter;
The formatter for all inputs from wrapped and unwrapped primitive types when a specific locale is required.

Either this or writeConverter should be used, and the other should always be null.

It is absolutely critical that access to this member variable is always synchronized!

/** * The formatter for all inputs from wrapped and unwrapped primitive * types when a specific locale is required. * <p>Either this or {@link #writeConverter} should be used, and the other * should always be {@code null}.</p> * <p><em>It is absolutely critical that access to this member variable is * always synchronized!</em></p> */
protected final LocaleConvertUtilsBean writeLocaleConverter;
Params:
  • type – The class of the type of the data being processed
  • locale – If not null or empty, specifies the locale used for converting locale-specific data types
  • writeLocale – If not null or empty, specifies the locale used for converting locale-specific data types for writing
  • errorLocale – The locale to use for error messages.
/** * @param type The class of the type of the data being processed * @param locale If not null or empty, specifies the locale used for * converting locale-specific data types * @param writeLocale If not null or empty, specifies the locale used for * converting locale-specific data types for writing * @param errorLocale The locale to use for error messages. */
public ConverterPrimitiveTypes(Class<?> type, String locale, String writeLocale, Locale errorLocale) { super(type, locale, writeLocale, errorLocale); if(this.locale == null) { readConverter = new ConvertUtilsBean(); readConverter.register(true, false, 0); readLocaleConverter = null; } else { readLocaleConverter = new LocaleConvertUtilsBean(); readLocaleConverter.setDefaultLocale(this.locale); readConverter = null; } if(this.writeLocale == null) { writeConverter = new ConvertUtilsBean(); writeConverter.register(true, false, 0); writeLocaleConverter = null; } else { writeLocaleConverter = new LocaleConvertUtilsBean(); writeLocaleConverter.setDefaultLocale(this.writeLocale); writeConverter = null; } } @Override public Object convertToRead(String value) throws CsvDataTypeMismatchException { Object o = null; if (StringUtils.isNotBlank(value) || (value != null && type.equals(String.class))) { try { if(readConverter != null) { synchronized (readConverter) { o = readConverter.convert(value, type); } } else { synchronized (readLocaleConverter) { o = readLocaleConverter.convert(value, type); } } } catch (ConversionException e) { CsvDataTypeMismatchException csve = new CsvDataTypeMismatchException( value, type, String.format( ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale).getString("conversion.impossible"), value, type.getCanonicalName())); csve.initCause(e); throw csve; } } return o; }
This method takes the current value of the field in question in the bean passed in and converts it to a string. It works for all of the primitives, wrapped primitives, String, BigDecimal, and BigInteger.
Throws:
/** * This method takes the current value of the field in question in the bean * passed in and converts it to a string. * It works for all of the primitives, wrapped primitives, * {@link java.lang.String}, {@link java.math.BigDecimal}, and * {@link java.math.BigInteger}. * * @throws CsvDataTypeMismatchException If there is an error converting * value to a string */
// The rest of the Javadoc is automatically inherited from the base class. @Override public String convertToWrite(Object value) throws CsvDataTypeMismatchException { String result = null; if(value != null) { try { if(writeConverter != null) { synchronized (writeConverter) { result = writeConverter.convert(value); } } else { synchronized (writeLocaleConverter) { result = writeLocaleConverter.convert(value); } } } catch(ConversionException e) { CsvDataTypeMismatchException csve = new CsvDataTypeMismatchException( ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale).getString("field.not.primitive")); csve.initCause(e); throw csve; } } return result; } }