package com.w11k.lsql.converter; import com.w11k.lsql.LSql; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Arrays; public abstract class Converter { public static Converter withDefaultValueForNull(final Converter delegate, final Object defaultValueForNull) { return new Converter(delegate.getJavaType(), delegate.getSqlTypes(), delegate.getSqlTypeForNullValues()) { @Override protected void setValue(LSql lSql, PreparedStatement ps, int index, Object val) throws SQLException { delegate.setValue(lSql, ps, index, val); } @Override protected Object getValue(LSql lSql, ResultSet rs, int index) throws SQLException { return delegate.getValue(lSql, rs, index); } @Override protected Object getDefaultValueForNull(LSql lSql, ResultSet rs, int index) { return defaultValueForNull; } }; } private final Class<?> javaType; private final int[] sqlTypes; private final int sqlTypeForNullValues; public Converter(Class<?> javaType, int[] sqlTypes, int sqlTypeForNullValues) { this.javaType = javaType; this.sqlTypes = sqlTypes; this.sqlTypeForNullValues = sqlTypeForNullValues; } public void setValueInStatement(LSql lSql, PreparedStatement ps, int index, Object val) throws SQLException { if (val != null) { failOnWrongValueType(val); setValue(lSql, ps, index, val); } else { ps.setNull(index, sqlTypeForNullValues); } } public void failOnWrongValueType(Object val) { if (!isValueValid(val)) { throw new IllegalArgumentException( "value '" + val + "' of type '" + val.getClass().getCanonicalName() + "' " + "does not match expected type " + "'" + getJavaType().getCanonicalName() + "'" ); } } public Object getValueFromResultSet(LSql lSql, ResultSet rs, int index) throws SQLException { rs.getObject(index); if (rs.wasNull()) { return this.getDefaultValueForNull(lSql, rs, index); } return getValue(lSql, rs, index); } public boolean isValueValid(Object value) { if (value == null) { return isNullValid(); } return javaType.isAssignableFrom(value.getClass()); } public boolean supportsSqlType(int sqlType) { for (int type : this.sqlTypes) { if (type == sqlType) { return true; } } return false; } public Class<?> getJavaType() { return javaType; } public int[] getSqlTypes() { return sqlTypes; } public int getSqlTypeForNullValues() { return sqlTypeForNullValues; } @Override public String toString() { return "Converter{" + "javaType=" + javaType + ", sqlTypes=" + Arrays.toString(sqlTypes) + ", sqlTypeForNullValues=" + sqlTypeForNullValues + '}'; } protected abstract void setValue(LSql lSql, PreparedStatement ps, int index, Object val) throws SQLException; protected abstract Object getValue(LSql lSql, ResultSet rs, int index) throws SQLException; protected boolean isNullValid() { return true; } protected Object getDefaultValueForNull(LSql lSql, ResultSet rs, int index) { return null; } }