pl.touk.wonderfulsecurity.dao.WsecBaseDaoImpl.java Source code

Java tutorial

Introduction

Here is the source code for pl.touk.wonderfulsecurity.dao.WsecBaseDaoImpl.java

Source

/*
 * Copyright (c) 2008 TouK.pl
 * 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 pl.touk.wonderfulsecurity.dao;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Order;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.HibernateException;

import java.io.Serializable;
import java.util.*;
import java.sql.SQLException;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;
import org.apache.maven.artifact.versioning.Restriction;
import pl.touk.wonderfulsecurity.beans.PagedQueryResult;

/**
 * Hibernate base dao implementation
 *
 * @author Lukasz Kucharski - lkc@touk.pl
 * @author <a href="mailto:msk@touk.pl">Micha Sokoowski</a>
 */
public class WsecBaseDaoImpl extends HibernateDaoSupport implements WsecBaseDao {

    public static final String dateFormatAsStr = "yyyy-MM-dd HH:mm:ss";
    public static final DateFormat dateFormat = new SimpleDateFormat(dateFormatAsStr);

    public void deleteAll(Collection collectionToDelete) {
        getHibernateTemplate().deleteAll(collectionToDelete);
    }

    public <E> ArrayList<E> fetchAll(Class<E> clazz) {
        checkIsBeanMapped(clazz);
        List<E> result = getHibernateTemplate().loadAll(clazz);
        if (result instanceof ArrayList) {
            return (ArrayList<E>) result;
        }
        // Collections.EmptyList != ArrayList
        return new ArrayList<E>(result);
    }

    public <E> E fetchById(Class<E> c, Serializable id) {
        checkIsBeanMapped(c);
        return (E) getHibernateTemplate().get(c, id);
    }

    public int fetchCount(final Map<String, ?> queryParameters, final Class clazz) {
        checkIsBeanMapped(clazz);
        Object o = getHibernateTemplate().execute(new HibernateCallback() {

            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                DetachedCriteria criteria = buildCriteriaFromMapOfParameters(queryParameters, clazz);
                criteria.setProjection(Projections.rowCount());
                return criteria.getExecutableCriteria(session).uniqueResult();
            }
        });

        return o != null ? ((Number) o).intValue() : 0;
    }

    public <E> ArrayList<E> fetchList(final Map<String, ?> queryParameters, final String sortColumn,
            final Boolean desc, final Class<E> clazz) {
        {
            checkIsBeanMapped(clazz);
            ArrayList<E> list = new ArrayList<E>(
                    (Collection<E>) getHibernateTemplate().execute(new HibernateCallback() {

                        public Object doInHibernate(Session session) throws HibernateException, SQLException {
                            DetachedCriteria detachedCriteria = buildCriteriaFromMapOfParameters(queryParameters,
                                    clazz);
                            Criteria criteria = detachedCriteria.getExecutableCriteria(session);
                            applySorting(criteria, sortColumn, desc);
                            return criteria.list();
                        }
                    }));

            return list != null ? list : new ArrayList();
        }

    }

    public <E> ArrayList<E> fetchPagedList(final Map<String, ?> queryParameters, final Integer offset,
            final Integer howMany, final String sortColumn, final Boolean desc, final Class<E> clazz) {
        checkIsBeanMapped(clazz);
        ArrayList<E> list = (ArrayList<E>) getHibernateTemplate().execute(new HibernateCallback() {

            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                DetachedCriteria detachedCriteria = buildCriteriaFromMapOfParameters(queryParameters, clazz);
                Criteria criteria = detachedCriteria.getExecutableCriteria(session);
                applySortingOffSetAndLimit(criteria, offset, howMany, sortColumn, desc);
                return criteria.list();
            }
        });

        return list != null ? list : new ArrayList();
    }

    public <E extends Serializable> PagedQueryResult<E> fetchPagedListWithOverallCount(
            Map<String, ?> queryParameters, Integer offset, Integer howMany, String sortColumn, Boolean desc,
            Class<E> clazz) {
        checkIsBeanMapped(clazz);
        ArrayList list = fetchPagedList(queryParameters, offset, howMany, sortColumn, desc, clazz);
        logger.info("Fetched page");
        int overallCount = fetchCount(queryParameters, clazz);

        return new PagedQueryResult(list, overallCount);
    }

    public <E extends Serializable> PagedQueryResult<E> fetchPagedListWithOverallCount(
            Map<String, ?> queryParameters, Integer offset, Integer howMany, String sortColumn, Boolean desc,
            Long maxObjectsInPageList, Class<E> clazz) {
        checkIsBeanMapped(clazz);
        ArrayList takenListOfClazz;
        logger.info("Fetched page");
        int overallCount = fetchCount(queryParameters, clazz);

        if (maxObjectsInPageList != null && maxObjectsInPageList > 0) {
            takenListOfClazz = overallCount > maxObjectsInPageList ? new ArrayList()
                    : fetchPagedList(queryParameters, offset, howMany, sortColumn, desc, clazz);
        } else {
            takenListOfClazz = fetchPagedList(queryParameters, offset, howMany, sortColumn, desc, clazz);
        }

        return new PagedQueryResult(takenListOfClazz, overallCount);
    }

    private void checkIsBeanMapped(Class clazz) {
        ClassMetadata classMetadata = getSessionFactory().getClassMetadata(clazz);
        if (classMetadata == null) {
            throw new RuntimeException(
                    "Bean class not mapped! Add bean class to mapping! Class: " + clazz.getName());
        }
    }

    public void saveOrUpdate(Object object) {
        getHibernateTemplate().saveOrUpdate(object);

    }

    public void saveOrUpdateAll(Collection entityCollection) {
        getHibernateTemplate().saveOrUpdateAll(entityCollection);
    }

    public void persist(Object o) {
        getHibernateTemplate().persist(o);
    }

    public void persistAll(Collection c) {
        if (c == null || c.isEmpty()) {
            return;
        }

        for (Iterator i = c.iterator(); i.hasNext();) {
            getHibernateTemplate().persist(i.next());
        }
    }

    public void delete(Object object) {
        getHibernateTemplate().delete(object);
    }

    // -------------------------- OTHER METHODS --------------------------

    protected Criteria applySorting(Criteria criteria, String sortColumn, Boolean desc) {

        if (desc == null) {
            desc = true;
        }

        boolean doSort = sortColumn != null && !sortColumn.trim().equals("");

        if (doSort) {
            criteria.addOrder(desc ? Order.desc(sortColumn) : Order.asc(sortColumn));
        }

        return criteria;
    }

    protected Criteria applySortingOffSetAndLimit(Criteria criteria, Integer offset, Integer howMany,
            String sortColumn, Boolean desc) {
        if (offset == null && howMany != null || offset != null && howMany == null) {
            throw new IllegalArgumentException(
                    "Both howMany and offset has to be either null or non null references");
        }

        boolean setLimitAndOffset = offset != null;

        if (desc == null) {
            desc = true;
        }

        boolean doSort = sortColumn != null && !sortColumn.trim().equals("");

        if (setLimitAndOffset) {
            criteria.setFirstResult(offset);
            criteria.setMaxResults(howMany);
        }

        if (doSort) {
            if (sortColumn.indexOf(".") == -1) {
                criteria.addOrder(desc ? Order.desc(sortColumn) : Order.asc(sortColumn));
            } else {
                //handles only one nested property
                //TODO: handle more nested properties
                String[] nestedProperties = sortColumn.split("\\.");
                criteria.createCriteria(nestedProperties[0])
                        .addOrder(desc ? Order.desc(nestedProperties[1]) : Order.asc(nestedProperties[1]));
            }
        }

        return criteria;
    }

    /**
     * Builds Hibernate criteria object from map of parameters that usually comes from front end
     */
    protected <E> DetachedCriteria buildCriteriaFromMapOfParameters(Map<String, ?> parameters, Class<E> clazz) {
        DetachedCriteria criteria = DetachedCriteria.forClass(clazz);

        if (parameters != null) {

            for (String key : parameters.keySet()) {
                if (key.indexOf(".") != -1) {

                    //handles only one nested property
                    //TODO: handle more nested properties
                    String[] nestedProperties = key.split("\\.");
                    //.addOrder(desc ? Order.desc() : Order.asc(nestedProperties[1]));
                    applyFilters(nestedProperties[1], parameters.get(key),
                            criteria.createCriteria(nestedProperties[0]));
                } else {

                    applyFilters(key, parameters.get(key), criteria);
                }

            }
        }

        return criteria;
    }

    private void applyFilters(String key, Object filter, DetachedCriteria criteria) {
        if (key.endsWith(LIKE_SUFFIX)) {
            criteria.add(
                    Restrictions.like(key.substring(0, key.length() - LIKE_SUFFIX.length()), "%" + filter + "%"));
        } else if (key.endsWith(I_LIKE_SUFFIX)) {
            criteria.add(Restrictions.ilike(key.substring(0, key.length() - I_LIKE_SUFFIX.length()),
                    "%" + filter + "%"));
        } else if (key.endsWith(LIKE_DATE_SUFFIX)) {
            String realKey = key.substring(0, key.length() - LIKE_DATE_SUFFIX.length());
            Date dateFilter = ((Date) filter);
            Date plus24h = new Date();
            plus24h.setTime(dateFilter.getTime() + 86399999l);
            criteria.add(Restrictions.between(realKey, dateFilter, plus24h));
        } else if (key.endsWith(NULL_END_SUFFIX)) {
            criteria.add(Restrictions.isNull(key.substring(0, key.length() - NULL_END_SUFFIX.length())));
        } else if (key.endsWith(NOT_NULL_END_SUFFIX)) {
            criteria.add(Restrictions.isNotNull(key.substring(0, key.length() - NOT_NULL_END_SUFFIX.length())));
        } else if (key.endsWith(LIKE_MATCH_START_SUFFIX)) {
            criteria.add(Restrictions.like(key.substring(0, key.length() - LIKE_MATCH_START_SUFFIX.length()),
                    filter + "%"));
        } else if (key.endsWith(I_LIKE_MATCH_START_SUFFIX)) {
            criteria.add(Restrictions.ilike(key.substring(0, key.length() - I_LIKE_MATCH_START_SUFFIX.length()),
                    filter + "%"));
        } else if (key.endsWith(NOT_LIKE_END_SUFFIX)) {
            criteria.add(Restrictions.not(Restrictions
                    .like(key.substring(0, key.length() - NOT_LIKE_END_SUFFIX.length()), "%" + filter + "%")));
        } else if (key.endsWith(LIKE_MATCH_END_SUFFIX)) {
            criteria.add(Restrictions.like(key.substring(0, key.length() - LIKE_MATCH_END_SUFFIX.length()),
                    "%" + filter));
        } else if (key.endsWith(I_LIKE_MATCH_END_SUFFIX)) {
            criteria.add(Restrictions.ilike(key.substring(0, key.length() - I_LIKE_MATCH_END_SUFFIX.length()),
                    "%" + filter));
        } else if (key.endsWith(BETWEEN_DATES_END_SUFFIX)) {
            String realKeyWithUpperLimit = key.substring(0, key.length() - BETWEEN_DATES_END_SUFFIX.length());
            String upperLimitAsStr = realKeyWithUpperLimit.substring(realKeyWithUpperLimit.indexOf("|") + 1);
            try {
                Date upperLimit = new Timestamp(dateFormat.parse(upperLimitAsStr).getTime());
                String realKey = realKeyWithUpperLimit.substring(0, realKeyWithUpperLimit.indexOf("|"));
                criteria.add(Restrictions.between(realKey, new Timestamp(((Date) filter).getTime()), upperLimit));
            } catch (ParseException e) {
                throw new IllegalArgumentException("for the key '" + key + "' the date '" + upperLimitAsStr
                        + "' can't be parsed according to the format '" + dateFormatAsStr, e);
            }
        } else if (key.endsWith(EVERYTHING_EXCEPT_END_SUFFIX)) {
            criteria.add(Restrictions.or(
                    Restrictions.ne(key.substring(0, key.length() - EVERYTHING_EXCEPT_END_SUFFIX.length()), filter),
                    Restrictions.isNull(key.substring(0, key.length() - EVERYTHING_EXCEPT_END_SUFFIX.length()))));
        } else if (filter == null) {
            criteria.add(Restrictions.isNull(key));
        } else if (filter instanceof Collection) {
            criteria.add(Restrictions.in(key, (Collection) filter));
        } else {
            criteria.add(Restrictions.eq(key, filter));
        }
    }
}