net.mlw.vlh.adapter.hibernate3.util.ScrollableResultsDecorator.java Source code

Java tutorial

Introduction

Here is the source code for net.mlw.vlh.adapter.hibernate3.util.ScrollableResultsDecorator.java

Source

/**
 * Copyright (c) 2003 held jointly by the individual authors.
 * 
 * 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 2.1 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; with out 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, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *  > http://www.gnu.org/copyleft/lesser.html >
 * http://www.opensource.org/licenses/lgpl-license.php
 */
package net.mlw.vlh.adapter.hibernate3.util;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Blob;
import java.sql.Clob;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import net.mlw.vlh.adapter.util.ObjectValidator;

import org.hibernate.HibernateException;
import org.hibernate.ScrollableResults;
import org.hibernate.type.Type;

/**
 * The ScrollableResultsDecorator class enable or disable putting objects into a
 * final ResultsSet, thus into a final valueList. To check validity it uses
 * ObjectValidator's interface. This implementation ensures that the validation
 * method is invoked only once per object.
 * 
 * @todo Implement setRowNumber
 * @author Andrej Zachar
 * @version $Revision: 1.1 $ $Date: 2005/10/20 16:45:24 $
 */
public class ScrollableResultsDecorator implements ScrollableResults {

    private static final int INITIAL_CAPACITY = 100;

    private ScrollableResults _scrollableResults;

    private ObjectValidator _validator;

    private int _currentRow = -1;

    private int[] _index;

    private int _size;

    private boolean _isComplete;

    /**
     * Default contructor of decorator;
     */
    public ScrollableResultsDecorator(ScrollableResults scrollableResults, ObjectValidator validator) {
        super();
        setValidator(validator);
        setScrollableResults(scrollableResults); // the method calls reset() as well
    }

    /**
     * @see org.hibernate.ScrollableResults#beforeFirst()
     */
    public void beforeFirst() throws HibernateException {
        if (_scrollableResults.getRowNumber() >= 0) {
            _scrollableResults.beforeFirst();
        }
        _currentRow = -1;
    }

    /**
     * @see org.hibernate.ScrollableResults#first()
     */
    public boolean first() throws HibernateException {
        return move(0);
    }

    /**
     * @see org.hibernate.ScrollableResults#isFirst()
     */
    public boolean isFirst() throws HibernateException {
        return (_currentRow == 0);
    }

    /**
     * @see org.hibernate.ScrollableResults#afterLast()
     */
    public void afterLast() throws HibernateException {
        if (_isComplete) {
            // the end has been already reached
            _scrollableResults.afterLast();
            _currentRow = _size;
        } else {
            lastKnown();
            while (nextValid())
                ;
        }
    }

    /**
     * @see org.hibernate.ScrollableResults#last()
     */
    public boolean last() throws HibernateException {
        if (_isComplete) {
            // the end has been already reached
            return move(_size - 1);
        } else {
            afterLast();
            return previous();
        }
    }

    /**
     * @see org.hibernate.ScrollableResults#isLast()
     */
    public boolean isLast() throws HibernateException {
        if (_isComplete) {
            return ((_currentRow + 1) == _size);
        } else {
            boolean result = next();
            previous();
            return result;
        }
    }

    /**
     * @see org.hibernate.ScrollableResults#next()
     */
    public boolean next() throws HibernateException {
        return move(_currentRow + 1);
    }

    /**
     * @see org.hibernate.ScrollableResults#previous()
     */
    public boolean previous() throws HibernateException {
        return move(_currentRow - 1);
    }

    /**
     * @see org.hibernate.ScrollableResults#scroll(int)
     */
    public boolean scroll(int i) throws HibernateException {
        if (i == 0) {
            return _scrollableResults.scroll(0);
        }

        return move(_currentRow + i);
    }

    /**
     * @see org.hibernate.ScrollableResults#setRowNumber(int)
     */
    public boolean setRowNumber(int row) throws HibernateException {
        if (row >= 0) {
            return move(row);
        } else {
            if (!_isComplete) {
                // ensure the end has been already reached
                afterLast();
            }
            return move(_size + row);
        }
    }

    private boolean move(int row) throws HibernateException {
        if (row >= 0) {
            if (row < _size) {
                _currentRow = row;
                int rowNumber = _index[_currentRow];
                if (rowNumber != _scrollableResults.getRowNumber()) {
                    return _scrollableResults.setRowNumber(rowNumber);
                } else {
                    return true;
                }
            } else {
                if (_isComplete) {
                    afterLast();
                    return false;
                } else {
                    lastKnown();
                    boolean result = true;
                    while (result && (_currentRow < row)) {
                        result = nextValid();
                    }
                    return result;
                }
            }
        } else {
            beforeFirst();
            return false;
        }
    }

    private void lastKnown() throws HibernateException {
        if (_size > 0) {
            _currentRow = _size - 1;
            int rowNumber = _index[_currentRow];
            if (rowNumber != _scrollableResults.getRowNumber()) {
                _scrollableResults.setRowNumber(_index[_currentRow]);
            }
        } else {
            beforeFirst();
        }
    }

    private boolean nextValid() throws HibernateException {
        boolean result;

        do {
            result = _scrollableResults.next();
        } while (result && !_validator.isAcceptable(_scrollableResults.get(0)));

        _currentRow++;

        if (result) {
            _size = _currentRow + 1;
            ensureCapacity(_size);
            _index[_currentRow] = _scrollableResults.getRowNumber();
        } else {
            _isComplete = true;
        }

        return result;
    }

    private void ensureCapacity(int minCapacity) {
        int oldCapacity = _index.length;
        if (minCapacity > oldCapacity) {
            int[] oldData = _index;
            int newCapacity = (oldCapacity * 3) / 2 + 1;
            if (newCapacity < minCapacity) {
                newCapacity = minCapacity;
            }
            _index = new int[newCapacity];
            System.arraycopy(oldData, 0, _index, 0, oldCapacity);
        }
    }

    /**
     * @see org.hibernate.ScrollableResults#getRowNumber()
     */
    public int getRowNumber() throws HibernateException {
        return _currentRow;
    }

    /* ###### delegated methods ###### */

    /**
     * @see org.hibernate.ScrollableResults#get()
     */
    public Object[] get() throws HibernateException {
        return _scrollableResults.get();
    }

    /**
     * @see org.hibernate.ScrollableResults#get(int)
     */
    public Object get(int arg0) throws HibernateException {
        return _scrollableResults.get(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#close()
     */
    public void close() throws HibernateException {
        _scrollableResults.close();
    }

    /**
     * @see org.hibernate.ScrollableResults#getBigDecimal(int)
     */
    public BigDecimal getBigDecimal(int arg0) throws HibernateException {
        return _scrollableResults.getBigDecimal(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getBigInteger(int)
     */
    public BigInteger getBigInteger(int arg0) throws HibernateException {
        return _scrollableResults.getBigInteger(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getBinary(int)
     */
    public byte[] getBinary(int arg0) throws HibernateException {
        return _scrollableResults.getBinary(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getBlob(int)
     */
    public Blob getBlob(int arg0) throws HibernateException {
        return _scrollableResults.getBlob(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getBoolean(int)
     */
    public Boolean getBoolean(int arg0) throws HibernateException {
        return _scrollableResults.getBoolean(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getByte(int)
     */
    public Byte getByte(int arg0) throws HibernateException {
        return _scrollableResults.getByte(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getCalendar(int)
     */
    public Calendar getCalendar(int arg0) throws HibernateException {
        return _scrollableResults.getCalendar(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getClob(int)
     */
    public Clob getClob(int arg0) throws HibernateException {
        return _scrollableResults.getClob(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getDate(int)
     */
    public Date getDate(int arg0) throws HibernateException {
        return _scrollableResults.getDate(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getDouble(int)
     */
    public Double getDouble(int arg0) throws HibernateException {
        return _scrollableResults.getDouble(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getFloat(int)
     */
    public Float getFloat(int arg0) throws HibernateException {
        return _scrollableResults.getFloat(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getCharacter(int)
     */
    public Character getCharacter(int arg0) throws HibernateException {
        return _scrollableResults.getCharacter(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getInteger(int)
     */
    public Integer getInteger(int arg0) throws HibernateException {
        return _scrollableResults.getInteger(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getLocale(int)
     */
    public Locale getLocale(int arg0) throws HibernateException {
        return _scrollableResults.getLocale(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getLong(int)
     */
    public Long getLong(int arg0) throws HibernateException {
        return _scrollableResults.getLong(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getShort(int)
     */
    public Short getShort(int arg0) throws HibernateException {
        return _scrollableResults.getShort(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getString(int)
     */
    public String getString(int arg0) throws HibernateException {
        return _scrollableResults.getString(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getText(int)
     */
    public String getText(int arg0) throws HibernateException {
        return _scrollableResults.getString(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getTimeZone(int)
     */
    public TimeZone getTimeZone(int arg0) throws HibernateException {
        return _scrollableResults.getTimeZone(arg0);
    }

    /**
     * @see org.hibernate.ScrollableResults#getType(int)
     */
    public Type getType(int arg0) {
        return _scrollableResults.getType(arg0);
    }

    /* ###### getters / setters ###### */

    public void setScrollableResults(ScrollableResults scrollableResults) {
        _scrollableResults = scrollableResults;
        reset();
    }

    public void setValidator(ObjectValidator validator) {
        _validator = validator;
    }

    private void reset() {
        _index = new int[INITIAL_CAPACITY];
        _currentRow = -1;
        _size = 0;
        _isComplete = false;
    }
}