All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.csv.Common Maven / Gradle / Ivy

There is a newer version: 3.1
Show newest version
/*
 * #%L
 * Nuiton CSV
 * %%
 * Copyright (C) 2011 CodeLutin, Tony Chemit, Brendan Le Ny
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */
package org.nuiton.csv;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.nuiton.util.StringUtil;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * TODO
 *
 * @author Brendan Le Ny - [email protected]
 * @author Tony Chemit - [email protected]
 * @since 2.4
 */
public class Common {

    public static final ValueParserFormatter STRING =
            new StringValueParser();

    public static final ValueFormatter TO_STRING_FORMATTER =
            new ToStringValueFormatter();

    public static final ValueParserFormatter BOOLEAN =
            new BooleanParserFormatter(null, true);

    public static final ValueParserFormatter PRIMITIVE_BOOLEAN =
            new BooleanParserFormatter(false, false);

    public static ValueParserFormatter CHAR =
            new CharacterParserFormatter(null, true);

    public static ValueParserFormatter PRIMITIVE_SHORT =
            new ShortParserFormatter((short) 0, false);

    public static ValueParserFormatter SHORT =
            new ShortParserFormatter(null, true);

    public static ValueParserFormatter INTEGER =
            new IntegerParserFormatter(null, true);

    public static ValueParserFormatter PRIMITIVE_INTEGER =
            new IntegerParserFormatter(0, false);

    public static ValueParserFormatter LONG =
            new LongParserFormatter(null, true);

    public static ValueParserFormatter PRIMITIVE_LONG =
            new LongParserFormatter(0l, false);

    public static ValueParserFormatter FLOAT =
            new FloatParserFormatter(null, true);

    public static ValueParserFormatter PRIMITIVE_FLOAT =
            new FloatParserFormatter(0f, false);

    public static ValueParserFormatter DOUBLE =
            new DoubleParserFormatter(null, true);

    public static ValueParserFormatter DOUBLE_PRIMITIVE =
            new DoubleParserFormatter(0d, false);

    public static final ValueParserFormatter DAY =
            new DateValue("dd/MM/yyyy");

    public static final ValueParserFormatter DAY_TIME =
            new DateValue("dd/MM/yyyy HH:mm");

    public static final ValueParserFormatter DAY_TIME_SECOND =
            new DateValue("dd/MM/yyyy HH:mm:ss");

    public static final ValueParserFormatter TIME =
            new DateValue("HH:mm");

    /** A week in a given year, ie "1/2011" until "52/2011" */
    public static final ValueParserFormatter WEEK =
            new DateValue("w/yyyy");

    public static final ValueParserFormatter YEAR =
            new DateValue("yyyy");

    public static , T> MapProperty newMapProperty(String propertyName) {
        return new MapProperty(propertyName);
    }

    public static  BeanProperty newBeanProperty(String propertyName) {
        return new BeanProperty(propertyName);
    }

    public static > ValueParserFormatter newEnumByNameParserFormatter(Class enumType) {
        return new EnumByNameParserFormatter(enumType);
    }

    public static > ValueParserFormatter newEnumByOrdinalParserFormatter(Class enumType) {
        return new EnumByOrdinalParserFormatter(enumType);
    }

    public static class StringValueParser implements ValueParserFormatter {

        @Override
        public String parse(String value) {
            return value;
        }

        @Override
        public String format(String value) {
            return value == null ? "" : value;
        }
    }

    public static class ToStringValueFormatter implements ValueFormatter {

        @Override
        public String format(Object value) {
            return value == null ? "" : value.toString();
        }
    }

    public static class BeanProperty implements ValueGetterSetter {

        protected String propertyName;

        BeanProperty(String propertyName) {
            this.propertyName = propertyName;
        }

        @Override
        public void set(E bean, T value) throws Exception {
            BeanUtilsBean.getInstance().getPropertyUtils().setProperty(bean, propertyName, value);
        }

        @Override
        public T get(E object) throws Exception {
            T value = (T) PropertyUtils.getProperty(object, propertyName);
            return value;
        }
    }

    public static class MapProperty, T> implements ValueGetterSetter {

        protected String propertyName;

        MapProperty(String propertyName) {
            this.propertyName = propertyName;
        }

        @Override
        public void set(E bean, T value) throws Exception {
            bean.put(propertyName, value);
        }

        @Override
        public T get(E object) throws Exception {
            T value = (T) object.get(propertyName);
            return value;
        }
    }

    public static class DateValue implements ValueParserFormatter {

        protected String dateFormatPattern;

        protected DateFormat dateFormat;

        public DateValue(String dateFormatPattern) {
            this.dateFormatPattern = dateFormatPattern;
            dateFormat = new SimpleDateFormat(dateFormatPattern);
        }

        @Override
        public Date parse(String value) throws ParseException {
            Date date = null;
            if (StringUtils.isNotBlank(value)) {
                try {
                    date = dateFormat.parse(value);
                } catch (ParseException e) {
                    throw new ParseException("unable to parse date, expected format is " + dateFormatPattern, 0);
                }
            }
            return date;
        }

        @Override
        public String format(Date date) {
            String value = "";
            if (date != null) {
                value = dateFormat.format(date);
            }
            return value;
        }
    }

    public static class EnumByNameParserFormatter> implements ValueParserFormatter {


        private final Class enumType;

        public EnumByNameParserFormatter(Class enumType) {
            this.enumType = enumType;
        }

        @Override
        public E parse(String value) throws ParseException {
            E result;
            if (StringUtils.isBlank(value)) {
                result = null;
            } else {
                result = Enum.valueOf(enumType, value);
            }
            return result;
        }

        @Override
        public String format(E date) {
            String value = "";
            if (date != null) {
                value = date.name();
            }
            return value;
        }
    }

    public static class EnumByOrdinalParserFormatter> implements ValueParserFormatter {

        private final E[] universe;

        private final int maxValue;

        public EnumByOrdinalParserFormatter(Class enumType) {
            universe = enumType.getEnumConstants();
            maxValue = universe.length - 1;
        }

        @Override
        public E parse(String value) throws ParseException {
            E result;
            if (StringUtils.isBlank(value)) {
                result = null;
            } else {
                Integer ordinal;
                try {
                    ordinal = Integer.valueOf(value);
                } catch (NumberFormatException e) {
                    throw new ParseException(
                            "Could not parse ordinal value [" + value + "]", 0);
                }
                if (ordinal > maxValue) {
                    throw new ParseException(
                            "Ordinal value [" + ordinal
                            + "] not inbound (possible value from [0.." +
                            maxValue + "] for enum " + Arrays.toString(universe),
                            0
                    );
                }
                result = universe[ordinal];
            }
            return result;
        }

        @Override
        public String format(E date) {
            String value = "";
            if (date != null) {
                value = date.name();
            }
            return value;
        }
    }

    public static class ToStringParserFormatter implements ValueParserFormatter {

        protected Map toStrings = new HashMap();

        protected Map fromString = new HashMap();

        public ToStringParserFormatter(List values) {
            this(values, null);
        }

        public ToStringParserFormatter(E[] values) {
            computeToStrings(values, null);
        }

        public ToStringParserFormatter(List values,
                                       StringUtil.ToString toString) {
            computeToStrings(values, toString);
        }

        /** fill toStrings and fromString */
        protected void computeToStrings(E[] values,
                                        StringUtil.ToString toString) {
            List valuesAsList = new LinkedList();
            Collections.addAll(valuesAsList, values);
            computeToStrings(valuesAsList, toString);
        }

        /** fill toStrings and fromString */
        protected void computeToStrings(List values,
                                        StringUtil.ToString toString) {
            for (E value : values) {
                String valueToString;
                if (toString == null) {
                    valueToString = value.toString();
                } else {
                    valueToString = toString.toString(value);
                }
                toStrings.put(value, valueToString);
                fromString.put(valueToString, value);
            }
        }

        @Override
        public String format(E value) {
            String valueAsString = toStrings.get(value);
            if (valueAsString == null) {
                throw new IllegalArgumentException();
            }
            return valueAsString;
        }

        @Override
        public E parse(String valueAsString) throws ParseException {
            E value = fromString.get(valueAsString);
            if (value == null) {
                throw new IllegalArgumentException("Unable to parse value '" + valueAsString +
                                                   "'. Possible values are " + fromString.keySet().toString());
            }
            return value;
        }
    }

    public static class ValueSaver implements ValueGetterSetter {

        protected T value;

        @Override
        public T get(E object) throws Exception {
            return value;
        }

        @Override
        public void set(E object, T value) throws Exception {
            this.value = value;
        }
    }

    public static abstract class NullableParserFormatter implements ValueParserFormatter {

        protected O defaultValue;

        protected boolean nullAllowed;

        protected abstract O parseNoneEmptyValue(String value);

        protected NullableParserFormatter(O defaultValue,
                                          boolean nullAllowed) {
            this.defaultValue = defaultValue;
            this.nullAllowed = nullAllowed;
        }

        @Override
        public O parse(String value) throws ParseException {
            O result;
            if (StringUtils.isBlank(value)) {
                result = defaultValue;
            } else {
                result = parseNoneEmptyValue(value);
            }

            if (result == null && !nullAllowed) {
                throw new IllegalArgumentException();
            }
            return result;
        }
    }

    public static class BooleanParserFormatter extends NullableParserFormatter {

        public BooleanParserFormatter(Boolean defaultValue, boolean nullAllowed) {
            super(defaultValue, nullAllowed);
        }

        @Override
        public String format(Boolean bool) {
            String value;
            if (bool == null) {
                if (nullAllowed) {
                    value = "?";
                } else {
                    throw new IllegalArgumentException();
                }
            } else if (bool) {
                value = "Y";
            } else {
                value = "N";
            }
            return value;
        }

        @Override
        protected Boolean parseNoneEmptyValue(String value) {
            Boolean result;
            if ("?".equals(value)) {
                result = null;
            } else if ("Y".equals(value)) {
                result = true;
            } else if ("N".equals(value)) {
                result = false;
            } else {
                result = Boolean.parseBoolean(value);
            }
            return result;
        }
    }

    public static class CharacterParserFormatter extends NullableParserFormatter {

        public CharacterParserFormatter(Character defaultValue, boolean nullAllowed) {
            super(defaultValue, nullAllowed);
        }

        @Override
        public String format(Character value) {
            String str = "";
            if (value != null) {
                str = String.valueOf(value);
            }
            return str;
        }

        @Override
        protected Character parseNoneEmptyValue(String value) {
            return value.charAt(0);
        }
    }

    public static class ShortParserFormatter extends NullableParserFormatter {

        public ShortParserFormatter(Short defaultValue, boolean nullAllowed) {
            super(defaultValue, nullAllowed);
        }

        @Override
        public String format(Short value) {
            String str = "";
            if (value != null) {
                str = String.valueOf(value);
            }
            return str;
        }

        @Override
        protected Short parseNoneEmptyValue(String value) {
            Float aFloat = Float.valueOf(value);
            if (aFloat > Short.MAX_VALUE) {
                // too big
                throw new IllegalArgumentException(value + " is too big to be an short, should be a integer.");
            }
            return aFloat.shortValue();
        }
    }

    public static class IntegerParserFormatter extends NullableParserFormatter {

        public IntegerParserFormatter(Integer defaultValue, boolean nullAllowed) {
            super(defaultValue, nullAllowed);
        }

        @Override
        public String format(Integer value) {
            String str = "";
            if (value != null) {
                str = String.valueOf(value);
            }
            return str;
        }

        @Override
        protected Integer parseNoneEmptyValue(String value) {
            // use a float to be able to parse for example 6e+06 (see https://forge.nuiton.org/issues/3131)
            Float aFloat = Float.valueOf(value);
            if (aFloat > Integer.MAX_VALUE) {
                // too big
                throw new IllegalArgumentException(value + " is too big to be an int, should be a long.");
            }
            return aFloat.intValue();
        }
    }

    public static class LongParserFormatter extends NullableParserFormatter {

        public LongParserFormatter(Long defaultValue, boolean nullAllowed) {
            super(defaultValue, nullAllowed);
        }

        @Override
        public String format(Long value) {
            String str = "";
            if (value != null) {
                str = String.valueOf(value);
            }
            return str;
        }

        @Override
        protected Long parseNoneEmptyValue(String value) {
            // use a double to be able to parse for example 6e+06 (see https://forge.nuiton.org/issues/3131)
            Double aDouble = Double.valueOf(value);
            if (aDouble > Long.MAX_VALUE) {
                // too big
                throw new IllegalArgumentException(value + " is too big to be an long.");
            }
            return aDouble.longValue();
        }

    }

    public static class FloatParserFormatter extends NullableParserFormatter {

        public FloatParserFormatter(Float defaultValue, boolean nullAllowed) {
            super(defaultValue, nullAllowed);
        }

        @Override
        public String format(Float value) {
            String str = "";
            if (value != null) {
                str = String.valueOf(value);
            }
            return str;
        }

        @Override
        protected Float parseNoneEmptyValue(String value) {
            return Float.valueOf(value);
        }

    }

    public static class DoubleParserFormatter extends NullableParserFormatter {

        public DoubleParserFormatter(Double defaultValue, boolean nullAllowed) {
            super(defaultValue, nullAllowed);
        }

        @Override
        public String format(Double value) {
            String str = "";
            if (value != null) {
                str = String.valueOf(value);
            }
            return str;
        }

        @Override
        protected Double parseNoneEmptyValue(String value) {
            return Double.valueOf(value);
        }

    }


}