View Javadoc
1   package com.opencsv;
2   /*
3    Copyright 2005 Bytecode Pty Ltd.
4   
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8   
9    http://www.apache.org/licenses/LICENSE-2.0
10  
11   Unless required by applicable law or agreed to in writing, software
12   distributed under the License is distributed on an "AS IS" BASIS,
13   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   See the License for the specific language governing permissions and
15   limitations under the License.
16   */
17  
18  import org.apache.commons.lang3.StringUtils;
19  import org.apache.commons.text.TextStringBuilder;
20  
21  import java.io.IOException;
22  import java.sql.*;
23  import java.text.NumberFormat;
24  import java.text.SimpleDateFormat;
25  import java.util.Objects;
26  
27  /**
28   * Helper class for processing JDBC ResultSet objects.
29   */
30  public class ResultSetHelperService implements ResultSetHelper {
31     protected static final int CLOBBUFFERSIZE = 2048;
32  
33     static final String DEFAULT_DATE_FORMAT = "dd-MMM-yyyy";
34     static final String DEFAULT_TIMESTAMP_FORMAT = "dd-MMM-yyyy HH:mm:ss";
35     private static final String NULL_DEFAULT_VALUE = StringUtils.EMPTY;
36  
37     protected String dateFormat = DEFAULT_DATE_FORMAT;
38     protected String dateTimeFormat = DEFAULT_TIMESTAMP_FORMAT;
39     protected NumberFormat integerFormat;
40     protected NumberFormat floatingPointFormat;
41     protected String nullDefault = NULL_DEFAULT_VALUE;
42  
43     /**
44      * Default constructor.
45      */
46     public ResultSetHelperService() {
47     }
48  
49     /**
50      * Set a default date format pattern that will be used by the service.
51      *
52      * @param dateFormat Desired date format
53      */
54     public void setDateFormat(String dateFormat) {
55        this.dateFormat = dateFormat;
56     }
57  
58     /**
59      * Set a default date time format pattern that will be used by the service.
60      *
61      * @param dateTimeFormat Desired date time format
62      */
63     public void setDateTimeFormat(String dateTimeFormat) {
64        this.dateTimeFormat = dateTimeFormat;
65     }
66  
67     /**
68      * Set a default number formatter for floating point numbers that will be used by the service.
69      *
70      * @param format Desired number format. Should not be null
71      */
72     public void setIntegerFormat(NumberFormat format) {
73        this.integerFormat = format;
74     }
75  
76     /**
77      * Set a default number formatter for integer numbers that will be used by the service.
78      *
79      * @param format Desired number format. Should not be null
80      */
81     public void setFloatingPointFormat(NumberFormat format) {
82        this.floatingPointFormat = format;
83     }
84  
85     /**
86      * Set a default value that will be used when column value is null.
87      *
88      * @param nullDefault
89      */
90     public void setNullDefault(String nullDefault) {
91        this.nullDefault = nullDefault;
92     }
93  
94     @Override
95     public String[] getColumnNames(ResultSet rs) throws SQLException {
96        ResultSetMetaData metadata = rs.getMetaData();
97        String[] nameArray = new String[metadata.getColumnCount()];
98        for (int i = 0; i < metadata.getColumnCount(); i++) {
99           nameArray[i] = metadata.getColumnLabel(i+1);
100       }
101       return nameArray;
102    }
103 
104    @Override
105    public String[] getColumnValues(ResultSet rs) throws SQLException, IOException {
106       return this.getColumnValues(rs, false, dateFormat, dateTimeFormat);
107    }
108 
109    @Override
110    public String[] getColumnValues(ResultSet rs, boolean trim) throws SQLException, IOException {
111       return this.getColumnValues(rs, trim, dateFormat, dateTimeFormat);
112    }
113 
114    @Override
115    public String[] getColumnValues(ResultSet rs, boolean trim, String dateFormatString, String timeFormatString) throws SQLException, IOException {
116       ResultSetMetaData metadata = rs.getMetaData();
117       String[] valueArray = new String[metadata.getColumnCount()];
118       for (int i = 1; i <= metadata.getColumnCount(); i++) {
119          valueArray[i-1] = getColumnValue(rs, metadata.getColumnType(i), i,
120                trim, dateFormatString, timeFormatString);
121       }
122       return valueArray;
123    }
124 
125    /**
126     * The formatted timestamp.
127     * @param timestamp Timestamp read from resultset
128     * @param timestampFormatString Format string
129     * @return Formatted time stamp.
130     */
131    protected String handleTimestamp(Timestamp timestamp, String timestampFormatString) {
132       SimpleDateFormat timeFormat = new SimpleDateFormat(timestampFormatString);
133       return timestamp == null ? null : timeFormat.format(timestamp);
134    }
135 
136    private String getColumnValue(ResultSet rs, int colType, int colIndex, boolean trim, String dateFormatString, String timestampFormatString)
137          throws SQLException, IOException {
138 
139       String value;
140 
141       switch (colType) {
142          case Types.BOOLEAN:
143             value = Objects.toString(rs.getBoolean(colIndex));
144             break;
145          case Types.NCLOB:
146             value = handleNClob(rs, colIndex);
147             break;
148          case Types.CLOB:
149             value = handleClob(rs, colIndex);
150             break;
151          case Types.BIGINT:
152             value = applyFormatter(integerFormat, rs.getBigDecimal(colIndex));
153             break;
154          case Types.DECIMAL:
155          case Types.REAL:
156          case Types.NUMERIC:
157             value = applyFormatter(floatingPointFormat, rs.getBigDecimal(colIndex));
158             break;
159          case Types.DOUBLE:
160             value = applyFormatter(floatingPointFormat, rs.getDouble(colIndex));
161             break;
162          case Types.FLOAT:
163             value = applyFormatter(floatingPointFormat, rs.getFloat(colIndex));
164             break;
165          case Types.INTEGER:
166          case Types.TINYINT:
167          case Types.SMALLINT:
168             value = applyFormatter(integerFormat, rs.getInt(colIndex));
169             break;
170          case Types.DATE:
171             value = handleDate(rs, colIndex, dateFormatString);
172             break;
173          case Types.TIME:
174             value = Objects.toString(rs.getTime(colIndex), nullDefault);
175             break;
176          case Types.TIMESTAMP:
177             value = handleTimestamp(rs.getTimestamp(colIndex), timestampFormatString);
178             break;
179          case Types.NVARCHAR:
180          case Types.NCHAR:
181          case Types.LONGNVARCHAR:
182             value = handleNVarChar(rs, colIndex, trim);
183             break;
184          case Types.LONGVARCHAR:
185          case Types.VARCHAR:
186          case Types.CHAR:
187             value = handleVarChar(rs, colIndex, trim);
188             break;
189          default:
190             // This takes care of Types.BIT, Types.JAVA_OBJECT, and anything
191             // unknown.
192             value = Objects.toString(rs.getObject(colIndex), nullDefault);
193       }
194 
195 
196       if (rs.wasNull() || value == null) {
197          value = nullDefault;
198       }
199 
200       return value;
201    }
202 
203    private String applyFormatter(NumberFormat formatter, Number value) {
204       if (formatter != null && value != null) {
205          return formatter.format(value);
206       }
207       return Objects.toString(value, nullDefault);
208    }
209 
210    /**
211     * retrieves the data from an VarChar in a result set
212     *
213     * @param rs       - result set
214     * @param colIndex - column location of the data in the result set
215     * @param trim     - should the value be trimmed before being returned
216     * @return a string representing the VarChar from the result set
217     * @throws SQLException
218     */
219    protected String handleVarChar(ResultSet rs, int colIndex, boolean trim) throws SQLException {
220       String value;
221       String columnValue = rs.getString(colIndex);
222       if (trim && columnValue != null) {
223          value = columnValue.trim();
224       } else {
225          value = columnValue;
226       }
227       return value;
228    }
229 
230    /**
231     * retrieves the data from an NVarChar in a result set
232     *
233     * @param rs       - result set
234     * @param colIndex - column location of the data in the result set
235     * @param trim     - should the value be trimmed before being returned
236     * @return a string representing the NVarChar from the result set
237     * @throws SQLException
238     */
239    protected String handleNVarChar(ResultSet rs, int colIndex, boolean trim) throws SQLException {
240       String value;
241       String nColumnValue = rs.getNString(colIndex);
242       if (trim && nColumnValue != null) {
243          value = nColumnValue.trim();
244       } else {
245          value = nColumnValue;
246       }
247       return value;
248    }
249 
250    /**
251     * retrieves an date from a result set
252     *
253     * @param rs               - result set
254     * @param colIndex         - column location of the data in the result set
255     * @param dateFormatString - desired format of the date
256     * @return - a string representing the data from the result set in the format set in dateFomratString.
257     * @throws SQLException
258     */
259    protected String handleDate(ResultSet rs, int colIndex, String dateFormatString) throws SQLException {
260       String value = nullDefault;
261       Date date = rs.getDate(colIndex);
262       if (date != null) {
263          SimpleDateFormat df = new SimpleDateFormat(dateFormatString);
264          value = df.format(date);
265       }
266       return value;
267    }
268 
269    /**
270     * retrieves the data out of a CLOB
271     *
272     * @param rs       - result set
273     * @param colIndex - column location of the data in the result set
274     * @return the data in the Clob as a string.
275     * @throws SQLException
276     * @throws IOException
277     */
278    protected String handleClob(ResultSet rs, int colIndex) throws SQLException, IOException {
279       String value = nullDefault;
280       Clob c = rs.getClob(colIndex);
281       if (c != null) {
282          TextStringBuilder sb = new TextStringBuilder();
283          sb.readFrom(c.getCharacterStream());
284          value = sb.toString();
285       }
286       return value;
287    }
288 
289    /**
290     * retrieves the data out of a NCLOB
291     *
292     * @param rs       - result set
293     * @param colIndex - column location of the data in the result set
294     * @return the data in the NCLOB as a string.
295     * @throws SQLException
296     * @throws IOException
297     */
298    protected String handleNClob(ResultSet rs, int colIndex) throws SQLException, IOException {
299       String value = nullDefault;
300       NClob nc = rs.getNClob(colIndex);
301       if (nc != null) {
302          TextStringBuilder sb = new TextStringBuilder();
303          sb.readFrom(nc.getCharacterStream());
304          value = sb.toString();
305       }
306       return value;
307    }
308 }