acolyte.jdbc.ImmutableArray Maven / Gradle / Ivy
package acolyte.jdbc;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.sql.Array;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.EqualsBuilder;
/**
* Immutable Array implementation.
*
* @author Cedric Chantepie
*/
public final class ImmutableArray implements Array {
// --- Properties ---
/**
* Base (element) class
*/
protected final Class baseClass;
/**
* Base JDBC type (identifier)
*/
protected final int baseType;
/**
* Base JDBC type name
*/
protected final String baseTypeName;
/**
* Array elements
*/
protected final List elements;
// --- Constructors ---
/**
* Constructor
*
* @param baseClass the class of array elements
* @param elements the values of array elements
*/
private ImmutableArray(final Class baseClass,
final List elements) {
if (baseClass == null) {
throw new IllegalArgumentException("No base class");
} // end of
Integer jdbcType = Defaults.jdbcTypeClasses.get(baseClass.getName());
if (jdbcType == null) {
throw new IllegalArgumentException("Unsupported base class");
} // end of if
// ---
this.baseClass = baseClass;
this.baseType = jdbcType;
this.baseTypeName = Defaults.jdbcTypeNames.get(jdbcType);
this.elements = elements;
} // end of
/**
* Returns empty array for given base class.
*
* @param the type of array elements
* @param baseClass the class of array elements
* @return Empty array for given class
*/
public static ImmutableArray getInstance(final Class baseClass) { return new ImmutableArray(baseClass, Collections.unmodifiableList(Collections.emptyList())); }
/**
* Returns array with copy of given |elements|.
*
* @param the type of array elements
* @param baseClass the class of array elements
* @param elements the values of array elements
* @return New array
*/
public static ImmutableArray getInstance(final Class baseClass, final A[] elements) {
if (elements == null) {
throw new IllegalArgumentException("Invalid element array");
} // end of if
return new ImmutableArray(baseClass, Arrays.asList(elements));
} // end of getInstance
/**
* Returns array with copy of given |elements|.
*
* @param the type of array elements
* @param baseClass the class of array elements
* @param elements the values of array elements
* @return New array
*/
public static ImmutableArray getInstance(final Class baseClass, final List elements) {
if (elements == null) {
throw new IllegalArgumentException("Invalid element list");
} // end of if
return new ImmutableArray(baseClass,
Collections.unmodifiableList(elements));
} // end of getInstance
// ---
/**
* {@inheritDoc}
*/
public int getBaseType() throws SQLException {
return this.baseType;
} // end of getBaseType
/**
* {@inheritDoc}
*/
public String getBaseTypeName() throws SQLException {
return this.baseTypeName;
} // end of getBaseTypeName
/**
* {@inheritDoc}
*/
public Object getArray() throws SQLException {
@SuppressWarnings("Unchecked")
final T[] arr = (T[]) java.lang.reflect.Array.
newInstance(baseClass, this.elements.size());
return this.elements.toArray(arr);
} // end of getArray
/**
* @param map the SQL type mapping
* @return the array according the type mapping
* @throws SQLFeatureNotSupportedException as array convertion
* is not supported
*/
public Object getArray(Map> map) throws SQLException {
throw new SQLFeatureNotSupportedException();
} // end of getArray
/**
* {@inheritDoc}
*/
public Object getArray(final long index, final int count)
throws SQLException {
final List sub = subList(index, count);
if (sub == null) {
throw new SQLException("Invalid range: " + index + " + " + count);
} // end of if
// ---
@SuppressWarnings("Unchecked")
final T[] arr = (T[]) java.lang.reflect.Array.
newInstance(baseClass, sub.size());
return sub.toArray(arr);
} // end of getArray
/**
* @throws SQLFeatureNotSupportedException as array convertion
* is not supported
*/
public Object getArray(long index, int count,
Map> map) throws SQLException {
throw new SQLFeatureNotSupportedException();
} // end of getArray
/**
* {@inheritDoc}
*/
public ResultSet getResultSet() throws SQLException {
RowList1 rows = RowLists.rowList1(this.baseClass);
for (final T elmt : this.elements) rows = rows.append(elmt);
return rows.resultSet();
} // end of getResultSet
/**
* {@inheritDoc}
*/
public ResultSet getResultSet(final long index, final int count)
throws SQLException {
// TODO: Test
final List sub = subList(index, count);
if (sub == null) {
throw new SQLException("Invalid range: " + index + " + " + count);
} // end of if
// ---
RowList1 rows = RowLists.rowList1(this.baseClass);
for (final T elmt : sub) rows = rows.append(elmt);
return rows.resultSet();
} // end of getResultSet
/**
* @throws SQLFeatureNotSupportedException as array convertion
* is not supported
*/
public ResultSet getResultSet(Map> map)
throws SQLException {
throw new SQLFeatureNotSupportedException();
} // end of getResultSet
/**
* @throws SQLFeatureNotSupportedException as array convertion
* is not supported
*/
public ResultSet getResultSet(long index,
int count,
Map> map)
throws SQLException {
throw new SQLFeatureNotSupportedException();
} // end of getResultSet
/**
* Does nothing, as immutable.
*/
public void free() throws SQLException {}
// --- Object support ---
/**
* {@inheritDoc}
*/
public int hashCode() {
return new HashCodeBuilder(11, 7).
append(this.baseClass).append(this.baseType).
append(this.baseTypeName).append(this.elements).
toHashCode();
} // end of hashCode
/**
* {@inheritDoc}
*/
public boolean equals(final Object o) {
if (o == null || !(o instanceof ImmutableArray)) {
return false;
} // end of if
final ImmutableArray> other = (ImmutableArray>) o;
return new EqualsBuilder().
append(this.baseClass, other.baseClass).
append(this.baseType, other.baseType).
append(this.baseTypeName, other.baseTypeName).
append(this.elements, other.elements).
isEquals();
} // end of equals
/**
* {@inheritDoc}
*/
public String toString() {
return String.format("ImmutableArray(%s)", this.elements);
} // end of toString
// ---
/**
* Returns sub-list, or null if |index| is not valid.
*/
private List subList(final long index, int count) {
final int len = this.elements.size();
if (index < 0 || index >= len || count < 0) {
return null;
} // end of if
// ---
final long end = (index+count > len) ? len+1 : index+count;
return this.elements.subList((int)index, (int)end);
} // end of subList
} // end of class ImmutableArray