it.greenvulcano.gvesb.datahandling.dbo.utils.StandardRowSetBuilder.java Source code

Java tutorial

Introduction

Here is the source code for it.greenvulcano.gvesb.datahandling.dbo.utils.StandardRowSetBuilder.java

Source

/*******************************************************************************
 * Copyright (c) 2009, 2016 GreenVulcano ESB Open Source Project.
 * All rights reserved.
 *
 * This file is part of GreenVulcano ESB.
 *
 * GreenVulcano ESB 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.
 *
 * GreenVulcano ESB 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 GreenVulcano ESB. If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
package it.greenvulcano.gvesb.datahandling.dbo.utils;

import it.greenvulcano.gvesb.datahandling.dbo.AbstractDBO;
import it.greenvulcano.gvesb.datahandling.utils.FieldFormatter;
import it.greenvulcano.util.thread.ThreadUtils;
import it.greenvulcano.util.xml.XMLUtils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.NClob;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

/**
 * 
 * @version 3.4.0 06/ago/2013
 * @author GreenVulcano Developer Team
 * 
 */
public class StandardRowSetBuilder implements RowSetBuilder {
    private String name;
    private Logger logger;
    private String numberFormat;
    private String groupSeparator;
    private String decSeparator;
    private XMLUtils parser;
    private SimpleDateFormat dateFormatter;
    private SimpleDateFormat timeFormatter;
    private DecimalFormat numberFormatter;

    public Document createDocument(XMLUtils parser) throws NullPointerException {
        if (parser == null) {
            parser = this.parser;
        }
        if (parser == null) {
            throw new NullPointerException("Parser not set");
        }
        Document doc = parser.newDocument(AbstractDBO.ROWSET_NAME);
        return doc;
    }

    public int build(Document doc, String id, ResultSet rs, Set<Integer> keyField,
            Map<String, FieldFormatter> fieldNameToFormatter, Map<String, FieldFormatter> fieldIdToFormatter)
            throws Exception {
        if (rs == null) {
            return 0;
        }
        int rowCounter = 0;
        Element docRoot = doc.getDocumentElement();
        ResultSetMetaData metadata = rs.getMetaData();
        FieldFormatter[] fFormatters = buildFormatterArray(metadata, fieldNameToFormatter, fieldIdToFormatter);

        boolean noKey = ((keyField == null) || keyField.isEmpty());

        //boolean isNull = false;
        Element data = null;
        Element row = null;
        Element col = null;
        Text text = null;
        String textVal = null;
        String precKey = null;
        String colKey = null;
        Map<String, String> keyAttr = new HashMap<String, String>();
        while (rs.next()) {
            if (rowCounter % 10 == 0) {
                ThreadUtils.checkInterrupted(getClass().getSimpleName(), name, logger);
            }
            row = parser.createElement(doc, AbstractDBO.ROW_NAME);

            parser.setAttribute(row, AbstractDBO.ID_NAME, id);
            for (int j = 1; j <= metadata.getColumnCount(); j++) {
                FieldFormatter fF = fFormatters[j];

                //isNull = false;
                col = parser.createElement(doc, AbstractDBO.COL_NAME);
                switch (metadata.getColumnType(j)) {
                case Types.DATE: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.DATE_TYPE);
                    java.sql.Date dateVal = rs.getDate(j);
                    textVal = processDateTime(col, fF, dateVal, AbstractDBO.DEFAULT_DATE_FORMAT);
                }
                    break;
                case Types.TIME: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.TIME_TYPE);
                    java.sql.Time dateVal = rs.getTime(j);
                    textVal = processDateTime(col, fF, dateVal, AbstractDBO.DEFAULT_TIME_FORMAT);
                }
                    break;
                case Types.TIMESTAMP: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.TIMESTAMP_TYPE);
                    Timestamp dateVal = rs.getTimestamp(j);
                    textVal = processDateTime(col, fF, dateVal, AbstractDBO.DEFAULT_DATE_FORMAT);
                }
                    break;
                case Types.DOUBLE: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.FLOAT_TYPE);
                    double numVal = rs.getDouble(j);
                    textVal = processDouble(col, fF, numVal);
                }
                    break;
                case Types.FLOAT:
                case Types.REAL: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.FLOAT_TYPE);
                    float numVal = rs.getFloat(j);
                    textVal = processDouble(col, fF, numVal);
                }
                    break;
                case Types.BIGINT: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.BIGINT_TYPE);
                    long numVal = rs.getLong(j);
                    parser.setAttribute(col, AbstractDBO.NULL_NAME, "false");
                    textVal = String.valueOf(numVal);
                }
                    break;
                case Types.INTEGER: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.INTEGER_TYPE);
                    int numVal = rs.getInt(j);
                    parser.setAttribute(col, AbstractDBO.NULL_NAME, "false");
                    textVal = String.valueOf(numVal);
                }
                    break;
                case Types.SMALLINT:
                case Types.TINYINT: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.SMALLINT_TYPE);
                    short numVal = rs.getShort(j);
                    parser.setAttribute(col, AbstractDBO.NULL_NAME, "false");
                    textVal = String.valueOf(numVal);
                }
                    break;
                case Types.NUMERIC:
                case Types.DECIMAL: {
                    BigDecimal bigdecimal = rs.getBigDecimal(j);
                    boolean isNull = bigdecimal == null;
                    parser.setAttribute(col, AbstractDBO.NULL_NAME, String.valueOf(isNull));
                    if (isNull) {
                        if (metadata.getScale(j) > 0) {
                            parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.DECIMAL_TYPE);
                        } else {
                            parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.NUMERIC_TYPE);
                        }
                        textVal = "";
                    } else {
                        if (fF != null) {
                            parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.DECIMAL_TYPE);
                            parser.setAttribute(col, AbstractDBO.FORMAT_NAME, fF.getNumberFormat());
                            parser.setAttribute(col, AbstractDBO.GRP_SEPARATOR_NAME, fF.getGroupSeparator());
                            parser.setAttribute(col, AbstractDBO.DEC_SEPARATOR_NAME, fF.getDecSeparator());
                            textVal = fF.formatNumber(bigdecimal);
                        } else if (metadata.getScale(j) > 0) {
                            parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.DECIMAL_TYPE);
                            parser.setAttribute(col, AbstractDBO.FORMAT_NAME, numberFormat);
                            parser.setAttribute(col, AbstractDBO.GRP_SEPARATOR_NAME, groupSeparator);
                            parser.setAttribute(col, AbstractDBO.DEC_SEPARATOR_NAME, decSeparator);
                            textVal = numberFormatter.format(bigdecimal);
                        } else {
                            parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.NUMERIC_TYPE);
                            textVal = bigdecimal.toString();
                        }
                    }
                }
                    break;
                case Types.BOOLEAN: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.BOOLEAN_TYPE);
                    boolean bVal = rs.getBoolean(j);
                    parser.setAttribute(col, AbstractDBO.NULL_NAME, "false");
                    textVal = String.valueOf(bVal);
                }
                    break;
                case Types.SQLXML: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.XML_TYPE);
                    SQLXML xml = rs.getSQLXML(j);
                    boolean isNull = xml == null;
                    parser.setAttribute(col, AbstractDBO.NULL_NAME, String.valueOf(isNull));
                    if (isNull) {
                        textVal = "";
                    } else {
                        textVal = xml.getString();
                    }
                }
                    break;
                case Types.NCHAR:
                case Types.NVARCHAR: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.NSTRING_TYPE);
                    textVal = rs.getNString(j);
                    if (textVal == null) {
                        textVal = "";
                    }
                }
                    break;
                case Types.CHAR:
                case Types.VARCHAR: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.STRING_TYPE);
                    textVal = rs.getString(j);
                    boolean isNull = textVal == null;
                    parser.setAttribute(col, AbstractDBO.NULL_NAME, String.valueOf(isNull));
                    if (isNull) {
                        textVal = "";
                    }
                }
                    break;
                case Types.NCLOB: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.LONG_NSTRING_TYPE);
                    NClob clob = rs.getNClob(j);
                    if (clob != null) {
                        Reader is = clob.getCharacterStream();
                        StringWriter str = new StringWriter();

                        IOUtils.copy(is, str);
                        is.close();
                        textVal = str.toString();
                    } else {
                        textVal = "";
                    }
                }
                    break;
                case Types.CLOB: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.LONG_STRING_TYPE);
                    Clob clob = rs.getClob(j);
                    if (clob != null) {
                        Reader is = clob.getCharacterStream();
                        StringWriter str = new StringWriter();

                        IOUtils.copy(is, str);
                        is.close();
                        textVal = str.toString();
                    } else {
                        textVal = "";
                    }
                }
                    break;
                case Types.BLOB: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.BASE64_TYPE);
                    Blob blob = rs.getBlob(j);
                    boolean isNull = blob == null;
                    parser.setAttribute(col, AbstractDBO.NULL_NAME, String.valueOf(isNull));
                    if (isNull) {
                        textVal = "";
                    } else {
                        InputStream is = blob.getBinaryStream();
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        IOUtils.copy(is, baos);
                        is.close();
                        try {
                            byte[] buffer = Arrays.copyOf(baos.toByteArray(), (int) blob.length());
                            textVal = Base64.getEncoder().encodeToString(buffer);
                        } catch (SQLFeatureNotSupportedException exc) {
                            textVal = Base64.getEncoder().encodeToString(baos.toByteArray());
                        }
                    }
                }
                    break;
                default: {
                    parser.setAttribute(col, AbstractDBO.TYPE_NAME, AbstractDBO.DEFAULT_TYPE);
                    textVal = rs.getString(j);
                    boolean isNull = textVal == null;
                    parser.setAttribute(col, AbstractDBO.NULL_NAME, String.valueOf(isNull));
                    if (isNull) {
                        textVal = "";
                    }
                }
                }
                if (textVal != null) {
                    text = doc.createTextNode(textVal);
                    col.appendChild(text);
                }
                if (!noKey && keyField.contains(new Integer(j))) {
                    if (textVal != null) {
                        if (colKey == null) {
                            colKey = textVal;
                        } else {
                            colKey += "##" + textVal;
                        }
                        keyAttr.put("key_" + j, textVal);
                    }
                } else {
                    row.appendChild(col);
                }
            }
            if (noKey) {
                if (data == null) {
                    data = parser.createElement(doc, AbstractDBO.DATA_NAME);
                    parser.setAttribute(data, AbstractDBO.ID_NAME, id);
                }
            } else if ((colKey != null) && !colKey.equals(precKey)) {
                if (data != null) {
                    docRoot.appendChild(data);
                }
                data = parser.createElement(doc, AbstractDBO.DATA_NAME);
                parser.setAttribute(data, AbstractDBO.ID_NAME, id);
                for (Entry<String, String> keyAttrEntry : keyAttr.entrySet()) {
                    parser.setAttribute(data, keyAttrEntry.getKey(), keyAttrEntry.getValue());
                }
                keyAttr.clear();
                precKey = colKey;
            }
            colKey = null;
            data.appendChild(row);
            rowCounter++;
        }
        if (data != null) {
            docRoot.appendChild(data);
        }

        return rowCounter;
    }

    /**
     * @param col
     * @param fF
     * @param numVal
     * @return
     * @throws NullPointerException
     * @throws Exception
     */
    private String processDouble(Element col, FieldFormatter fF, double numVal)
            throws NullPointerException, Exception {
        String textVal;
        parser.setAttribute(col, AbstractDBO.NULL_NAME, "false");
        if (fF != null) {
            parser.setAttribute(col, AbstractDBO.FORMAT_NAME, fF.getNumberFormat());
            parser.setAttribute(col, AbstractDBO.GRP_SEPARATOR_NAME, fF.getGroupSeparator());
            parser.setAttribute(col, AbstractDBO.DEC_SEPARATOR_NAME, fF.getDecSeparator());
            textVal = fF.formatNumber(numVal);
        } else {
            parser.setAttribute(col, AbstractDBO.FORMAT_NAME, numberFormat);
            parser.setAttribute(col, AbstractDBO.GRP_SEPARATOR_NAME, groupSeparator);
            parser.setAttribute(col, AbstractDBO.DEC_SEPARATOR_NAME, decSeparator);
            textVal = numberFormatter.format(numVal);
        }
        return textVal;
    }

    /**
     * @param col
     * @param fF
     * @param dateVal
     * @return
     * @throws Exception
     */
    private String processDateTime(Element col, FieldFormatter fF, Date dateVal, String format) throws Exception {
        String textVal;
        boolean isNull = dateVal == null;
        parser.setAttribute(col, AbstractDBO.NULL_NAME, String.valueOf(isNull));
        if (isNull) {
            parser.setAttribute(col, AbstractDBO.FORMAT_NAME, format);
            textVal = "";
        } else {
            if (fF != null) {
                parser.setAttribute(col, AbstractDBO.FORMAT_NAME, fF.getDateFormat());
                textVal = fF.formatDate(dateVal);
            } else {
                parser.setAttribute(col, AbstractDBO.FORMAT_NAME, format);
                if (dateVal instanceof Time) {
                    textVal = timeFormatter.format(dateVal);
                } else {
                    textVal = dateFormatter.format(dateVal);
                }
            }
        }
        return textVal;
    }

    public void cleanup() {
        numberFormat = null;
        groupSeparator = null;
        decSeparator = null;
        parser = null;
        dateFormatter = null;
        timeFormatter = null;
        numberFormatter = null;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setLogger(Logger logger) {
        this.logger = logger;
    }

    public void setDateFormatter(SimpleDateFormat dateFormatter) {
        this.dateFormatter = dateFormatter;
    }

    public void setTimeFormatter(SimpleDateFormat timeFormatter) {
        this.timeFormatter = timeFormatter;
    }

    public void setNumberFormatter(DecimalFormat numberFormatter) {
        this.numberFormatter = numberFormatter;
    }

    public void setDecSeparator(String decSeparator) {
        this.decSeparator = decSeparator;
    }

    public void setGroupSeparator(String groupSeparator) {
        this.groupSeparator = groupSeparator;
    }

    public void setNumberFormat(String numberFormat) {
        this.numberFormat = numberFormat;
    }

    public void setXMLUtils(XMLUtils parser) {
        this.parser = parser;
    }

    @Override
    public RowSetBuilder getCopy() {
        StandardRowSetBuilder copy = new StandardRowSetBuilder();

        copy.name = this.name;
        copy.logger = this.logger;
        copy.numberFormat = this.numberFormat;
        copy.groupSeparator = this.groupSeparator;
        copy.decSeparator = this.decSeparator;
        copy.parser = this.parser;
        copy.dateFormatter = this.dateFormatter;
        copy.numberFormatter = this.numberFormatter;

        return copy;
    }

    private FieldFormatter[] buildFormatterArray(ResultSetMetaData rsm,
            Map<String, FieldFormatter> fieldNameToFormatter, Map<String, FieldFormatter> fieldIdToFormatter)
            throws Exception {
        FieldFormatter[] fFA = new FieldFormatter[rsm.getColumnCount() + 1];

        for (int i = 1; i < fFA.length; i++) {
            FieldFormatter fF = fieldNameToFormatter.get(rsm.getColumnName(i));
            if (fF == null) {
                fF = fieldIdToFormatter.get("" + i);
            }
            fFA[i] = fF;
        }
        return fFA;
    }
}