package com.fp.bpm.query; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.NoResultException; import javax.persistence.NonUniqueResultException; import javax.persistence.Query; import com.fp.common.helper.BeanManager; import com.fp.dto.AbstractDataTransport; import com.fp.dto.hb.HibernateBean; import com.fp.dto.query.AdditionalQuery; import com.fp.dto.query.QueryBean; import com.fp.dto.query.QueryCriteria; import com.fp.persistence.commondb.PersistenceHelper; import com.fp.persistence.commondb.db.DataHelper; import com.fp.persistence.commondb.exception.CommondbException; import com.fp.persistence.pgeneral.gene.TgeneCatalogDetail; /** * Clase utilitaria utiliza en el motor generico de consultas. * @author Jorge Vaca. * @version 2.1 */ public class QueryHelper { // NOPMD by jorge on 12/10/10 21:53 /**Almacena la senetencia dinamica de consulta.*/ protected StringBuffer query = new StringBuffer(64); // NOPMD by jorge on 12/10/10 21:53 /**Map que almacen los parametros o restricciones para cada consulta asociada a un Query.*/ protected Map mParameters; /** * Metodo que se encarga de adicionar a la sentencia las restricciones del query. * @param pCriteria Objeto que contiene los criterios a aplicar en la sentencia. * @param pType Tipo de dato del campo al cual se aplica la restriccion. * @throws CommondbException * @throws Exception */ @SuppressWarnings("rawtypes") protected void addRestrictions(QueryCriteria pCriteria, Class pType) throws CommondbException,Exception { // NOPMD by jorge on 12/10/10 21:51 String field = pCriteria.getProperty(); String condition = pCriteria.getOperation(); Object value = pCriteria.getValue(); try { value = BeanManager.convertObject(pCriteria.getValue(), pType); } catch (Exception e) { } if (this.basic(condition)) { String aux = field.substring(field.indexOf(".") + 1,field.length()); // NOPMD by jorge on 12/10/10 21:52 aux = this.getAux(aux); query.append("t."+field+" "+condition+" "+":"+aux); mParameters.put(aux, value); return; } if (condition.compareTo("isNull") == 0 || condition.compareTo("isNotNull") == 0 ) { query.append("t."+field+" is null "); return; } if ( condition.compareTo("isNotNull") == 0 ) { query.append("t."+field+" is not null "); return; } if (condition.compareTo("sql") == 0) { query.append(value); return; } if (condition.compareTo("in") == 0 || condition.compareTo("not in") == 0) { query.append("t."+field+" "+condition+"("+value+")"); return; } if (pCriteria.getOperation().compareTo("between") == 0) { Object[] param = ((Collection) pCriteria.getValue()).toArray(); query.append("t."+field+" "+condition+" "+param[0] +" and "+param[1]); return; } throw new CommondbException("QRY001", "OPERADOR {0} NO DISPONIBLE", pCriteria.getOperation()); } /** * Metodo que adiciona un numero secuencial si el campo de la restriccion se repite en la sentencia. * @param pAux Parametro de la sentencia. * @return String * @throws Exception */ private String getAux(String pAux) throws Exception { if(!mParameters.containsKey(pAux)){ return pAux; } Set s = mParameters.keySet(); int i = 0; for (String obj : s) { if(!obj.contains("AAA")){ continue; } String data = obj.substring(obj.indexOf("AAA"),obj.length()); data = data.substring(3, data.length()); i = Integer.valueOf(data); ++i; } return pAux+"AAA"+i; } /** * Metodo que se encarga de adicionar a la senetencia los criterios de orden de la consulta. * @param pQueryBean Objeto que contiene el bean a consultas, y las restricciones. * @throws Exception */ protected void addOrder(QueryBean pQueryBean) throws Exception { boolean first = true; for (QueryCriteria order : pQueryBean.getOrder(true)) { if(first){ query.append(" ORDER BY "); }else{ query.append(" ,"); } query.append("t."+order.getProperty()+" asc "); first = false; } for (QueryCriteria order : pQueryBean.getOrder(false)) { if(first){ query.append(" ORDER BY "); }else{ query.append(" ,"); } query.append("t."+order.getProperty()+" desc "); first = false; } } /** * Metodo que crea un objeto de tipo beanname asociado al QueryBean. * @param pQueryBean Objeto que contiene el bean a consultas, y las restricciones. * @return Object */ protected Object createObject(QueryBean pQueryBean) { try { HibernateBean obj = (HibernateBean) Class.forName(pQueryBean.getBeanName()).newInstance(); try { Object id = BeanManager.getBeanAttributeValue(obj, "pk"); if (id == null) { Object key = Class.forName(pQueryBean.getBeanName() + "Key").newInstance(); BeanManager.setBeanAttributeValue(obj, "pk", key); } } catch (Exception e) { return obj; } return obj; } catch (Exception e) { return null; } } /** * Metodo que transforma los campos de un registro a un AbstractDataTransport. * @param pRecord Datos de un registro obtenidos de la base de datos. * @param nameAttributes Atributos adicionales con los cuales se completa la descripcion del catalogo. * @return Object. * @throws Exception */ protected AbstractDataTransport fillRecord(QueryBean pQueryBean,Object pRecord, String[] nameAttributes) throws Exception { if (pRecord == null) { return null; } AbstractDataTransport obj = (AbstractDataTransport) pRecord; this.completeDescriptionCatalog(obj, nameAttributes); this.addAditionData(pQueryBean, obj); return obj; } /** * Metodo que se encarga de completar descripciones de catalogo. * @param pObject Objeto al cual se completa las descripciones de catalogo. * @param nameAttributes Arreglo con los nombres de catalogo a buscar descripciones ejemlo * [baserate,calculationbase] * @throws Exception */ protected void completeDescriptionCatalog(AbstractDataTransport pObject, String[] nameAttributes) throws Exception { // NOPMD by jorge on 12/10/10 21:53 if (nameAttributes == null) { return; } for (int i = 0; i < nameAttributes.length; i++) { if (nameAttributes[i].startsWith("pk_")) { nameAttributes[i] = nameAttributes[i].replaceAll("_", "."); } String descCatalog = "catalog"; String descCatalogCode = "catalogcode"; if (nameAttributes[i].compareTo("pk.catalog") == 0 || nameAttributes[i].compareTo("catalog") == 0) { descCatalog = ""; descCatalogCode = "code"; } if (pObject == null) { break; } String catalog = (String) BeanManager.getBeanAttributeValue(pObject, nameAttributes[i] + descCatalog); String catalogcode = (String) BeanManager.getBeanAttributeValue(pObject, nameAttributes[i] + descCatalogCode); String nameNewAtribute = nameAttributes[i] + "desc"; if (nameNewAtribute.startsWith("pk.")) { nameNewAtribute = nameNewAtribute.substring(3, nameNewAtribute.length()); } if (catalog != null && catalogcode != null) { TgeneCatalogDetail detail = DataHelper.getInstance().getTgeneCatalogDetail(catalog, catalogcode); pObject.addAddtionalInfo(nameNewAtribute, detail.getDescription()); } else { pObject.addAddtionalInfo(nameNewAtribute, null); } } } /** * Metodo que verifica que la condicion de la restriccion sea basica. * @param pCondition Codigo de condicion de la restriccion. * @return boolean * @throws Exception */ protected boolean basic(String pCondition) throws Exception { if (pCondition.compareTo("<") == 0) { return true; } if (pCondition.compareTo(">") == 0) { return true; } if (pCondition.compareTo("<=") == 0) { return true; } if (pCondition.compareTo(">=") == 0) { return true; } if (pCondition.compareTo("=") == 0) { return true; } if (pCondition.compareTo("<>") == 0) { return true; } if (pCondition.compareTo("like") == 0) { return true; } return false; } /** * Metodo que se encarga de ejecutar sentencias que completan informacion de la consulta asociada al QueryBean. * @param pQueryBean Objeto que contiene el bean a consultas, y las restricciones. * @param pObject Objeto que contiene la datos resultado del query del bean principal de la consulta. * @throws Exception */ protected void addAditionData(QueryBean pQueryBean,AbstractDataTransport pObject) throws Exception { List lData = pQueryBean.getAdditionalQuery(); if(lData == null || lData.isEmpty()){ return; } for (AdditionalQuery additionalQuery : lData) { this.processByAditionalQuery(additionalQuery, pObject); } } /** * Metodo que ejecuta sentecias por cada AdditionalQuery, que llega como parametro.
* Los valores de la restriccion los toma del resultado del bean principal. * @param pAdditional Objeto que contiene las consideraciones necesarias para armar una consula adiciona de datos. * @param pObject Objeto que contiene la datos resultado del query del bean principal de la consulta. * @throws Exception */ @SuppressWarnings("rawtypes") private void processByAditionalQuery(AdditionalQuery pAdditional,AbstractDataTransport pObject) throws Exception { // NOPMD by jorge on 12/10/10 21:52 if(pObject == null){ return; } StringBuffer query = new StringBuffer(); // NOPMD by jorge on 12/10/10 21:52 query.append("select t."+pAdditional.getField()+" from "+pAdditional.getBean()+" t "); List> lCriteria = pAdditional.getCriteria(); mParameters.clear(); boolean first = true; boolean execute = true; for (Map map : lCriteria) { if(first){ query.append(" WHERE "); first = false; }else{ query.append(" AND "); } String aux = map.get("inner").substring(map.get("inner").indexOf(".") + 1,map.get("inner").length()); // NOPMD by jorge on 12/10/10 21:52 query.append("t."+map.get("inner")+" = "+":"+aux); Object value = map.get("value"); if(value == null){ Class type = null; try { type = BeanManager.getBeanGetterMethod(pObject, map.get("outer")).getReturnType(); } catch (Exception e1) { } String aux1 = map.get("outer"); //Si es pk simple llega pk, si es compuesta llega pk.campo value = BeanManager.getBeanAttributeValue(pObject, aux1); if(value == null){ execute = false; //Si no encuentra valor en la tabla padre no ejecuta el query. break; } if(type != null){ value = BeanManager.convertObject(value, type); } } mParameters.put(aux, value); } if(!execute){ pObject.addAddtionalInfo(pAdditional.getAlias(), null); return; } Query qry = PersistenceHelper.getEntityManager().createQuery(query.toString()); Iterator itr = mParameters.keySet().iterator(); while(itr.hasNext()){ String key = itr.next(); qry.setParameter(key, mParameters.get(key)); } try { Object result = qry.getSingleResult(); pObject.addAddtionalInfo(pAdditional.getAlias(), result); } catch (NoResultException e) { pObject.addAddtionalInfo(pAdditional.getAlias(), null); } catch (NonUniqueResultException e) { throw new CommondbException("COMMONDB-00015","EXISTE MAS DE UN REGISTRO PARA LA TABAL: {0}", e,pAdditional.getBean()); } } }