/*******************************************************************************
* Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.tools.workbench.utility.iterators;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* A <code>ResultSetIterator</code> wraps a <code>ResultSet</code>
* and transforms its rows for client consumption. Subclasses can override
* <code>#buildNext(ResultSet)</code> to build the expected object from
* the current row of the result set.
* <p>
* To use, supply:<ul>
* <li> a <code>ResultSet</code>
* <li> an <code>Adapter</code> that converts a row in the <code>ResultSet</code>
* into the desired object
* (alternatively, subclass <code>ResultSetIterator</code>
* and override the <code>buildNext(ResultSet)</code> method)
* </ul>
* <p>
*/
public class ResultSetIterator
implements Iterator
{
private final ResultSet resultSet;
private final Adapter adapter;
private Object next;
private static final Object END = new Object();
/**
* Construct an iterator on the specified result set that returns
* the objects produced by the specified adapter.
*/
public ResultSetIterator(ResultSet resultSet, Adapter adapter) {
super();
this.resultSet = resultSet;
this.adapter = adapter;
this.next = this.buildNext();
}
/**
* Construct an iterator on the specified result set that returns
* the first object in each row of the result set.
*/
public ResultSetIterator(ResultSet resultSet) {
this(resultSet, Adapter.DEFAULT_INSTANCE);
}
/**
* Build the next object for the iterator to return.
* Close the result set when we reach the end.
*/
private Object buildNext() {
try {
if (this.resultSet.next()) {
return this.buildNext(this.resultSet);
}
this.resultSet.close();
return END;
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
/**
* By default, return the first object in the current row
* of the result set. Any <code>SQLException</code>s will
* be caught and wrapped in a <code>RuntimeException</code>.
*/
protected Object buildNext(ResultSet rs) throws SQLException {
return this.adapter.buildNext(rs);
}
/**
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
return this.next != END;
}
/**
* @see java.util.Iterator#next()
*/
public Object next() {
if (this.next == END) {
throw new NoSuchElementException();
}
Object temp = this.next;
this.next = this.buildNext();
return temp;
}
/**
* @see java.util.Iterator#remove()
*/
public void remove() {
throw new UnsupportedOperationException();
}
// ********** interface **********
/**
* Used by <code>ResultSetIterator</code> to convert a
* <code>ResultSet</code>'s current row into the next object
* to be returned by the <code>Iterator</code>.
*/
public interface Adapter {
/**
* Return an object corresponding to the result set's
* "current" row. Any <code>SQLException</code>s will
* be caught and wrapped in a <code>RuntimeException</code>.
* @see java.sql.ResultSet
*/
Object buildNext(ResultSet rs) throws SQLException;
Adapter DEFAULT_INSTANCE =
new Adapter() {
// return the first object in the current row of the result set
public Object buildNext(ResultSet rs) throws SQLException {
// result set columns are indexed starting with 1
return rs.getObject(1);
}
};
}
}