/*
Copyright 2011 Jose Maria Arranz Santamaria
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package jepl.impl.query;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import jepl.JEPLException;
import jepl.JEPLResultSetDAO;
import jepl.JEPLResultSetDAOListener;
import jepl.impl.JEPLPreparedStatementImpl;
/**
*
* @author jmarranz
* @param <T>
*/
public class JEPLResultSetDAOImpl<T> extends JEPLResultSetImpl implements JEPLResultSetDAO<T>
{
protected JEPLResultSetDAOListener<T> listener;
protected LinkedList<T> internalList = new LinkedList<T>();
protected boolean constructedObject; // NO INICIAR A FALSE NI A TRUE
protected boolean detectedDebugMode; // NO INICIAR A FALSE NI A TRUE
public JEPLResultSetDAOImpl(JEPLDAOQueryImpl<T> query,JEPLPreparedStatementImpl stmt,ResultSet result,JEPLResultSetDAOListener<T> listener) throws SQLException
{
super(query,stmt,result);
this.listener = listener;
this.constructedObject = true;
}
@SuppressWarnings("unchecked")
public JEPLDAOQueryImpl<T> getJEPLDAOQueryImpl()
{
return (JEPLDAOQueryImpl<T>)query;
}
public LinkedList<T> getInternalList()
{
return internalList;
}
@Override
public String getErrorMsgClosed()
{
return "This result set is already closed, use normal List methods instead";
}
@Override
public T getObject()
{
if (isClosed()) throw new JEPLException("This result set is already closed, use normal List methods instead");
try
{
T obj = listener.createObject(this);
if (obj != null) // El ser null es como un "continue", útil para filtrar objetos
listener.fillObject(obj,this);
// En el caso de obj == null añadimos el null a la List interna pues si utilizáramos el List
// después esperamos encontrarnos con lo mismo que hemos iterado
internalList.add(obj);
return obj;
}
catch (JEPLException ex)
{
throw ex;
}
catch (Exception ex)
{
throw new JEPLException(ex);
}
}
@Override
public boolean isStopped()
{
throw new JEPLException("This call has no sense in this context");
}
@Override
public void stop()
{
throw new JEPLException("This call has no sense in this context");
}
public void checkResultSetNotClosed()
{
if (!isClosed()) throw new JEPLException("This method cannot be called when ResultSet is still open");
}
public void fetchToIndex(int index) // Método interno
{
if (isClosed()) return;
int size = internalList.size();
int diff = size - 1 - index;
if (diff >= 0) return;
for(int i = 0; i < (-diff); i++)
{
next();
getObject();
}
}
@Override
public Object getRowContent()
{
return getObject();
}
// Desde aquí métodos implementación de List
@Override
public int size()
{
if (!constructedObject)
{
// Se ha llamado a size() antes de que se construta el objeto, esto es cosa del modo
// debug en NetBeans que en el caso de un List muestra el size() de la colección
// en el campo "Value of Variable"
// Hay que tener en cuenta que pasamos por aquí antes de pasar por el constructor
// y de definir los valores iniciales de los atributos (si hubiera que NO deben tener para no sobreescribir detectedDebugMode)
this.detectedDebugMode = true;
}
boolean closed = isClosed();
if (detectedDebugMode && !closed)
{
JEPLException ex = new JEPLException("size() method cannot be called in debug mode and ResultSet not closed");
ex.printStackTrace();
throw ex;
}
fetchToTheEndIfNotClosed();
return internalList.size();
}
@Override
public boolean isEmpty()
{
fetchToTheEndIfNotClosed();
return internalList.isEmpty();
}
@Override
public boolean contains(Object o)
{
fetchToTheEndIfNotClosed();
return internalList.contains(o);
}
@Override
public Iterator<T> iterator()
{
if (isClosed()) return internalList.iterator();
else return new JEPLResultSetDAOIteratorImpl<T>(this);
}
@Override
public Object[] toArray()
{
fetchToTheEndIfNotClosed();
return internalList.toArray();
}
@Override
public <U> U[] toArray(U[] a)
{
fetchToTheEndIfNotClosed();
return internalList.toArray(a);
}
@Override
public boolean add(T e)
{
fetchToTheEndIfNotClosed();
return internalList.add(e);
}
@Override
public boolean remove(Object o)
{
fetchToTheEndIfNotClosed();
return internalList.remove(o);
}
@Override
public boolean containsAll(Collection<?> c)
{
fetchToTheEndIfNotClosed();
return internalList.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends T> c)
{
fetchToTheEndIfNotClosed();
return internalList.addAll(c);
}
@Override
public boolean addAll(int index, Collection<? extends T> c)
{
fetchToTheEndIfNotClosed();
return internalList.addAll(index,c);
}
@Override
public boolean removeAll(Collection<?> c)
{
fetchToTheEndIfNotClosed();
return internalList.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c)
{
fetchToTheEndIfNotClosed();
return internalList.retainAll(c);
}
@Override
public void clear()
{
fetchToTheEndIfNotClosed();
internalList.clear();
}
@Override
public T get(int index)
{
fetchToIndex(index);
return internalList.get(index);
}
@Override
public T set(int index, T element)
{
fetchToIndex(index);
return internalList.set(index,element);
}
@Override
public void add(int index, T element)
{
fetchToTheEndIfNotClosed();
internalList.add(index,element);
}
@Override
public T remove(int index)
{
fetchToTheEndIfNotClosed();
return internalList.remove(index);
}
@Override
public int indexOf(Object o)
{
fetchToTheEndIfNotClosed();
return internalList.indexOf(o);
}
@Override
public int lastIndexOf(Object o)
{
fetchToTheEndIfNotClosed();
return internalList.lastIndexOf(o);
}
@Override
public ListIterator<T> listIterator()
{
if (isClosed()) return internalList.listIterator();
else return new JEPLResultSetDAOIteratorImpl<T>(this);
}
@Override
public ListIterator<T> listIterator(int index)
{
if (isClosed()) return internalList.listIterator();
else return new JEPLResultSetDAOIteratorImpl<T>(this,index);
}
@Override
public List<T> subList(int fromIndex, int toIndex)
{
fetchToIndex(fromIndex);
fetchToIndex(toIndex);
return internalList.subList(fromIndex,toIndex);
}
}