Package com.projectnine.csvmapper

Source Code of com.projectnine.csvmapper.ObjectToCsvMapper

/**
* Copyright (C) 2008 rweber <quietgenie@users.sourceforge.net>
*
* This file is part of CsvObjectMapper.
*
* CsvObjectMapper 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.
*
* CsvObjectMapper 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CsvObjectMapper.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
*
*/
package com.projectnine.csvmapper;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import net.sf.csv4j.CSVWriter;

import org.apache.commons.jexl.Expression;
import org.apache.commons.jexl.ExpressionFactory;
import org.apache.commons.jexl.JexlContext;
import org.apache.commons.jexl.JexlHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* @author robweber
*
*/
public class ObjectToCsvMapper {
    private static final Log log = LogFactory.getLog(ObjectToCsvMapper.class);

    private String mappingDefinition;
    private Writer output;
    private CSVWriter csvWriter;

    public ObjectToCsvMapper(String mappingDefinition, String outputFilename) {
        this.mappingDefinition = mappingDefinition;
        try {
            this.output = new FileWriter(outputFilename);
            csvWriter = new CSVWriter(output);
        } catch (IOException e) {
            log.error("Unable to open the specified file, " + outputFilename
                    + ", for writing.", e);
            throw new RuntimeException(e);
        }
    }

    public void writeObjectsToCsv(List<? extends Object> list) throws Exception {
        writeObjectsToCsv(list, false);
    }

    public void writeObjectsToCsv(List<? extends Object> list,
            boolean writeHeader) throws Exception {
        if (writeHeader) {
            List<String> csvHeader = createHeader(mappingDefinition);
            if (csvHeader != null) {
                csvWriter.writeLine(csvHeader);
            }
        }

        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) != null) {
                List<String> stringList = convertObjectToCsv(list.get(i),
                        mappingDefinition);
                csvWriter.writeLine(stringList);
            }
        }

        try {
            output.flush();
            output.close();
        } catch (Exception e) {
            log.warn("Unable to close the CSV output.");
        }
    }

    public static List<String> createHeader(String mappingDefinition) {
        List<String> csvHeader = new Vector<String>();
        CsvMappingDefinition csvMappingDefinition = CsvToObjectMapper.csvMappingDefinitions
                .get(mappingDefinition);

        for (int i = 0; i < csvMappingDefinition.getFieldMappings().size(); i++) {
            String fieldHeader = csvMappingDefinition.getFieldMappings().get(i)
                    .getCsvFieldHeader();
            if (fieldHeader == null) {
                fieldHeader = "";
            }

            csvHeader.add(fieldHeader);
        }

        return csvHeader;
    }

    @SuppressWarnings("unchecked")
    public static List<String> convertObjectToCsv(Object object,
            String mappingDefinition) throws Exception {
        log.debug("Converting object of class, " + object.getClass().getName()
                + ", using mapping definition, " + mappingDefinition);
        CsvMappingDefinition csvMappingDefinition = CsvToObjectMapper.csvMappingDefinitions
                .get(mappingDefinition);

        if (csvMappingDefinition == null) {
            throw new Exception("The mapping definition specified, "
                    + mappingDefinition + ", is not valid.");
        }

        List<CsvFieldMapping> fieldMappingList = getFieldMappingListForMappingDefinition(mappingDefinition);
        log.debug("Retrieved " + fieldMappingList.size() + " "
                + (fieldMappingList.size() != 1 ? "fields" : "field") + ".");
        List<String> csvFieldList = new Vector<String>();
        Collections.sort(fieldMappingList, new Comparator<CsvFieldMapping>() {

            public int compare(CsvFieldMapping o1, CsvFieldMapping o2) {
                if (o1.getColumnIndex() < o2.getColumnIndex()) {
                    return -1;
                }

                if (o1.getColumnIndex() == o2.getColumnIndex()) {
                    return 0;
                }

                return 1;
            }

        });

        if (log.isDebugEnabled()) {
            for (int i = 0; i < fieldMappingList.size(); i++) {
                log.debug("FieldMapping "
                        + fieldMappingList.get(i).getColumnIndex());
            }
        }

        int lastCsvIndex;
        int currentFieldMappingIndex = 0;
        if (csvMappingDefinition.getExpectedNumberOfFields() > 0) {
            log
                    .debug("Getting expected number of fields from explicit definition.");
            lastCsvIndex = csvMappingDefinition.getExpectedNumberOfFields();
        } else {
            log.debug("Getting expected number of fields by inferrence.");
            lastCsvIndex = fieldMappingList.get(fieldMappingList.size() - 1)
                    .getColumnIndex() + 1;
        }

        log.debug("Expect the CSV to have " + lastCsvIndex + " "
                + (lastCsvIndex != 1 ? "fields" : "field") + ".");

        JexlContext jexlContext = JexlHelper.createContext();
        jexlContext.getVars().put(csvMappingDefinition.getBeanVariableName(),
                object);
        if (csvMappingDefinition.getExtendedContext() != null) {
            Iterator<String> it = csvMappingDefinition.getExtendedContext()
                    .keySet().iterator();
            while (it.hasNext()) {
                String variableName = it.next();
                String valueExpression = csvMappingDefinition
                        .getExtendedContext().get(variableName);
                Expression preProcessing = ExpressionFactory
                        .createExpression(valueExpression);
                preProcessing.addPreResolver(new PoundDefineJexlResolver());
                jexlContext.getVars().put(variableName,
                        preProcessing.evaluate(jexlContext));
            }
        }

        for (int i = 0; i < lastCsvIndex; i++) {
            if (fieldMappingList.get(currentFieldMappingIndex).getColumnIndex() != i) {
                csvFieldList.add("");
            } else {
                String expressionString = fieldMappingList.get(
                        currentFieldMappingIndex).getObjectToCsvExpression();
                Expression expression = ExpressionFactory
                        .createExpression(expressionString);
                csvFieldList.add(fieldMappingList.get(currentFieldMappingIndex)
                        .getCsvFieldValueFromObject(
                                expression.evaluate(jexlContext)));
                currentFieldMappingIndex++;

                if (currentFieldMappingIndex < fieldMappingList.size()) {
                    while (fieldMappingList.get(currentFieldMappingIndex)
                            .getColumnIndex() == i) {
                        currentFieldMappingIndex++;
                    }
                }
            }
        }

        return csvFieldList;
    }

    private static List<CsvFieldMapping> getFieldMappingListForMappingDefinition(
            String mappingDefinition) {
        CsvMappingDefinition csvMappingDefinition = CsvToObjectMapper.csvMappingDefinitions
                .get(mappingDefinition);
        List<CsvFieldMapping> rawList = csvMappingDefinition.getFieldMappings();
        log.debug("The raw list of field mappings has " + rawList.size() + " "
                + (rawList.size() != 1 ? "elements" : "element") + ".");
        List<CsvFieldMapping> finishedList = new Vector<CsvFieldMapping>();

        for (int i = 0; i < rawList.size(); i++) {
            if (rawList.get(i).getBeanName() == null) {
                finishedList.add(rawList.get(i));
            } else {
                log.debug("Complex bean definition. Getting fields for "
                        + rawList.get(i).getBeanName());
                List<CsvFieldMapping> deeperRawList = getFieldMappingListForMappingDefinition(
                        rawList.get(i).getBeanName());
                log.debug("The next bean, " + rawList.get(i).getBeanName()
                        + ", gave us " + deeperRawList.size()
                        + " more field mappings.");
                for (int j = 0; j < deeperRawList.size(); j++) {
                    CsvFieldMapping temp = (CsvFieldMapping) deeperRawList.get(
                            j).clone();
                    String newExpression = new StringBuffer(temp
                            .getObjectToCsvExpression()).toString();
                    temp.setObjectToCsvExpression(newExpression.replace(
                            csvMappingDefinition.getBeanVariableName(), rawList
                                    .get(i).getObjectToCsvExpression()));
                    finishedList.add(temp);
                }
            }
        }

        return finishedList;
    }
}
TOP

Related Classes of com.projectnine.csvmapper.ObjectToCsvMapper

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.