/* * 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.util.Arrays; public class ColumnComparableArrayTuple extends ArrayTuple implements ColumnComparableTuple { /** * An array containing column objects. */ protected Object[] tuple; /** * Constructs an array-tuple containing the column objects of an object array. The meta data is * taken from the passed result set meta data object. <b>Please note</b>: If you want to use a * single column or a set of columns you have to <b>ensure</b> that the containing objects * implements {@link java.lang.Comparable}. Otherwise an <code>RuntimeException</code> will be * thrown. * * * @param array an object array containing column objects. Caution: the tuple is linked (not * copied). So, changes to tuple will cause changes in the tuple! */ public ColumnComparableArrayTuple(Object... array) { for (Object c : array) if (c instanceof ColumnComparableArrayTuple) { this.tuple = ((ColumnComparableArrayTuple) c).toComparableArray(); return; } else if (c instanceof Tuple) { this.tuple = (Comparable[]) c; return; } this.tuple = array; } /** * Constructs an array-tuple containing the column objects of an object array. The meta data is * taken from the passed result set meta data object. * * @param template an object array containing column objects. Caution: the tuple is linked (not * copied). So, changes to tuple will cause changes in the tuple! */ public ColumnComparableArrayTuple(Tuple template) { Comparable destination[] = new Comparable[template.getColumnCount()]; Object source[] = template.toArray(); for (int i = 0; i < source.length; i++) { destination[i] = (Comparable) source[i]; } this.tuple = destination; } /** * Creates and returns a copy of this object. The precise meaning of "copy" may depend on the * class of the object. The general intent is that, for any object <tt>x</tt>, the expression: * * <pre> * x.clone() != x * </pre> * * will be <code>true</code>, and that the expression: * * <pre> * x.clone().getClass() == x.getClass() * </pre> * * will be <code>true</code>, but these are not absolute requirements. While it is typically the * case that: * * <pre> * x.clone().equals(x) * </pre> * * will be <code>true</code>, this is not an absolute requirement. * * <p> * By convention, the returned object should be obtained by calling <code>super.clone</code>. If a * class and all of its superclasses (except <code>Object</code>) obey this convention, it will be * the case that <code>x.clone().getClass() == x.getClass()</code>. * </p> * * <p> * By convention, the object returned by this method should be independent of this object (which * is being cloned). To achieve this independence, it may be necessary to modify one or more * fields of the object returned by <tt>super.clone</tt> before returning it. Typically, this * means copying any mutable objects that comprise the internal "deep structure" of the object * being cloned and replacing the references to these objects with references to the copies. If a * class contains only primitive fields or references to immutable objects, then it is usually the * case that no fields in the object returned by <code>super.clone</code> need to be modified. * </p> * * <p> * The method <code>clone</code> for class <code>Object</code> performs a specific cloning * operation. First, if the class of this object does not implement the interface * <code>Cloneable</code>, then a <code>CloneNotSupportedException</code> is thrown. Note that all * arrays are considered to implement the interface <code>Cloneable</code>. Otherwise, this method * creates a new instance of the class of this object and initializes all its fields with exactly * the contents of the corresponding fields of this object, as if by assignment; the contents of * the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this * object, not a "deep copy" operation. * </p> * * <p> * The class <code>Object</code> does not itself implement the interface <code>Cloneable</code>, * so calling the <code>clone</code> method on an object whose class is <code>Object</code> will * result in throwing an exception at run time. * </p> * * @return a clone of this instance. * @throws CloneNotSupportedException if the object's class does not support the * <code>Cloneable</code> interface. Subclasses that override the <code>clone</code> * method can also throw this exception to indicate that an instance cannot be cloned. * @see java.lang.Cloneable */ @Override public Object clone() throws CloneNotSupportedException { ColumnComparableArrayTuple clone = (ColumnComparableArrayTuple) super.clone(); clone.tuple = tuple.clone(); return clone; } /** * Compares this tuple to another by comparing each component, see {@link java.lang.Comparable * Comparable}. <br/> * <b>Note</b> If the dimension of this tuple an <b>other</b> does not match and both are equal in * their shared components, than this tuple is greater than <b>other</b> if the length of * <b>other</b> is greater than the length of this tuple. Otherwise <b>other</b> is greater. <br/> * <br/> * <b>Example</b> * * <pre> * ComparableTuple t1 = new ComparableArrayTuple(new Integer(50), new Integer(30), new Integer(10)); * ComparableTuple t2 = new ComparableArrayTuple(new Integer(50), new Integer(30)); * System.out.println(t1.compareTo(t2)); // outputs "1" * </pre> * * @param other the second <b>ComparableTuple</b> */ @SuppressWarnings("rawtypes") @Override public int compareTo(Object other) { Comparable[] first = new ColumnComparableArrayTuple(tuple).toComparableArray(); Comparable[] second = ((ColumnComparableArrayTuple) other).toComparableArray(); for (int i = 0; i < Math.min(first.length, second.length); i++) { @SuppressWarnings("unchecked") int compare = first[i].compareTo(second[i]); if (compare != 0) return compare; } if (first.length < second.length) return -1; else if (first.length > second.length) return 1; else return 0; } /** * Returns the number of columns in this tuple. * * @return the number of columns. */ @Override public int getColumnCount() { return tuple.length; } /** * Returns the object of the given column. * * @param columnIndex the first column is 1, the second is 2, ... * @return the object of the column. */ @Override public Object getObject(int columnIndex) { return tuple[columnIndex - 1]; } /** * Copies the objects of the tuple into a new object array. * * @return array containing the objects of the tuple */ @Override public Object[] toArray() { return tuple.clone(); } @Override public Comparable[] toComparableArray() { try { Comparable[] result = new Comparable[tuple.length]; for (int i = 0; i < tuple.length; i++) result[i] = (Comparable) tuple[i]; return result; } catch (Exception e) { throw new RuntimeException( "The given tuple does not contain comparable objects at all."); } } /** * Outputs the content of the tuple. * * @return a string representation of a tuple. */ @Override public String toString() { return Arrays.toString(tuple); } }