package com.fp.bpm.query; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.NoResultException; import com.fp.common.logger.APPLogger; import com.fp.dto.AbstractDataTransport; import com.fp.dto.query.DtoQuery; import com.fp.dto.query.Filter; import com.fp.dto.query.QueryRequest; import com.fp.dto.query.SubQuery; import com.fp.persistence.commondb.PersistenceHelper; import com.fp.persistence.commondb.PersistenceManager; /** * Clase que se encarga de realizar consultas genericas a la base de datos. * * @author Jorge Vaca. * @version 2.1 */ public class QueryJsf { /** Map con el orden campos a aplicar a la consulta */ protected final Map mparameter = new HashMap(); /** Parte de la setencia que tiene la instruccion for de la cosnualta. */ private StringBuffer sql; /** Almacena las restriciones de la consulta. */ protected StringBuffer where; private boolean issubquery = false; /** * Metodo que se encarga de realizar consulta de tablas que llegan en el request.
* La cosnsulta se ejecuta por tabla. * * @param queryRequest Request de consultya que almacena la lista de tablas a consultar. * @throws Exception */ public void execute(QueryRequest queryRequest) throws Exception { Map mtablas = queryRequest.getQueryTables(); if (mtablas == null) { return; } Set s = mtablas.keySet(); for (String key : s) { // Crea nuevos objetos por cada tabla que se consulta. sql = new StringBuffer(46); where = new StringBuffer(46); mparameter.clear(); issubquery = false; // Ejecuta consulta de la tabla. DtoQuery dtoqry = mtablas.get(key); if (dtoqry.getBeanname() == null) { continue; } Object resp = queryByBean(dtoqry); queryRequest.getResponse().put(key, resp); } } private Object queryByBean(DtoQuery dtoquey) throws Exception { buildSentence(dtoquey); APPLogger.getLogger().debug(sql); return executeByDtoQuery(dtoquey); } private void buildSentence(DtoQuery dtoquery) throws Exception { buildSql(dtoquery); buildCriteria(dtoquery); sql.append(where); if (dtoquery.getOrderby() != null) { sql.append(" order by " + dtoquery.getOrderby()); } } private Object executeByDtoQuery(DtoQuery dtoquery) throws Exception { if (dtoquery.isMultirecord()) { List lresp = queryList(dtoquery); if (issubquery) { return buildlistresponse(dtoquery, lresp); } else { return lresp; } } Object resp = queryObject(dtoquery); if ((resp != null) && issubquery) { return buildobjectresponse(dtoquery, resp); } return resp; } private Object buildobjectresponse(DtoQuery dtoquery, Object object) throws Exception { List lsubquery = dtoquery.getlSubquery(); Object[] obj = (Object[]) object; AbstractDataTransport bean = (AbstractDataTransport) obj[0]; for (int i = 1; i <= lsubquery.size(); i++) { SubQuery s = lsubquery.get(i - 1); Object valor = obj[i]; bean.put(s.getAlias(), valor); } return bean; } private Object buildlistresponse(DtoQuery dtoquery, List lresp) throws Exception { List l = new ArrayList(); List lsubquery = dtoquery.getlSubquery(); for (Object object : lresp) { Object[] obj = (Object[]) object; AbstractDataTransport bean = (AbstractDataTransport) obj[0]; for (int i = 1; i <= lsubquery.size(); i++) { SubQuery s = lsubquery.get(i - 1); Object valor = obj[i]; bean.put(s.getAlias(), valor); } l.add(bean); } return l; } /** * Metodo que se encarga de construir y adicionar campos a consultar de una tabla. * * @throws Exception */ protected void buildSql(DtoQuery dtoquery) throws Exception { sql.append("select t "); List lsubquery = dtoquery.getlSubquery(); for (SubQuery subQuery : lsubquery) { issubquery = true; sql.append("," + subQuery.getSubQuery()); } // Adiciona subqueries. sql.append(" from " + dtoquery.getBeanname() + " t"); } protected void buildCriteria(DtoQuery dtoquery) throws Exception { List lfiltro = dtoquery.getLfilter(); if ((lfiltro == null) || lfiltro.isEmpty()) { return; } boolean first = true; for (Filter filtro : lfiltro) { if (filtro.getSql() != null) { this.addFiltersql(filtro.getSql(), first); continue; } if (filtro.getValue() == null) { continue; } addFilter(dtoquery.getBeanname(), filtro, first); first = false; } } private void addFilter(String bean, Filter filtro, boolean first) throws Exception { Object valor = filtro.getValue(); String campo = filtro.getField(); String condicion = filtro.getCondition() == null ? "=" : filtro.getCondition(); valor = PersistenceManager.changeType(bean, campo, valor); if (String.valueOf(valor).indexOf("%") >= 0) { condicion = "like"; } String aux = campo.substring(campo.indexOf(".") + 1, campo.length()); String cond = "t." + campo + " " + condicion + " " + ":" + aux; mparameter.put(aux, valor); if (where == null) { where = new StringBuffer(46); } if (first) { where.append(" where " + cond); } else { where.append(" and " + cond); } } private void addFiltersql(String sql, boolean first) throws Exception { if (first) { where.append(" where " + sql); } else { where.append(" and " + sql); } } /** * Metodo que entrega una lista de objetos relacionados a la tabla que se consulta. * * @return List * @throws Exception */ @SuppressWarnings("unchecked") private List queryList(DtoQuery dtoquery) throws Exception { javax.persistence.Query query = createQuery(dtoquery); return query.getResultList(); } /** * Metodo que entrega un objeto, de una tabla relacionado a la consulta. * * @return Object. * @throws Exception */ private Object queryObject(DtoQuery dtoquery) throws Exception { Object obj = null; javax.persistence.Query query = createQuery(dtoquery); try { obj = query.getSingleResult(); } catch (NoResultException e) { // Si no existe datos no hacer nada. } return obj; } private javax.persistence.Query createQuery(DtoQuery dtoquery) throws Exception { javax.persistence.Query query = PersistenceHelper.getEntityManager().createQuery(sql.toString()); this.setParameters(dtoquery, query); return query; } /** * Fija parametros, primer registro y ultimo registro de comsulta. * * @param dtoquery * @param qry * @throws Exception */ public void setParameters(DtoQuery dtoquery, javax.persistence.Query qry) throws Exception { Integer pagina = dtoquery.getPage(); Integer numreg = dtoquery.getRecperpage() == null ? 10 : dtoquery.getRecperpage(); // Control de paginacion. if (dtoquery.isMultirecord()) { qry.setFirstResult(pagina); qry.setMaxResults(numreg); } // Fija parametros a la sentencia Set s = mparameter.keySet(); for (String key : s) { Object valor = mparameter.get(key); qry.setParameter(key, valor); } } }