CSVResultSetHelper.java

package org.genesys.server.service.impl;

import java.io.IOException;
import java.io.Reader;
import java.sql.Clob;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import org.apache.commons.text.TextStringBuilder;
import org.genesys.util.NumberUtils;

import com.opencsv.ResultSetHelperService;

/**
 * This class extends {@link ResultSetHelperService} by adding support for UUID.
 * Copied straigth from superclass.
 */
public class CSVResultSetHelper extends ResultSetHelperService {

	public static final int CLOBBUFFERSIZE = 2048;

	// note: we want to maintain compatibility with Java 5 VM's
	// These types don't exist in Java 5
	private static final int NVARCHAR = -9;
	private static final int NCHAR = -15;
	private static final int LONGNVARCHAR = -16;
	private static final int NCLOB = 2011;

	/**
	 * Get all the column values from the result set.
	 * 
	 * @param rs
	 *            - the ResultSet containing the values.
	 * @param trim
	 *            - values should have white spaces trimmed.
	 * @param dateFormatString
	 *            - format String for dates.
	 * @param timeFormatString
	 *            - format String for timestamps.
	 * @return - String array containing all the column values.
	 * @throws SQLException
	 *             - thrown by the result set.
	 * @throws IOException
	 *             - thrown by the result set.
	 */
	@Override
	public String[] getColumnValues(ResultSet rs, boolean trim, String dateFormatString, String timeFormatString) throws SQLException, IOException {
		List<String> values = new ArrayList<String>();
		ResultSetMetaData metadata = rs.getMetaData();

		for (int i = 0; i < metadata.getColumnCount(); i++) {
			values.add(getColumnValue(rs, metadata.getColumnType(i + 1), i + 1, trim, dateFormatString, timeFormatString));
		}

		String[] valueArray = new String[values.size()];
		return values.toArray(valueArray);
	}

	private String handleBinary(ResultSet rs, int colIndex) throws SQLException {
		byte[] bs = rs.getBytes(colIndex);

		if (bs == null) {
			return null;
		}

		if (bs.length == 16) {
			// UUID?
			UUID uuid = NumberUtils.toUUID(bs);
			return uuid.toString();
		} else {
			// TODO FIXME What to do with other binary?
			return "";
		}
	}

	private static String read(Clob c) throws SQLException, IOException {
		StringBuilder sb = new StringBuilder((int) c.length());
		Reader r = c.getCharacterStream();
		char[] cbuf = new char[CLOBBUFFERSIZE];
		int n;
		while ((n = r.read(cbuf, 0, cbuf.length)) != -1) {
			sb.append(cbuf, 0, n);
		}
		return sb.toString();
	}

	private String getColumnValue(ResultSet rs, int colType, int colIndex, boolean trim, String dateFormatString, String timestampFormatString) throws SQLException, IOException {

		String value = "";

		switch (colType) {
		case Types.BIT:
		case Types.JAVA_OBJECT:
			// Once Java 7 is the minimum supported version.
			// value = Objects.toString(rs.getObject(colIndex), "");
			value = Objects.toString(rs.getObject(colIndex), "");
			break;
		case Types.BOOLEAN:
			// Once Java 7 is the minimum supported version.
			// value = Objects.toString(rs.getBoolean(colIndex));
			value = Objects.toString(rs.getBoolean(colIndex));
			break;
		case Types.NCLOB: // todo : use rs.getNClob
		case Types.CLOB:
			Clob c = rs.getClob(colIndex);
			if (c != null) {
				TextStringBuilder sb = new TextStringBuilder();
				sb.readFrom(c.getCharacterStream());
				value = sb.toString();
			}
			break;
		case Types.BIGINT:
			// Once Java 7 is the minimum supported version.
			// value = Objects.toString(rs.getLong(colIndex));
			value = Objects.toString(rs.getLong(colIndex));
			break;
		case Types.DECIMAL:
		case Types.REAL:
		case Types.NUMERIC:
			// Once Java 7 is the minimum supported version.
			// value = Objects.toString(rs.getBigDecimal(colIndex), "");
			value = Objects.toString(rs.getBigDecimal(colIndex), "");
			break;
		case Types.DOUBLE:
			// Once Java 7 is the minimum supported version.
			// value = Objects.toString(rs.getDouble(colIndex));
			value = Objects.toString(rs.getDouble(colIndex));
			break;
		case Types.FLOAT:
			// Once Java 7 is the minimum supported version.
			// value = Objects.toString(rs.getFloat(colIndex));
			value = Objects.toString(rs.getFloat(colIndex));
			break;
		case Types.INTEGER:
		case Types.TINYINT:
		case Types.SMALLINT:
			// Once Java 7 is the minimum supported version.
			// value = Objects.toString(rs.getInt(colIndex));
			value = Objects.toString(rs.getInt(colIndex));
			break;
		case Types.DATE:
			java.sql.Date date = rs.getDate(colIndex);
			if (date != null) {
				SimpleDateFormat df = new SimpleDateFormat(dateFormatString);
				value = df.format(date);
			}
			break;
		case Types.TIME:
			// Once Java 7 is the minimum supported version.
			// value = Objects.toString(rs.getTime(colIndex), "");
			value = Objects.toString(rs.getTime(colIndex), "");
			break;
		case Types.TIMESTAMP:
			value = handleTimestamp(rs.getTimestamp(colIndex), timestampFormatString);
			break;
		case Types.NVARCHAR: // todo : use rs.getNString
		case Types.NCHAR: // todo : use rs.getNString
		case Types.LONGNVARCHAR: // todo : use rs.getNString
		case Types.LONGVARCHAR:
		case Types.VARCHAR:
		case Types.CHAR:
			String columnValue = rs.getString(colIndex);
			if (trim && columnValue != null) {
				value = columnValue.trim();
			} else {
				value = columnValue;
			}
			break;
		default:
			value = "";
		}

		if (rs.wasNull() || value == null) {
			value = "";
		}

		return value;
	}
}