Package org.chinasb.framework.core.base.search.hibernate

Source Code of org.chinasb.framework.core.base.search.hibernate.HibernateSearchProcessor$MapResultTransformer

/* Copyright 2009 The Revere Group
*
* 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 org.chinasb.framework.core.base.search.hibernate;

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

import org.hibernate.NonUniqueResultException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.transform.Transformers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.chinasb.framework.core.base.search.BaseSearchProcessor;
import org.chinasb.framework.core.base.search.Field;
import org.chinasb.framework.core.base.search.ISearch;
import org.chinasb.framework.core.base.search.InternalUtil;
import org.chinasb.framework.core.base.search.SearchResult;
import org.chinasb.framework.core.base.search.SearchUtil;

/**
* Implementation of BaseSearchProcessor that generates Works with standard Hibernate.
*
* A singleton instance of this class is maintained for each SessionFactory. This should
* be accessed using {@link HibernateSearchProcessor#getInstanceForSessionFactory(SessionFactory)}.
*
* @author dwolverton
*/
public class HibernateSearchProcessor extends BaseSearchProcessor {
  private static Logger logger = LoggerFactory.getLogger(HibernateSearchProcessor.class);

  private static Map<SessionFactory, HibernateSearchProcessor> map = new HashMap<SessionFactory, HibernateSearchProcessor>();

  public static HibernateSearchProcessor getInstanceForSessionFactory(SessionFactory sessionFactory) {
    HibernateSearchProcessor instance = map.get(sessionFactory);
    if (instance == null) {
      instance = new HibernateSearchProcessor(HibernateMetadataUtil.getInstanceForSessionFactory(sessionFactory));
      map.put(sessionFactory, instance);
    }
    return instance;
  }

  private HibernateSearchProcessor(HibernateMetadataUtil mdu) {
    super(QLTYPE_HQL, mdu);
  }

  // --- Public Methods ---

  /**
   * Search for objects based on the search parameters in the specified
   * <code>ISearch</code> object.
   *
   * @see ISearch
   */
  @SuppressWarnings("unchecked")
  public List search(Session session, ISearch search) {
    if (search == null)
      return null;

    return search(session, search.getSearchClass(), search);
  }

  /**
   * Search for objects based on the search parameters in the specified
   * <code>ISearch</code> object. Uses the specified searchClass, ignoring the
   * searchClass specified on the search itself.
   *
   * @see ISearch
   */
  @SuppressWarnings("unchecked")
  public List search(Session session, Class<?> searchClass, ISearch search) {
    if (searchClass == null || search == null)
      return null;

    List<Object> paramList = new ArrayList<Object>();
    String hql = generateQL(searchClass, search, paramList);
    Query query = session.createQuery(hql);
    addParams(query, paramList);
    addPaging(query, search);
    addResultMode(query, search);

    return query.list();
  }

  /**
   * Returns the total number of results that would be returned using the
   * given <code>ISearch</code> if there were no paging or maxResult limits.
   *
   * @see ISearch
   */
  public int count(Session session, ISearch search) {
    if (search == null)
      return 0;
    return count(session, search.getSearchClass(), search);
  }

  /**
   * Returns the total number of results that would be returned using the
   * given <code>ISearch</code> if there were no paging or maxResult limits.
   * Uses the specified searchClass, ignoring the searchClass specified on the
   * search itself.
   *
   * @see ISearch
   */
  public int count(Session session, Class<?> searchClass, ISearch search) {
    if (searchClass == null || search == null)
      return 0;

    List<Object> paramList = new ArrayList<Object>();
    String hql = generateRowCountQL(searchClass, search, paramList);
    if (hql == null) { // special case where the query uses column operators
      return 1;
    }
    Query query = session.createQuery(hql);
    addParams(query, paramList);

    return ((Number) query.uniqueResult()).intValue();
  }

  /**
   * Returns a <code>SearchResult</code> object that includes the list of
   * results like <code>search()</code> and the total length like
   * <code>searchLength</code>.
   *
   * @see ISearch
   */
  @SuppressWarnings("unchecked")
  public SearchResult searchAndCount(Session session, ISearch search) {
    if (search == null)
      return null;
    return searchAndCount(session, search.getSearchClass(), search);
  }

  /**
   * Returns a <code>SearchResult</code> object that includes the list of
   * results like <code>search()</code> and the total length like
   * <code>searchLength</code>. Uses the specified searchClass, ignoring the
   * searchClass specified on the search itself.
   *
   * @see ISearch
   */
  @SuppressWarnings("unchecked")
  public SearchResult searchAndCount(Session session, Class<?> searchClass, ISearch search) {
    if (searchClass == null || search == null)
      return null;

    SearchResult result = new SearchResult();
    result.setResult(search(session, searchClass, search));

    if (search.getMaxResults() > 0) {
      result.setTotalCount(count(session, searchClass, search));
    } else {
      result.setTotalCount(result.getResult().size() + SearchUtil.calcFirstResult(search));
    }

    return result;
  }

  /**
   * Search for a single result using the given parameters.
   */
  public Object searchUnique(Session session, ISearch search) throws NonUniqueResultException {
    if (search == null)
      return null;
    return searchUnique(session, search.getSearchClass(), search);
  }

  /**
   * Search for a single result using the given parameters. Uses the specified
   * searchClass, ignoring the searchClass specified on the search itself.
   */
  public Object searchUnique(Session session, Class<?> entityClass, ISearch search) throws NonUniqueResultException {
    if (search == null)
      return null;

    List<Object> paramList = new ArrayList<Object>();
    String hql = generateQL(entityClass, search, paramList);
    Query query = session.createQuery(hql);
    addParams(query, paramList);
    addResultMode(query, search);

    return query.uniqueResult();
  }

  // ---- SEARCH HELPERS ---- //

  @SuppressWarnings("unchecked")
  private void addParams(Query query, List<Object> params) {
    StringBuilder debug = null;

    int i = 1;
    for (Object o : params) {
      if (logger.isDebugEnabled()) {
        if (debug == null)
          debug = new StringBuilder();
        else
          debug.append("\n\t");
        debug.append("p");
        debug.append(i);
        debug.append(": ");
        debug.append(InternalUtil.paramDisplayString(o));
      }
      if (o instanceof Collection) {
        query.setParameterList("p" + Integer.toString(i++), (Collection) o);
      } else if (o instanceof Object[]) {
        query.setParameterList("p" + Integer.toString(i++), (Object[]) o);
      } else {
        query.setParameter("p" + Integer.toString(i++), o);
      }
    }
    if (debug != null && debug.length() != 0) {
      logger.debug(debug.toString());
    }
  }

  private void addPaging(Query query, ISearch search) {
    int firstResult = SearchUtil.calcFirstResult(search);
    if (firstResult > 0) {
      query.setFirstResult(firstResult);
    }
    if (search.getMaxResults() > 0) {
      query.setMaxResults(search.getMaxResults());
    }
  }

  private void addResultMode(Query query, ISearch search) {
    int resultMode = search.getResultMode();
    if (resultMode == ISearch.RESULT_AUTO) {
      int count = 0;
      Iterator<Field> fieldItr = search.getFields().iterator();
      while (fieldItr.hasNext()) {
        Field field = fieldItr.next();
        if (field.getKey() != null && !field.getKey().equals("")) {
          resultMode = ISearch.RESULT_MAP;
          break;
        }
        count++;
      }
      if (resultMode == ISearch.RESULT_AUTO) {
        if (count > 1)
          resultMode = ISearch.RESULT_ARRAY;
        else
          resultMode = ISearch.RESULT_SINGLE;
      }
    }

    switch (resultMode) {
    case ISearch.RESULT_ARRAY:
      query.setResultTransformer(ARRAY_RESULT_TRANSFORMER);
      break;
    case ISearch.RESULT_LIST:
      query.setResultTransformer(Transformers.TO_LIST);
      break;
    case ISearch.RESULT_MAP:
      List<String> keyList = new ArrayList<String>();
      Iterator<Field> fieldItr = search.getFields().iterator();
      while (fieldItr.hasNext()) {
        Field field = fieldItr.next();
        if (field.getKey() != null && !field.getKey().equals("")) {
          keyList.add(field.getKey());
        } else {
          keyList.add(field.getProperty());
        }
      }
      query.setResultTransformer(new MapResultTransformer(keyList.toArray(new String[0])));
      break;
    default: // ISearch.RESULT_SINGLE
      break;
    }
  }

  @SuppressWarnings("unchecked")
  private static final ResultTransformer ARRAY_RESULT_TRANSFORMER = new ResultTransformer() {
    private static final long serialVersionUID = 1L;

    public List transformList(List collection) {
      return collection;
    }

    public Object transformTuple(Object[] tuple, String[] aliases) {
      return tuple;
    }
  };

  @SuppressWarnings("unchecked")
  private static class MapResultTransformer implements ResultTransformer {
    private static final long serialVersionUID = 1L;

    private String[] keys;

    public MapResultTransformer(String[] keys) {
      this.keys = keys;
    }

    public List transformList(List collection) {
      return collection;
    }

    public Object transformTuple(Object[] tuple, String[] aliases) {
      Map<String, Object> map = new HashMap<String, Object>();
      for (int i = 0; i < keys.length; i++) {
        String key = keys[i];
        if (key != null) {
          map.put(key, tuple[i]);
        }
      }

      return map;
    }
  }

}
TOP

Related Classes of org.chinasb.framework.core.base.search.hibernate.HibernateSearchProcessor$MapResultTransformer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.