All Downloads are FREE. Search and download functionalities are using the official Maven repository.

acolyte.jdbc.ImmutableArray Maven / Gradle / Ivy

There is a newer version: 1.2.9
Show newest version
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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy