/* XXL: The eXtensible and fleXible Library for data processing
Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger
Head of the Database Research Group
Department of Mathematics and Computer Science
University of Marburg
Germany
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see <http://www.gnu.org/licenses/>.
http://code.google.com/p/xxl/
*/
package xxl.core.relational.tuples;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
/**
* This class is a skeleton-implementation for a tuple.
*
* <p>Tuples are equal, if they have the same number of columns and they are
* equal on each column value.</p>
*
* <p>Two column values <code>x</code> and <code>y</code> are equal, if they
* are both <code>null</code> or they are both not <code>null</code> and
* <code>x.equals(y)</code> holds.</p>
*
* <p>The <code>getXXX</code> methods retrieve the values with the given index
* from the internal list, and return the casted result.</p>
*/
public abstract class AbstractTuple implements Tuple {
/**
* Returns the number of columns in this tuple.
*
* @return the number of columns.
*/
public abstract int getColumnCount();
/**
* Provides access to the packed objects in the tuple. An abstract method
* that has to be overwritten to construct a non-abstract tuple.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return column object
* @see xxl.core.relational.tuples.ArrayTuple
* @see xxl.core.relational.tuples.ListTuple
*/
public abstract Object getObject(int columnIndex);
/**
* Column access method that corresponds to <code>getBoolean</code> in
* {@link java.sql.ResultSet ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return a boolean representation of the column object.
*/
public boolean getBoolean(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
false :
o instanceof Boolean ?
((Boolean)o).booleanValue() :
o instanceof Number ?
((Number)o).doubleValue() != 0 :
o instanceof BigDecimal ?
((BigDecimal)o).signum() != 0 :
Boolean.parseBoolean(o.toString());
}
/**
* Column access method that corresponds to <code>getByte</code> in
* {@link java.sql.ResultSet ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return a byte representation of the column object.
*/
public byte getByte(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
0 :
o instanceof Byte ?
((Byte)o).byteValue() :
Byte.parseByte(o.toString());
}
/**
* Column access method that corresponds to <code>getDate</code> in
* {@link java.sql.ResultSet ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return a Date representation of the column object.
*/
public Date getDate(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
null :
o instanceof Date ?
(Date)o :
Date.valueOf(o.toString());
}
/**
* Column access method that corresponds to <code>getDouble</code> in
* {@link java.sql.ResultSet ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return a double representation of the column object.
*/
public double getDouble(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
0 :
o instanceof Double ?
((Double)o).doubleValue() :
Double.parseDouble(o.toString());
}
/**
* Column access method that corresponds to <code>getFloat</code> in
* {@link java.sql.ResultSet ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return a float representation of the column object.
*/
public float getFloat(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
0 :
o instanceof Float ?
((Float)o).floatValue() :
Float.parseFloat(o.toString());
}
/**
* Column access method that corresponds to <code>getInt</code> in
* {@link java.sql.ResultSet ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return an int representation of the column object.
*/
public int getInt(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
0 :
o instanceof Integer ?
((Integer)o).intValue() :
Integer.parseInt(o.toString());
}
/**
* Column access method that corresponds to <code>getLong</code> in
* {@link java.sql.ResultSet ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return a long representation of the column object.
*/
public long getLong(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
0 :
o instanceof Long ?
((Long)o).longValue() :
Long.parseLong(o.toString());
}
/**
* Column access method that corresponds to <code>getShort</code> in
* {@link java.sql.ResultSet java.sql.ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return a short representation of the column object.
*/
public short getShort(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
0 :
o instanceof Short ?
((Short)o).shortValue() :
Short.parseShort(o.toString());
}
/**
* Column access method that corresponds to <code>getString</code> in
* {@link java.sql.ResultSet java.sql.ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return a String representation of the column object.
*/
public String getString(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
null :
o.toString();
}
/**
* Column access method that corresponds to <code>getTime</code> in
* {@link java.sql.ResultSet ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return a Time representation of the column object.
*/
public Time getTime(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
null :
o instanceof Time ?
(Time)o :
Time.valueOf(o.toString());
}
/**
* Column access method that corresponds to <code>getTimestamp</code> in
* {@link java.sql.ResultSet ResultSet}.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return a Timestamp representation of the column object.
*/
public Timestamp getTimestamp(int columnIndex) {
Object o = getObject(columnIndex);
return o == null ?
null :
o instanceof Timestamp ?
(Timestamp)o :
Timestamp.valueOf(o.toString());
}
/**
* Compares the column object to <code>null</code>.
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return <code>true</code> if the column object is equal to
* <code>null</code>.
*/
public boolean isNull(int columnIndex) {
return getObject(columnIndex) == null;
}
/**
* Compares two tuples.
*
* <p>Tuples are equal, if they have the same number of columns and they
* are equal on each column value.</p>
*
* <p>Two column values <code>x</code> and <code>y</code> are equal, if
* they are both <code>null</code> or they are both not <code>null</code>
* and <code>x.equals(y)</code> holds.</p>
*
* @param object the object with which the current object is compared
* @return <code>true</code> if the two objects are equal in the sense
* explained above.
*/
@Override
public boolean equals(Object object) {
if (object == null || !(object instanceof Tuple))
return false;
Tuple tuple = (Tuple)object;
if (getColumnCount() != tuple.getColumnCount())
return false;
Object o1, o2;
for (int i = 1; i <= getColumnCount(); i++) {
o1 = getObject(i);
o2 = tuple.getObject(i);
if (o1 == null ^ o2 == null || o1 != null && !o1.equals(o2))
return false;
}
return true;
}
/**
* Returns the hash code value for this tuple.
*
* @return the hash code value for this tuple.
*/
@Override
public int hashCode() {
int hashCode = 1;
for (int i = 0; i < getColumnCount(); i++) {
Object object = getObject(i+1);
hashCode = 31*hashCode + (object == null ? 0 : object.hashCode());
}
return hashCode;
}
/**
* Copies the objects of the tuple into a new object array.
*
* @return array containing the objects of the tuple
*/
public Object[] toArray() {
Object[] result = new Object[getColumnCount()];
for (int i = 0; i < getColumnCount(); i++)
result[i] = getObject(i+1);
return result;
}
/**
* Outputs the content of the tuple.
*
* @return a string representation of a tuple.
*/
@Override
public String toString() {
if (getColumnCount() == 0)
return "[]";
StringBuilder string = new StringBuilder().append('[').append(getObject(1));
for (int i = 2; i <= getColumnCount(); i++)
string.append(", ").append(getObject(i));
return string.append(']').toString();
}
}