Package org.jrest4guice.dao.jpa

Source Code of org.jrest4guice.dao.jpa.FindAction

package org.jrest4guice.dao.jpa;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

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.jrest4guice.dao.actions.ActionTemplate;
import org.jrest4guice.dao.annotations.Find;

import com.google.inject.Inject;

public class FindAction extends ActionTemplate<Find, JpaContext> {
 
  protected final static Log log = LogFactory.getLog(FindAction.class);
 
  @SuppressWarnings("unchecked")
  @Override
  public Object execute(Object[] parameters) {
    Query query = getQuery();
    QueryParameter queryPara = new QueryParameter(parameters, method.getParameterAnnotations());
    fittingQuery(query, queryPara);
    Find find = getAnnotation();
    if (!find.resultClass().equals(void.class) && !find.nativeQuery())
      return toProjectionalList(find.resultClass(), query.getResultList());
    return query.getResultList();
  }
 
  @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, QueryParameter para) {
    if (para.hasNamedParameters()) {
      for (String name : para.getNamedParameters().keySet()) {
        query.setParameter(name, para.getNamedParameters().get(name));
      }
    }
    if (para.hasPositionParameters()) {
      for (Integer index : para.getPositionParameters().keySet()) {
        query.setParameter(index, para.getPositionParameters().get(index));
      }
    }
    if (para.getFirstResult() != null) {
      query.setFirstResult(para.getFirstResult());
    }
    if (para.getMaxResults() != null) {
      query.setMaxResults(para.getMaxResults());
    }
  }
 
  private Query getQuery() {
    Find find = getAnnotation();
    EntityManager em = getContext().getEntityManager();
    if (StringUtils.isNotBlank(find.namedQuery()))
      return em.createNamedQuery(find.namedQuery());
    if (find.nativeQuery()) {
      if (find.resultClass().equals(void.class))
        return em.createNativeQuery(find.query());
      else
        return em.createNativeQuery(find.query(), find.resultClass());
    } else
      return em.createQuery(find.query());
  }
 
  @Override
  protected void initialize() {
    annotationClass = Find.class;
    contextClass = JpaContext.class;
  }
 
  @Inject
  @Override
  public void setContext(JpaContext context) {
    this.context = context;
  }
 
}
TOP

Related Classes of org.jrest4guice.dao.jpa.FindAction

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.