PageRenderTime 91ms CodeModel.GetById 77ms app.highlight 12ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/t11e/discovery/datatool/ResultSetConvertor.java

http://github.com/t11e/discovery_datatool
Java | 221 lines | 207 code | 10 blank | 4 comment | 27 complexity | 14c4c828f6fbe3946a8f9515b7e3206d MD5 | raw file
  1package com.t11e.discovery.datatool;
  2
  3import java.sql.ResultSet;
  4import java.sql.ResultSetMetaData;
  5import java.sql.SQLException;
  6import java.util.ArrayList;
  7import java.util.Collections;
  8import java.util.HashMap;
  9import java.util.HashSet;
 10import java.util.LinkedHashMap;
 11import java.util.List;
 12import java.util.Map;
 13import java.util.Set;
 14
 15import org.apache.commons.lang.StringUtils;
 16
 17import com.t11e.discovery.datatool.column.BooleanColumnProcessor;
 18import com.t11e.discovery.datatool.column.DateColumnProcessor;
 19import com.t11e.discovery.datatool.column.IItemPropertiesFromColumnProcessor;
 20import com.t11e.discovery.datatool.column.ItemPropertiesFromColumnProcessor;
 21import com.t11e.discovery.datatool.column.ItemPropertiesFromUnscopedJsonColumnProcessor;
 22import com.t11e.discovery.datatool.column.JsonColumnProcessor;
 23import com.t11e.discovery.datatool.column.LowerCaseStringColumnProcessor;
 24import com.t11e.discovery.datatool.column.StringColumnProcessor;
 25import com.t11e.discovery.datatool.column.TimeColumnProcessor;
 26import com.t11e.discovery.datatool.column.TimestampColumnProcessor;
 27import com.t11e.discovery.datatool.column.UpperCaseStringColumnProcessor;
 28
 29public class ResultSetConvertor
 30{
 31  private static final IItemPropertiesFromColumnProcessor JSON = new ItemPropertiesFromColumnProcessor(
 32    JsonColumnProcessor.INSTANCE);
 33  private static final IItemPropertiesFromColumnProcessor[] LOWER_STRING = new IItemPropertiesFromColumnProcessor[]{
 34      new ItemPropertiesFromColumnProcessor(LowerCaseStringColumnProcessor.INSTANCE)};
 35  private static final IItemPropertiesFromColumnProcessor[] UPPER_STRING = new IItemPropertiesFromColumnProcessor[]{
 36      new ItemPropertiesFromColumnProcessor(UpperCaseStringColumnProcessor.INSTANCE)};
 37  private static final IItemPropertiesFromColumnProcessor[] STRING = new IItemPropertiesFromColumnProcessor[]{
 38      new ItemPropertiesFromColumnProcessor(StringColumnProcessor.INSTANCE)};
 39  private static final IItemPropertiesFromColumnProcessor[] DATE = new IItemPropertiesFromColumnProcessor[]{
 40      new ItemPropertiesFromColumnProcessor(DateColumnProcessor.INSTANCE)};
 41  private static final IItemPropertiesFromColumnProcessor[] TIME = new IItemPropertiesFromColumnProcessor[]{
 42      new ItemPropertiesFromColumnProcessor(TimeColumnProcessor.INSTANCE)};
 43  private static final IItemPropertiesFromColumnProcessor[] TIMESTAMP = new IItemPropertiesFromColumnProcessor[]{
 44      new ItemPropertiesFromColumnProcessor(TimestampColumnProcessor.INSTANCE)};
 45
 46  private final PropertyCase propertyCase;
 47  private final Set<String> scopedJsonColumns;
 48  private final Set<String> unscopedJsonColumns;
 49  private final Set<String> changeValueCaseColumns;
 50  private IItemPropertiesFromColumnProcessor[][] columnProcessors;
 51  private String[] columnNames;
 52  private Map<String, String> lowercaseKeyToActualKey = Collections.emptyMap();
 53
 54  public ResultSetConvertor(final PropertyCase propertyCase, final Set<String> scopedJsonColumns,
 55    final Set<String> unscopedJsonColumns,
 56    final Set<String> potentialChangeValueCaseColumns)
 57  {
 58    this.propertyCase = propertyCase;
 59    if (PropertyCase.LEGACY != propertyCase && PropertyCase.PRESERVE != propertyCase && potentialChangeValueCaseColumns != null)
 60    {
 61      changeValueCaseColumns = new HashSet<String>(potentialChangeValueCaseColumns.size());
 62      for (final String columnLabel : potentialChangeValueCaseColumns)
 63      {
 64        changeValueCaseColumns.add(propertyCase.convert(columnLabel));
 65      }
 66    }
 67    else
 68    {
 69      changeValueCaseColumns = Collections.emptySet();
 70    }
 71    this.scopedJsonColumns = scopedJsonColumns != null ? scopedJsonColumns : Collections.<String> emptySet();
 72    this.unscopedJsonColumns = unscopedJsonColumns != null ? unscopedJsonColumns : Collections.<String> emptySet();
 73  }
 74
 75  public Map<String, Object> getRowAsMap(final ResultSet rs)
 76    throws SQLException
 77  {
 78    lazyInitialize(rs);
 79    final Map<String, Object> properties = new LinkedHashMap<String, Object>();
 80    for (int idx = 0; idx < columnProcessors.length; ++idx)
 81    {
 82      final int column = idx + 1;
 83      final IItemPropertiesFromColumnProcessor[] processors = columnProcessors[idx];
 84      if (processors != null)
 85      {
 86        final String name = columnNames[idx];
 87        for (final IItemPropertiesFromColumnProcessor processor : processors)
 88        {
 89          processor.processColumn(properties, rs, column, name);
 90        }
 91      }
 92    }
 93    return properties;
 94  }
 95
 96  /**
 97   * Given a potential column alias, return the actual column alias if a match is found ignoring case in the available column aliases.
 98   * Can only be called after getRowAsMap().
 99   */
100  public String getKey(final String potentialKey)
101  {
102    return lowercaseKeyToActualKey.get(StringUtils.lowerCase(potentialKey));
103  }
104
105  private void lazyInitialize(final ResultSet rs)
106    throws SQLException
107  {
108    if (columnProcessors == null)
109    {
110      final ResultSetMetaData metaData = rs.getMetaData();
111      final IItemPropertiesFromColumnProcessor[][] processors = new IItemPropertiesFromColumnProcessor[metaData.getColumnCount()][];
112      final String[] names = new String[processors.length];
113      lowercaseKeyToActualKey = new HashMap<String, String>();
114      for (int idx = 0; idx < processors.length; idx++)
115      {
116        final int column = idx + 1;
117        final String columnName = metaData.getColumnLabel(column);
118        final String convertedName = propertyCase.convert(columnName);
119        names[idx] = convertedName;
120        processors[idx] = getColumnProcessor(metaData, column, convertedName);
121        lowercaseKeyToActualKey.put(StringUtils.lowerCase(convertedName), convertedName);
122      }
123      columnProcessors = processors;
124      columnNames = names;
125    }
126  }
127
128  private IItemPropertiesFromColumnProcessor[] getColumnProcessor(
129    final ResultSetMetaData md,
130    final int column,
131    final String columnLabel)
132    throws SQLException
133  {
134    IItemPropertiesFromColumnProcessor[] output;
135    switch (md.getColumnType(column))
136    {
137      case java.sql.Types.BIT:
138      case java.sql.Types.BOOLEAN:
139        output = new ItemPropertiesFromColumnProcessor[]{new ItemPropertiesFromColumnProcessor(BooleanColumnProcessor.INSTANCE)};
140        break;
141      case java.sql.Types.TINYINT:
142      case java.sql.Types.SMALLINT:
143      case java.sql.Types.INTEGER:
144      case java.sql.Types.BIGINT:
145      case java.sql.Types.FLOAT:
146      case java.sql.Types.REAL:
147      case java.sql.Types.DOUBLE:
148      case java.sql.Types.NUMERIC:
149      case java.sql.Types.DECIMAL:
150        output = STRING;
151        break;
152      case java.sql.Types.CHAR:
153      case java.sql.Types.VARCHAR:
154      case java.sql.Types.LONGVARCHAR:
155      case java.sql.Types.CLOB:
156      {
157        final String columnLabelLower = StringUtils.lowerCase(columnLabel);
158        if (columnLabel != null &&
159          (scopedJsonColumns.contains(columnLabelLower)
160          || unscopedJsonColumns.contains(columnLabelLower)))
161        {
162          final List<IItemPropertiesFromColumnProcessor> jsonProcessors = new ArrayList<IItemPropertiesFromColumnProcessor>(2);
163          if (scopedJsonColumns.contains(columnLabelLower))
164          {
165            jsonProcessors.add(JSON);
166          }
167          if (unscopedJsonColumns.contains(columnLabelLower))
168          {
169            jsonProcessors.add(new ItemPropertiesFromUnscopedJsonColumnProcessor(JsonColumnProcessor.INSTANCE, propertyCase));
170          }
171          output = jsonProcessors.toArray(new IItemPropertiesFromColumnProcessor[jsonProcessors.size()]);
172        }
173        else if (columnLabel != null && changeValueCaseColumns.contains(columnLabel))
174        {
175          switch (propertyCase)
176          {
177            case LOWER:
178              output = LOWER_STRING;
179              break;
180            case UPPER:
181              output = UPPER_STRING;
182              break;
183            default:
184              output = STRING;
185              break;
186          }
187        }
188        else
189        {
190          output = STRING;
191        }
192        break;
193      }
194      case java.sql.Types.DATE:
195        output = DATE;
196        break;
197      case java.sql.Types.TIME:
198        output = TIME;
199        break;
200      case java.sql.Types.TIMESTAMP:
201        output = TIMESTAMP;
202        break;
203      case java.sql.Types.BINARY:
204      case java.sql.Types.VARBINARY:
205      case java.sql.Types.LONGVARBINARY:
206      case java.sql.Types.NULL:
207      case java.sql.Types.OTHER:
208      case java.sql.Types.JAVA_OBJECT:
209      case java.sql.Types.DISTINCT:
210      case java.sql.Types.STRUCT:
211      case java.sql.Types.ARRAY:
212      case java.sql.Types.BLOB:
213      case java.sql.Types.REF:
214      case java.sql.Types.DATALINK:
215      default:
216        output = null;
217        break;
218    }
219    return output;
220  }
221}