HibernatePager.java :  » Groupware » coefficient » za » org » coefficient » util » common » Java Open Source

Java Open Source » Groupware » coefficient 
coefficient » za » org » coefficient » util » common » HibernatePager.java
/*
 * Coefficient - facilitates project based collaboration
 * Copyright (C) 2003, Dylan Etkin, CSIR icomtek
 * PO Box 395
 * Pretoria 0001, RSA
 * 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; 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package za.org.coefficient.util.common;

import za.org.coefficient.core.Constants;
import za.org.coefficient.interfaces.Pager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * DOCUMENT ME!
 *
 * @author $author$
 * @version $Revision: 1.5 $
 */
public class HibernatePager implements Pager, java.io.Serializable {
    //~ Static fields/initializers =============================================

    private static final String AND = "and";
    private static final String OR = "or";

    //~ Instance fields ========================================================

    private ArrayList andVals = new ArrayList();
    private ArrayList orVals = new ArrayList();
    private ArrayList page = new ArrayList();
    private Class pagerClass;
    private String orderByField;
    private String userQuery;
    private StringBuffer andConstraints = new StringBuffer("");
    private StringBuffer fromClause = new StringBuffer("");
    private StringBuffer orConstraints = new StringBuffer("");
    private Object[] userValues;
    private boolean ascending = true;
    private boolean hasNext = false;
    private int currentPageNumber = 1;
    private int pageSize = Constants.MAX_ELEMENTS_PER_PAGE;
    private int total = 0;

    //~ Constructors ===========================================================

    public HibernatePager() {
    }

    public HibernatePager(String searchQuery, Object[] values) throws Exception {
        userQuery = searchQuery;
        userValues = values;
        this.initialize();
    }

    public HibernatePager(String searchQuery, Object[] values, int pageSize)
        throws Exception {
        userQuery = searchQuery;
        userValues = values;
        this.pageSize = pageSize;
        this.initialize();
    }

    public HibernatePager(Class pageClass, String orderByField)
        throws Exception {
        this.pagerClass = pageClass;
        this.orderByField = orderByField;
        this.initialize();
    }

    public HibernatePager(Class pageClass, String orderByField,
        boolean orderByAscending) throws Exception {
        this.pagerClass = pageClass;
        this.orderByField = orderByField;
        this.ascending = orderByAscending;
        this.initialize();
    }

    public HibernatePager(Class pageClass, String orderByField, int pageSize)
        throws Exception {
        this.pagerClass = pageClass;
        this.orderByField = orderByField;
        this.pageSize = pageSize;
        this.initialize();
    }

    public HibernatePager(Class pageClass, String orderByField, int pageSize,
        boolean orderByAscending) throws Exception {
        this.pagerClass = pageClass;
        this.orderByField = orderByField;
        this.ascending = orderByAscending;
        this.pageSize = pageSize;
        this.initialize();
    }

    public HibernatePager(Class pageClass, String orderByField,
        boolean orderByAscending, HashMap andSearchParams) throws Exception {
        this.pagerClass = pageClass;
        this.orderByField = orderByField;
        this.ascending = orderByAscending;
        this.setAndSearchParams(andSearchParams);
    }

    public HibernatePager(Class pageClass, String orderByField,
        boolean orderByAscending, HashMap andSearchParams,
        HashMap orSearchParams) throws Exception {
        this.pagerClass = pageClass;
        this.orderByField = orderByField;
        this.ascending = orderByAscending;
        this.setAndSearchParams(andSearchParams);
        this.setOrSearchParams(orSearchParams);
    }

    public HibernatePager(Class pageClass, String orderByField, int pageSize,
        HashMap andSearchParams) throws Exception {
        this.pagerClass = pageClass;
        this.orderByField = orderByField;
        this.pageSize = pageSize;
        this.setAndSearchParams(andSearchParams);
    }

    public HibernatePager(Class pageClass, String orderByField, int pageSize,
        HashMap andSearchParams, HashMap orSearchParams) throws Exception {
        this.pagerClass = pageClass;
        this.orderByField = orderByField;
        this.pageSize = pageSize;
        this.setAndSearchParams(andSearchParams);
        this.setOrSearchParams(orSearchParams);
    }

    public HibernatePager(Class pageClass, String orderByField, int pageSize,
        HashMap andSearchParams, boolean orderByAscending) throws Exception {
        this.pagerClass = pageClass;
        this.orderByField = orderByField;
        this.ascending = orderByAscending;
        this.pageSize = pageSize;
        this.setAndSearchParams(andSearchParams);
    }

    public HibernatePager(Class pageClass, String orderByField, int pageSize,
        HashMap andSearchParams, HashMap orSearchParams,
        boolean orderByAscending) throws Exception {
        this.pagerClass = pageClass;
        this.orderByField = orderByField;
        this.ascending = orderByAscending;
        this.pageSize = pageSize;
        this.setAndSearchParams(andSearchParams);
        this.setOrSearchParams(orSearchParams);
    }

    //~ Methods ================================================================

    /**
     * Use this to constrain the result set by doing a field 'like' value
     * for the key-value pairs in the hashmap all pairs being And'ed together
     *
     * @param searchParams must contain a string key which is the element
     *                     name on the class this pager is for and an Object
     *                     representing the value of this field to constrain
     *                     by. If null it will clear the old params.
     * @exception exception is thrown if a named element does not exist on
     *                      the pager class or if a Hibernate Type can not
     *                      be determined for it
     */
    public void setAndSearchParams(HashMap searchParams) throws Exception {
        setSearchParams(searchParams, AND);
    }

    /**
     * Returns the current page number
     * @return is the current page number
     */
    public int getCurrentPageNumber() {
        return currentPageNumber;
    }

    /**
     * Use fromElements to add elments to the from portion of the query
     */
    public void setFromClauses(HashMap fromElements) throws Exception {
        fromClause = new StringBuffer();
        if (fromElements != null) {
            for (Iterator it = fromElements.keySet()
                                           .iterator(); it.hasNext();) {
                String key = (String) it.next();
                String val = (String) fromElements.get(key);
                fromClause.append(" , ");
                fromClause.append(key);
                if (val != null) {
                    fromClause.append(" in ");
                    fromClause.append(" objs.");
                    fromClause.append(val);
                }
            }
        }
        this.initialize();
    }

    public void setFromWhereAndInitialize(HashMap andSearchParams,
        HashMap orSearchParams, HashMap fromElements) throws Exception {
        this.setFromClauses(fromElements);
        this.setAndSearchParams(andSearchParams);
        this.setOrSearchParams(orSearchParams);
        this.initialize();
    }

    /**
     * Returns the maximum number of pages
     * @return is the maximum number of pages
     */
    public int getMaxPageNumber() {
        return (int) (Math.ceil(((double) total) / pageSize));
    }

    /**
     * Use this to constrain the result set by doing a field 'like' value
     * for the key-value pairs in the hashmap all pairs being Or'ed together
     *
     * @param searchParams must contain a string key which is the element
     *                     name on the class this pager is for and an Object
     *                     representing the value of this field to constrain
     *                     by. If null it will clear the old params.
     * @exception exception is thrown if a named element does not exist on
     *                      the pager class or if a Hibernate Type can not
     *                      be determined for it
     */
    public void setOrSearchParams(HashMap searchParams) throws Exception {
        setSearchParams(searchParams, OR);
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getPageSize() {
        return this.pageSize;
    }

    public void setQuery(String queryString, Object[] values) {
        userQuery = queryString;
        userValues = values;
        this.initialize();
    }

    /**
     * Returns the total number of results found by the query
     * @returns total # of results
     */
    public int getTotalNumberOfResults() {
        return total;
    }

    /**
     * Returns the data in the current page.
     * @returns  The data in the current page.
     */
    public List currentPage() {
        return page;
    }

    /**
     * If the submitted page is in range then the pager will jump to that
     * page otherwise it will stay where it is
     *
     * @param pageNumber is the page to move to
     * @return list containing data for the page
     */
    public List goToPage(int pageNumber) {
        if (pageNumber <= (Math.ceil(((double) total) / pageSize))) {
            this.performQuery(((pageNumber - 1) * pageSize));
            currentPageNumber = pageNumber;
            hasNext = (currentPageNumber * pageSize) < total;
        }

        return currentPage();
    }

    /**
     * Checks whether there is a "next" page of data
     * @returns  True id there a "next" page of data, false otherwise.
     */
    public boolean hasNextPage() {
        return hasNext;
    }

    /**
     * Checks whether there is a "previous" page of data
     * @returns  True id there a "previous" page of data, false otherwise.
     */
    public boolean hasPreviousPage() {
        return currentPageNumber != 1;
    }

    /**
     * This will start the pager at the beginning of the search set
     */
    public void initialize() {
        this.performQuery(0);
        hasNext = (currentPageNumber * pageSize) < total;
    }

    /**
     * Moves to the next page of data.
     */
    public void next() {
        if (hasNext) {
            this.performQuery((currentPageNumber * pageSize));
            currentPageNumber++;
            hasNext = (currentPageNumber * pageSize) < total;
        }
    }

    /**
     * Moves to the next page of data, and returns the data in that page.
     * @returns  The data in the next page.
     */
    public List nextPage() {
        this.next();

        return this.currentPage();
    }

    /**
     * Moves to the previous page of data.
     */
    public void previous() {
        if (hasPreviousPage()) {
            page.clear();
            performQuery((pageSize * (currentPageNumber - 1)) - pageSize);
            currentPageNumber--;
            hasNext = true;
        }
    }

    /**
     * Moves to the previous page of data, and returns the data in that page.
     * @returns  The data in the previous page.
     */
    public List previousPage() {
        this.previous();

        return this.currentPage();
    }

    private void setIntoConstraint(boolean and, String addition) {
        if (and) {
            andConstraints.append(addition);
        } else {
            orConstraints.append(addition);
        }
    }

    private void setIntoVals(boolean and, Object val) {
        if (and) {
            andVals.add(val);
        } else {
            orVals.add(val);
        }
    }

    private int getLengthForConstraint(boolean and) {
        if (and) {
            return andConstraints.length();
        } else {
            return orConstraints.length();
        }
    }

    private void setSearchParams(HashMap searchParams, String logicalOperator)
        throws Exception {
        boolean and = AND.equals(logicalOperator);
        if (and) {
            andConstraints = new StringBuffer("");
            andVals = new ArrayList();
        } else {
            orConstraints = new StringBuffer("");
            orVals = new ArrayList();
        }

        if (searchParams != null) {
            for (Iterator it = searchParams.keySet()
                                           .iterator(); it.hasNext();) {
                String field = (String) it.next();
                Object value = searchParams.get(field);
                if (getLengthForConstraint(and) != 0) {
                    if (and) {
                        andConstraints.append(" and ");
                    } else {
                        orConstraints.append(" or ");
                    }
                }
                boolean not = false;
                String operator = "like";
                if (field.startsWith("!")) {
                    not = true;
                    field = field.substring(1, field.length());
                    operator = "!=";
                } else if (field.startsWith("<=")) {
                    operator = "<=";
                    field = field.substring(2, field.length());
                } else if (field.startsWith(">=")) {
                    operator = ">=";
                    field = field.substring(2, field.length());
                } else if (field.startsWith("<")) {
                    operator = "<";
                    field = field.substring(1, field.length());
                } else if (field.startsWith(">")) {
                    operator = ">";
                    field = field.substring(1, field.length());
                }

                if (value instanceof Boolean) {
                    if (not) {
                        setIntoConstraint(and, " objs." + field + " != ? ");
                    } else {
                        setIntoConstraint(and, " objs." + field + " = ? ");
                    }
                    setIntoVals(and, value);
                } else {
                    if (value == null) {
                        if (not) {
                            setIntoConstraint(and,
                                " objs." + field + " is not null ");
                        } else {
                            setIntoConstraint(and,
                                " objs." + field + " is null ");
                        }
                    } else {
                        if(value instanceof String) {
                            setIntoConstraint(and,
                                " upper(objs." + field + ") " + operator + " ? ");
                            value = ((String)value).toUpperCase();
                        } else {
                            setIntoConstraint(and,
                                " objs." + field + " " + operator + " ? ");
                        }
                        setIntoVals(and, value);
                    }
                }
            }
        }
        this.initialize();
    }

    private Object[] convertValsToArray() {
        int i = 0;
        Object[] oVals = new Object[andVals.size() + orVals.size()];
        for (Iterator it = andVals.iterator(); it.hasNext(); i++) {
            Object val = it.next();
            oVals[i] = val;
        }
        for (Iterator it = orVals.iterator(); it.hasNext(); i++) {
            Object val = it.next();
            oVals[i] = val;
        }

        return oVals;
    }

    private void performQuery(int startElement) {
        try {
            Object[] oVals = null;
            String sql = null;
            if ((userQuery == null) || (userQuery.length() == 0)) {
                oVals = convertValsToArray();
                StringBuffer query = new StringBuffer("select objs ");
                query.append(" from ");
                query.append(pagerClass.getName());
                query.append(" as objs");
                if (fromClause.length() != 0) {
                    query.append(fromClause.toString());
                }
                if (andConstraints.length() != 0) {
                    query.append(" where ");
                    query.append(andConstraints.toString());
                }
                if (orConstraints.length() != 0) {
                    if (andConstraints.length() == 0) {
                        query.append(" where ");
                    } else {
                        query.append(" and ");
                    }
                    query.append(" ( ");
                    query.append(orConstraints.toString());
                    query.append(" ) ");
                }
                query.append(" order by objs.");
                query.append(orderByField);
                if (!ascending) {
                    query.append(" desc");
                }
                sql = query.toString();
            } else {
                sql = userQuery.toString();
                oVals = userValues;
            }

            total = ((Integer)InvokerFactory.getRemoteInvoker()
                .invokeMethodOnService("Search", "getPage",
                                       new Object[]{sql, new Integer(pageSize), 
                                                    new Integer(startElement),
                                                    oVals, page})).intValue();
        } catch (Exception e) {
            System.err.println(
                "<< could not execute query from pager for class: "
                + pagerClass.getName() + " with orderByField: " + orderByField);
            e.printStackTrace();
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.