/src/main/java/com/t11e/discovery/datatool/ResultSetConvertor.java
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}