Package org.jrest4guice.dao.hibernate

Source Code of org.jrest4guice.dao.hibernate.FindAction$QueryParameters

package org.jrest4guice.dao.hibernate;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.ConstructorUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Session;
import org.jrest4guice.dao.actions.ActionTemplate;
import org.jrest4guice.dao.annotations.Find;
import org.jrest4guice.dao.annotations.Find.FirstResult;
import org.jrest4guice.dao.annotations.Find.MaxResults;

import com.google.inject.Inject;
import com.google.inject.name.Named;

public class FindAction extends ActionTemplate<Find, HibernateContext> {

  protected final static Log log = LogFactory.getLog(FindAction.class);

  @SuppressWarnings("unchecked")
  @Override
  public Object execute(Object[] parameters) {
    Query query = getQuery();
    QueryParameters queryPara = new QueryParameters(parameters, method.getParameterAnnotations());
    fittingQuery(query, queryPara);
    Find find = getAnnotation();
    if (!find.resultClass().equals(void.class))
      return toProjectionalList(find.resultClass(), query.list());
    return query.list();
  }

  @SuppressWarnings("unchecked")
  protected List toProjectionalList(Class<?> clz, List<Object[]> records) {
    List result = new ArrayList();
    if (records.size() == 0)
      return result;
    Object[] args = records.get(0);
    Class parameterTypes[] = new Class[args.length];
    for (int i = 0; i < args.length; i++) {
      parameterTypes[i] = args[i].getClass();
    }
    Constructor constructor = ConstructorUtils.getAccessibleConstructor(clz, parameterTypes);
    if (constructor == null) {
      String message = "找不到适合的构造方法:" + clz.getName() + "(" + StringUtils.join(parameterTypes, ", ") + ")";
      log.error(message);
      throw new IllegalArgumentException(message);
    }
    for (Object[] parameters : records) {
      try {
        result.add(constructor.newInstance(parameters));
      } catch (Exception e) {
        log.error("无法构建投影类型对象", e.getCause()); // 不应该出现该错误
      }
    }
    return result;
  }

  private void fittingQuery(Query query, QueryParameters para) {
    if (para.namedParameters != null) {
      for (String name : para.namedParameters.keySet()) {
        query.setParameter(name, para.namedParameters.get(name));
      }
    }
    if (para.positionParameters != null) {
      for (Integer index : para.positionParameters.keySet()) {
        query.setParameter(index, para.positionParameters.get(index));
      }
    }
    if (para.firstResult != null) {
      query.setFirstResult(para.firstResult);
    }
    if (para.maxResults != null) {
      query.setMaxResults(para.maxResults);
    }
  }

  private Query getQuery() {
    Find find = getAnnotation();
    if (StringUtils.isNotBlank(find.namedQuery()))
      return getSession().getNamedQuery(find.namedQuery());
    if (find.nativeQuery())
      return getSession().createSQLQuery(find.query());
    else
      return getSession().createQuery(find.query());
  }

  private Session getSession() {
    return getContext().getSession();
  }

  @Override
  protected void initialize() {
    annotationClass = Find.class;
    contextClass = HibernateContext.class;
  }

  @Inject
  @Override
  public void setContext(HibernateContext context) {
    this.context = context;
  }

  class QueryParameters {

    Annotation[][] annotations;
    Object[] parameters;
    Integer firstResult;
    Integer maxResults;
    Map<String, Object> namedParameters;
    Map<Integer, Object> positionParameters;

    QueryParameters(Object[] parameters, Annotation[][] annotations) {
      this.annotations = annotations;
      this.parameters = parameters;
      if (parameters == null)
        return;
      label1: for (int index = 0; index < parameters.length; index++) {
        final Object para = parameters[index];
        if (this.annotations == null) {
          getPositionParameters().put(index, para);
          continue;
        }
        for (final Annotation annotation : annotations[index]) {
          final Class<? extends Annotation> clazz = annotation.annotationType();
          if (clazz.equals(Named.class)) {
            final Named named = (Named) annotation;
            getNamedParameters().put(named.value(), para);
            continue label1;
          } else if (clazz.equals(FirstResult.class)) {
            firstResult = (Integer) para;
            continue label1;
          } else if (clazz.equals(MaxResults.class)) {
            maxResults = (Integer) para;
            continue label1;
          }
        }
        getPositionParameters().put(index, para);
      }
    }

    public Map<String, Object> getNamedParameters() {
      if (namedParameters == null)
        namedParameters = new HashMap<String, Object>();
      return namedParameters;
    }

    public Map<Integer, Object> getPositionParameters() {
      if (positionParameters == null)
        positionParameters = new HashMap<Integer, Object>();
      return positionParameters;
    }
  }
}
TOP

Related Classes of org.jrest4guice.dao.hibernate.FindAction$QueryParameters

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.