Package name.abuchen.portfolio.datatransfer

Source Code of name.abuchen.portfolio.datatransfer.CSVImporter$DateField

package name.abuchen.portfolio.datatransfer;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.text.FieldPosition;
import java.text.Format;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import name.abuchen.portfolio.Messages;
import name.abuchen.portfolio.datatransfer.CSVImportDefinition.AccountTransactionDef;
import name.abuchen.portfolio.datatransfer.CSVImportDefinition.PortfolioTransactionDef;
import name.abuchen.portfolio.datatransfer.CSVImportDefinition.SecurityDef;
import name.abuchen.portfolio.datatransfer.CSVImportDefinition.SecurityPriceDef;
import name.abuchen.portfolio.model.Client;

import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVStrategy;

public class CSVImporter
{
    public static final class Column
    {
        private int columnIndex;
        private String label;
        private Field field;
        private FieldFormat format;

        /* package */Column(int columnIndex, String label)
        {
            this.columnIndex = columnIndex;
            this.label = label;
        }

        public int getColumnIndex()
        {
            return columnIndex;
        }

        public String getLabel()
        {
            return label;
        }

        public void setField(Field field)
        {
            this.field = field;
            this.format = null;
        }

        public Field getField()
        {
            return field;
        }

        public void setFormat(FieldFormat format)
        {
            this.format = format;
        }

        public FieldFormat getFormat()
        {
            return format;
        }
    }

    public static class FieldFormat
    {
        private final String label;
        private final Format format;

        public FieldFormat(String label, Format format)
        {
            this.label = label;
            this.format = format;
        }

        @Override
        public String toString()
        {
            return label;
        }

        public Format getFormat()
        {
            return format;
        }
    }

    public static class Field
    {
        private final String name;
        private boolean isOptional = false;

        public Field(String name)
        {
            this.name = name;
        }

        public String getName()
        {
            return name;
        }

        public Field setOptional(boolean isOptional)
        {
            this.isOptional = isOptional;
            return this;
        }

        public boolean isOptional()
        {
            return isOptional;
        }

        @Override
        public String toString()
        {
            return name;
        }
    }

    public static class DateField extends CSVImporter.Field
    {
        public static final FieldFormat[] FORMATS = new FieldFormat[] {
                        new FieldFormat(Messages.CSVFormatYYYYMMDD, new SimpleDateFormat("yyyy-MM-dd")), //$NON-NLS-1$
                        new FieldFormat(Messages.CSVFormatDDMMYYYY, new SimpleDateFormat("dd.MM.yyyy")), //$NON-NLS-1$
                        new FieldFormat(Messages.CSVFormatDDMMYYYY1, new SimpleDateFormat("dd/MM/yyyy")) //$NON-NLS-1$
        };

        /* package */DateField(String name)
        {
            super(name);
        }
    }

    public static class AmountField extends CSVImporter.Field
    {
        public static final FieldFormat[] FORMATS = new FieldFormat[] {
                        new FieldFormat(Messages.CSVFormatNumberGermany, NumberFormat.getInstance(Locale.GERMANY)),
                        new FieldFormat(Messages.CSVFormatNumberUS, NumberFormat.getInstance(Locale.US)) };

        /* package */AmountField(String name)
        {
            super(name);
        }
    }

    public static class EnumField<M extends Enum<M>> extends CSVImporter.Field
    {
        private final Class<M> enumType;

        /* package */EnumField(String name, Class<M> enumType)
        {
            super(name);
            this.enumType = enumType;
        }

        public Class<M> getEnumType()
        {
            return enumType;
        }

        public EnumMapFormat<M> createFormat()
        {
            return new EnumMapFormat<M>(enumType);
        }
    }

    public static class EnumMapFormat<M extends Enum<M>> extends Format
    {
        private static final long serialVersionUID = 1L;

        private EnumMap<M, String> enumMap;

        public EnumMapFormat(Class<M> enumType)
        {
            enumMap = new EnumMap<M, String>(enumType);
            for (M element : enumType.getEnumConstants())
                enumMap.put(element, element.toString());
        }

        public EnumMap<M, String> map()
        {
            return enumMap;
        }

        @Override
        public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos)
        {
            String s = enumMap.get(obj);
            if (s == null)
                throw new IllegalArgumentException();

            return toAppendTo.append(s);
        }

        @Override
        public M parseObject(String source, ParsePosition pos)
        {
            if (pos == null)
                throw new NullPointerException();

            for (Map.Entry<M, String> entry : enumMap.entrySet())
            {
                int p = source.indexOf(entry.getValue());
                if (p >= 0)
                {
                    pos.setIndex(source.length());
                    return entry.getKey();
                }
            }

            return null;
        }
    }

    private final Client client;
    private final File inputFile;
    private final CSVImportDefinition[] definitions = new CSVImportDefinition[] { new AccountTransactionDef(),
                    new PortfolioTransactionDef(), new SecurityDef(), new SecurityPriceDef() };

    private CSVImportDefinition importDefinition;
    private Object importTarget;

    private char delimiter = ';';
    private Charset encoding = Charset.defaultCharset();
    private int skipLines = 0;
    private boolean isFirstLineHeader = true;

    private Column[] columns;
    private List<String[]> values;

    public CSVImporter(Client client, File file)
    {
        this.client = client;
        this.inputFile = file;
    }

    public Client getClient()
    {
        return client;
    }

    public CSVImportDefinition[] getDefinitions()
    {
        return definitions;
    }

    public void setDefinition(CSVImportDefinition target)
    {
        this.importDefinition = target;
        if (importTarget != null && !this.importDefinition.getTargets(client).contains(importTarget))
            importTarget = null;
    }

    public CSVImportDefinition getDefinition()
    {
        return importDefinition;
    }

    public Object getImportTarget()
    {
        return importTarget;
    }

    public void setImportTarget(Object target)
    {
        if (target != null && !this.importDefinition.getTargets(client).contains(target))
            throw new IllegalArgumentException();
        this.importTarget = target;
    }

    public void setDelimiter(char delimiter)
    {
        this.delimiter = delimiter;
    }

    public void setEncoding(Charset encoding)
    {
        this.encoding = encoding;
    }

    public void setSkipLines(int skipLines)
    {
        this.skipLines = skipLines;
    }

    public void setFirstLineHeader(boolean isFirstLineHeader)
    {
        this.isFirstLineHeader = isFirstLineHeader;
    }

    public List<String[]> getRawValues()
    {
        return values;
    }

    public Column[] getColumns()
    {
        return columns;
    }

    public void processFile() throws IOException
    {
        FileInputStream stream = null;
        try
        {
            stream = new FileInputStream(inputFile);
            Reader reader = new InputStreamReader(stream, encoding);

            CSVStrategy strategy = new CSVStrategy(delimiter, '"', CSVStrategy.COMMENTS_DISABLED,
                            CSVStrategy.ESCAPE_DISABLED, false, false, false, false);

            CSVParser parser = new CSVParser(reader, strategy);

            for (int ii = 0; ii < skipLines; ii++)
                parser.getLine();

            List<String[]> values = new ArrayList<String[]>();
            String[] header = null;
            String[] line = parser.getLine();
            if (isFirstLineHeader)
            {
                header = line;
            }
            else
            {
                header = new String[line.length];
                for (int ii = 0; ii < header.length; ii++)
                    header[ii] = MessageFormat.format(Messages.CSVImportGenericColumnLabel, ii + 1);
                values.add(line);
            }

            while ((line = parser.getLine()) != null)
                values.add(line);

            this.columns = new CSVImporter.Column[header.length];
            for (int ii = 0; ii < header.length; ii++)
                this.columns[ii] = new Column(ii, header[ii]);

            this.values = values;

            mapToImportDefinition();
        }
        finally
        {
            if (stream != null)
            {
                try
                {
                    stream.close();
                }
                catch (IOException ignore)
                {}
            }
        }
    }

    private void mapToImportDefinition()
    {
        List<Field> list = new LinkedList<Field>(importDefinition.getFields());

        for (Column column : columns)
        {
            column.setField(null);
            Iterator<Field> iter = list.iterator();
            while (iter.hasNext())
            {
                Field field = iter.next();
                if (field.getName().equalsIgnoreCase(column.getLabel()))
                {
                    column.setField(field);

                    if (field instanceof DateField)
                        column.setFormat(DateField.FORMATS[0]);
                    else if (field instanceof AmountField)
                        column.setFormat(AmountField.FORMATS[0]);
                    else if (field instanceof EnumField<?>)
                        column.setFormat(new FieldFormat(null, ((EnumField<?>) field).createFormat()));

                    iter.remove();
                    break;
                }

            }
        }
    }

    public void createObjects(List<Exception> errors)
    {
        if (importDefinition == null)
            throw new IllegalArgumentException();
        if (importTarget == null)
            throw new IllegalArgumentException();

        Map<String, Column> field2column = new HashMap<String, Column>();
        for (Column column : getColumns())
            if (column.getField() != null)
                field2column.put(column.getField().name, column);

        for (String[] rawValues : values)
        {
            try
            {
                importDefinition.build(client, importTarget, rawValues, field2column);
            }
            catch (ParseException e)
            {
                errors.add(new IOException(MessageFormat.format(Messages.CSVImportError, Arrays.toString(rawValues),
                                e.getMessage()), e));
            }
        }
    }
}
TOP

Related Classes of name.abuchen.portfolio.datatransfer.CSVImporter$DateField

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.