001/*
002 *  Copyright 2014 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.contentio.in.csv;
017
018import java.io.IOException;
019import java.io.Reader;
020import java.util.ArrayList;
021import java.util.HashMap;
022import java.util.List;
023import java.util.Map;
024
025import org.supercsv.cellprocessor.ift.CellProcessor;
026import org.supercsv.io.AbstractCsvReader;
027import org.supercsv.io.ICsvMapReader;
028import org.supercsv.io.ITokenizer;
029import org.supercsv.prefs.CsvPreference;
030
031/**
032 * Custom CsvMapReader which uses the column number as the map index.<br>
033 * The nameMapping parameter in the two read methods will not be used.
034 */
035public class CsvColNumberMapReader extends AbstractCsvReader implements ICsvMapReader
036{
037    
038    /**
039     * Constructs a new <code>CsvMapReader</code> with the supplied Reader and CSV preferences. Note
040     * that the <code>reader</code> will be wrapped in a <code>BufferedReader</code> before accessed.
041     * 
042     * @param reader the reader
043     * @param preferences the CSV preferences
044     * @throws NullPointerException if reader or preferences are null
045     */
046    public CsvColNumberMapReader(final Reader reader, final CsvPreference preferences)
047    {
048        super(reader, preferences);
049    }
050    
051    /**
052     * Constructs a new <code>CsvMapReader</code> with the supplied (custom) Tokenizer and CSV
053     * preferences. The tokenizer should be set up with the Reader (CSV input) and CsvPreference
054     * beforehand.
055     * 
056     * @param tokenizer the tokenizer
057     * @param preferences the CSV preferences
058     * @throws NullPointerException if tokenizer or preferences are null
059     */
060    public CsvColNumberMapReader(final ITokenizer tokenizer, final CsvPreference preferences)
061    {
062        super(tokenizer, preferences);
063    }
064    
065    @Override
066    public Map<String, String> read(final String... nameMapping) throws IOException
067    {
068        if (readRow())
069        {
070            final Map<String, String> destination = new HashMap<>();
071            
072            List<String> columns = getColumns();
073            for (int i = 0; i < columns.size(); i++)
074            {
075                destination.put(Integer.toString(i + 1), columns.get(i));
076            }
077            
078            return destination;
079        }
080        
081        return null; // EOF
082    }
083
084    @Override
085    public Map<String, Object> read(final String[] nameMapping, final CellProcessor[] processors) throws IOException
086    {
087        if (processors == null)
088        {
089            throw new NullPointerException("processors should not be null");
090        }
091        
092        if (readRow())
093        {
094            // process the columns
095            final List<Object> processedColumns = executeProcessors(new ArrayList<>(getColumns().size()), processors);
096            
097            // convert the List to a Map
098            final Map<String, Object> destination = new HashMap<>(processedColumns.size());
099            
100            for (int i = 0; i < processedColumns.size(); i++)
101            {
102                destination.put(Integer.toString(i + 1), processedColumns.get(i));
103            }
104            
105            return destination;
106        }
107        
108        return null; // EOF
109    }
110
111}