Java tutorial
/* * Este programa es software libre; usted puede redistribuirlo y/o modificarlo bajo los trminos * de la licencia "GNU General Public License" publicada por la Fundacin "Free Software Foundation". * Este programa se distribuye con la esperanza de que pueda ser til, pero SIN NINGUNA GARANTIA; * vea la licencia "GNU General Public License" para obtener mas informacin. */ package ips1ap101.lib.core.db.util; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import ips1ap101.lib.base.BaseBundle; import ips1ap101.lib.base.app.constant.EAB; import ips1ap101.lib.base.constant.CBM; import ips1ap101.lib.base.entity.enumeration.TipoAgregacionEnumeration; import ips1ap101.lib.base.enumeration.EnumFormatoGuardar; import ips1ap101.lib.base.enumeration.EnumTipoInforme; import ips1ap101.lib.base.persistence.entity.*; import ips1ap101.lib.base.util.BitUtils; import ips1ap101.lib.base.util.StrUtils; import ips1ap101.lib.core.app.Bitacora; import ips1ap101.lib.core.app.ExcepcionAplicacion; import ips1ap101.lib.core.app.TLC; import ips1ap101.lib.core.comparators.VistaFuncionColPorId; import ips1ap101.lib.core.comparators.VistaFuncionColPorSecuencia; import ips1ap101.lib.core.constant.EAC; import ips1ap101.lib.core.constant.Global; import ips1ap101.lib.core.jasper.Report; import ips1ap101.lib.core.util.Utils; import ips1ap101.lib.core.util.VelocityAid; import ips1ap101.lib.core.util.VelocityEngineer; import ips1ap101.lib.core.web.app.EJBL; import org.apache.commons.collections.ComparatorUtils; import org.apache.commons.lang.StringUtils; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; /** * @author Jorge Campins */ public class VistaFuncionWrapper { private long _id; private String _nombre; private EnumFormatoGuardar _formato; private EnumTipoInforme _tipo; private String _select; private String _from; private String _where; private VistaFuncionBase _vista; private Collection<VistaFuncionColBase> _columnas; private Collection<VistaFuncionColBase> _columnasOcultas; private Collection<VistaFuncionColBase> _grupos; private Collection<VistaFuncionColBase> _agregaciones; private VistaFuncionColBase _ultimo; private boolean _orden; private boolean _vistaValida; private VistaFuncionWrapper() { } public VistaFuncionWrapper(long vista, EnumFormatoGuardar formato, EnumTipoInforme tipo, String select) throws ExcepcionAplicacion { _id = vista; _nombre = Global.PREFIJO_STRING_ID_RECURSO + vista; _formato = formato != null ? formato : EnumFormatoGuardar.INFORME; _tipo = tipo != null ? tipo : EnumTipoInforme.DETALLE; if (_formato.equals(EnumFormatoGuardar.ARCHIVO) && _tipo.equals(EnumTipoInforme.GRAFICO)) { throw new ExcepcionAplicacion(Bitacora.getTextoMensaje(CBM.GRAFICO_NO_DISPONIBLE)); } _select = StringUtils.trimToNull(select); if (_select == null) { throw new ExcepcionAplicacion(Bitacora.getTextoMensaje(CBM.ERROR_COMANDO_SELECT)); } init(); } private void init() throws ExcepcionAplicacion { _vista = EJBL.getVistaFuncionFacade().find(_id, true); if (_vista == null) { throw new ExcepcionAplicacion(Bitacora.getTextoMensaje(CBM.VISTA_NO_DISPONIBLE, _nombre)); } _nombre = _vista.getNombre(); _from = from(_select); if (StringUtils.isBlank(_from)) { // vista "{0}" no tiene origen throw new ExcepcionAplicacion(Bitacora.getTextoMensaje(CBM.ERROR_COMANDO_SELECT_VISTA_1, _nombre)); } _where = where(_select); _columnas = new ArrayList<>(_vista.getVistaFuncionColByVistaCollection()); _columnasOcultas = new ArrayList<>(); _grupos = new ArrayList<>(); _agregaciones = new ArrayList<>(); VistaFuncionColPorSecuencia c1 = new VistaFuncionColPorSecuencia(); VistaFuncionColPorId c2 = new VistaFuncionColPorId(); Comparator<VistaFuncionColBase> comparator = (Comparator<VistaFuncionColBase>) ComparatorUtils .chainedComparator(c1, c2); Collections.sort((List<VistaFuncionColBase>) _columnas, comparator); boolean parametrosRestringidos = TLC.getControlador() .esFuncionConParametrosRestringidos(_vista.getFuncion().getIdFuncion()); String codigoDominio = _vista.getFuncion().getIdDominio().getCodigoDominio(); TipoAgregacionBase agregacion; TipoAgregacionEnumeration tipoAgregacion; VistaFuncionColBase grupo; String alias; String propertyColumn; Long propertySelect; boolean parametroAutorizado; for (VistaFuncionColBase vistaFuncionCol : _columnas) { agregacion = vistaFuncionCol.getAgregacion(); tipoAgregacion = agregacion == null ? null : TipoAgregacionEnumeration.valueOf(agregacion.getNumero()); grupo = vistaFuncionCol.getGrupo(); alias = vistaFuncionCol.getAlias(); if (parametrosRestringidos) { propertyColumn = BaseBundle.getPropertyColumn(codigoDominio, alias); propertySelect = BaseBundle.getPropertySelect(codigoDominio, alias); parametroAutorizado = propertyColumn == null || propertySelect == null || TLC.getControlador().esParametroAutorizado(propertyColumn, propertySelect); } else { parametroAutorizado = true; } if (parametroAutorizado) { if (tipoAgregacion != null) { if (TipoAgregacionEnumeration.GRUPO.equals(tipoAgregacion)) { if (grupo != null && vistaFuncionCol.getId().equals(grupo.getId())) { _grupos.add(vistaFuncionCol); _ultimo = vistaFuncionCol; } } else { _agregaciones.add(vistaFuncionCol); } } _orden |= BitUtils.valueOf(vistaFuncionCol.getOrden()); } else { _columnasOcultas.add(vistaFuncionCol); } } if (_columnasOcultas.isEmpty()) { if (_columnas.isEmpty()) { // vista "{0}" no tiene columnas throw new ExcepcionAplicacion(Bitacora.getTextoMensaje(CBM.ERROR_COMANDO_SELECT_VISTA_2, _nombre)); } switch (_tipo) { case DETALLE: if (_grupos.isEmpty()) { } else if (_agregaciones.isEmpty()) { // vista "{0}" no tiene agregaciones throw new ExcepcionAplicacion( Bitacora.getTextoMensaje(CBM.ERROR_COMANDO_SELECT_VISTA_4, _nombre)); } break; case GRAFICO: if (_grupos.isEmpty()) { // vista "{0}" no tiene grupos throw new ExcepcionAplicacion( Bitacora.getTextoMensaje(CBM.ERROR_COMANDO_SELECT_VISTA_3, _nombre)); } if (_agregaciones.isEmpty()) { // vista "{0}" no tiene agregaciones throw new ExcepcionAplicacion( Bitacora.getTextoMensaje(CBM.ERROR_COMANDO_SELECT_VISTA_4, _nombre)); } agregacion = null; for (VistaFuncionColBase vistaFuncionCol : _agregaciones) { if (BitUtils.valueOf(vistaFuncionCol.getGraficable())) { continue; } agregacion = vistaFuncionCol.getAgregacion(); tipoAgregacion = TipoAgregacionEnumeration.valueOf(agregacion.getNumero()); TLC.getBitacora().error(CBM.COLUMNA_NO_GRAFICABLE, vistaFuncionCol.getNombre(), tipoAgregacion.getLabel()); } if (agregacion != null) { throw new ExcepcionAplicacion(Bitacora.getTextoMensaje(CBM.VISTA_NO_GRAFICABLE, _nombre)); } break; case RESUMEN: if (_agregaciones.isEmpty()) { // vista "{0}" no tiene agregaciones throw new ExcepcionAplicacion( Bitacora.getTextoMensaje(CBM.ERROR_COMANDO_SELECT_VISTA_4, _nombre)); } break; } } else { for (VistaFuncionColBase vistaFuncionCol : _columnasOcultas) { TLC.getBitacora().error(CBM.COLUMNA_NO_AUTORIZADA, vistaFuncionCol.getNombre()); } throw new ExcepcionAplicacion(Bitacora.getTextoMensaje(CBM.VISTA_NO_AUTORIZADA, _nombre)); } if (_orden) { } else { // vista "{0}" no tiene orden TLC.getBitacora().warn(CBM.ERROR_COMANDO_SELECT_VISTA_5, _nombre); } _vistaValida = true; } public long getId() { return _id; } public String getNombre() { return _nombre; } public EnumFormatoGuardar getFormato() { return _formato; } public EnumTipoInforme getTipo() { return _tipo; } public String getSelect() { return _select; } public String getFrom() { return _from; } public String getWhere() { return _where; } public VistaFuncionBase getVista() { return _vista; } public Collection<VistaFuncionColBase> getColumnas() { return _columnas; } public Collection<VistaFuncionColBase> getColumnasOcultas() { return _columnasOcultas; } public Collection<VistaFuncionColBase> getGrupos() { return _grupos; } public Collection<VistaFuncionColBase> getAgregaciones() { return _agregaciones; } public VistaFuncionColBase getUltimo() { return _ultimo; } public boolean isOrden() { return _orden; } public boolean isVistaValida() { return _vistaValida; } public String getReportSourceFileName() throws ExcepcionAplicacion { check(); return Utils.getReportSourceFileName(_nombre, _formato, _tipo); } public String getSelectStatement() throws ExcepcionAplicacion { check(); String alias; TipoAgregacionBase agregacion; TipoAgregacionEnumeration tipoAgregacion; VistaFuncionColBase grupo; boolean orden; ArrayList<String> detalle = new ArrayList<>(); ArrayList<String> resumen = new ArrayList<>(); ArrayList<String> grafico = new ArrayList<>(); ArrayList<String> groupBy = new ArrayList<>(); ArrayList<String> orderBy = new ArrayList<>(); for (VistaFuncionColBase vistaFuncionCol : _columnas) { alias = vistaFuncionCol.getAlias(); agregacion = vistaFuncionCol.getAgregacion(); tipoAgregacion = agregacion == null ? null : TipoAgregacionEnumeration.valueOf(agregacion.getNumero()); grupo = check(vistaFuncionCol.getGrupo()); orden = BitUtils.valueOf(vistaFuncionCol.getOrden()); // <editor-fold defaultstate="collapsed"> // if (_columnasOcultas.contains(vistaFuncionCol)) { // addDetalle(detalle, alias, false); // addResumen(resumen, alias, tipoAgregacion, grupo, false); // addGrafico(grafico, alias, tipoAgregacion, grupo, false); // continue; // } // </editor-fold> addDetalle(detalle, alias, true); addResumen(resumen, alias, tipoAgregacion, grupo, true); addGrafico(grafico, alias, tipoAgregacion, grupo, true); addGroupBy(groupBy, alias, tipoAgregacion, grupo); addOrderBy(orderBy, alias, orden); } switch (_tipo) { case DETALLE: return select(false, detalle, _from, _where, null, orderBy); case RESUMEN: if (EnumFormatoGuardar.ARCHIVO.equals(_formato)) { return select(false, resumen, _from, _where, groupBy, groupBy); } else { return select(false, detalle, _from, _where, null, orderBy); } case GRAFICO: if (grafico.isEmpty()) { grafico.add("1"); return select(false, grafico, _from, _where, null, grafico); } else { return select(true, grafico, _from, _where, null, grafico); } default: return null; } } private void check() throws ExcepcionAplicacion { if (!_vistaValida) { throw new ExcepcionAplicacion(Bitacora.getTextoMensaje(CBM.VISTA_NO_DISPONIBLE, _nombre)); } } private VistaFuncionColBase check(VistaFuncionColBase grupo) { return _grupos.contains(grupo) ? grupo : null; } private void addDetalle(List<String> detalle, String alias, boolean visible) { detalle.add(pdq(alias, visible)); } private void addResumen(List<String> resumen, String alias, TipoAgregacionEnumeration tipo, VistaFuncionColBase grupo, boolean visible) { if (tipo == null) { if (grupo != null) { resumen.add(pdq(alias, visible)); } } else { switch (tipo) { case GRUPO: resumen.add(pdq(alias, visible)); break; case CUENTA: resumen.add(cnt(alias, visible)); break; case MINIMO: resumen.add(min(alias, visible)); break; case MAXIMO: resumen.add(max(alias, visible)); break; case SUMA: resumen.add(sum(alias, visible)); break; case PROMEDIO: resumen.add(avg(alias, visible)); break; case DESVIACION: resumen.add(dev(alias, visible)); break; case CUENTA_MINIMO_MAXIMO: resumen.add(cnt(alias, visible)); resumen.add(min(alias, visible)); resumen.add(max(alias, visible)); break; case MINIMO_MAXIMO: resumen.add(min(alias, visible)); resumen.add(max(alias, visible)); break; case SUMA_CUENTA_PROMEDIO: resumen.add(sum(alias, visible)); resumen.add(cnt(alias, visible)); resumen.add(avg(alias, visible)); break; case SUMA_CUENTA_PROMEDIO_DESVIACION_MINIMO_MAXIMO: resumen.add(sum(alias, visible)); resumen.add(cnt(alias, visible)); resumen.add(avg(alias, visible)); resumen.add(dev(alias, visible)); resumen.add(min(alias, visible)); resumen.add(max(alias, visible)); break; case PROMEDIO_DESVIACION: resumen.add(avg(alias, visible)); resumen.add(dev(alias, visible)); break; case PROMEDIO_DESVIACION_MINIMO_MAXIMO: resumen.add(avg(alias, visible)); resumen.add(dev(alias, visible)); resumen.add(min(alias, visible)); resumen.add(max(alias, visible)); break; default: resumen.add(cnt(alias, visible)); break; } } } private void addGrafico(List<String> grafico, String alias, TipoAgregacionEnumeration tipo, VistaFuncionColBase grupo, boolean visible) { if (grupo != null && grupo != _ultimo) { if (tipo == null || TipoAgregacionEnumeration.GRUPO.equals(tipo)) { grafico.add(pdq(alias, visible)); } } } private void addGroupBy(List<String> groupBy, String alias, TipoAgregacionEnumeration tipo, VistaFuncionColBase grupo) { if (TipoAgregacionEnumeration.GRUPO.equals(tipo) || (tipo == null && grupo != null)) { groupBy.add(alias); } } private void addOrderBy(List<String> orderBy, String alias, boolean orden) { if (orden) { orderBy.add(alias); } } private String pdq(String alias, boolean visible) { return visible ? alias : "NULL" + " AS " + alias; } private String cnt(String alias, boolean visible) { return agg(alias, visible, TipoAgregacionEnumeration.CUENTA); } private String min(String alias, boolean visible) { return agg(alias, visible, TipoAgregacionEnumeration.MINIMO); } private String max(String alias, boolean visible) { return agg(alias, visible, TipoAgregacionEnumeration.MAXIMO); } private String sum(String alias, boolean visible) { return agg(alias, visible, TipoAgregacionEnumeration.SUMA); } private String avg(String alias, boolean visible) { return agg(alias, visible, TipoAgregacionEnumeration.PROMEDIO); } private String dev(String alias, boolean visible) { return agg(alias, visible, TipoAgregacionEnumeration.DESVIACION); } private String agg(String alias, boolean visible, TipoAgregacionEnumeration tipo) { String funcion = TLC.getInterpreteSql().getNombreFuncionAgregacion(tipo); String prefijo = StrUtils.getIdentificadorSqlLowerCase(tipo.getLabel()); String value = visible ? funcion + "(" + alias + ")" : "NULL"; return value + " AS " + prefijo + "__" + alias; } private String select(boolean distinct, List<String> columns, String from, String where, List<String> groupBy, List<String> orderBy) throws ExcepcionAplicacion { return "SELECT " + (distinct ? "DISTINCT " : "") + StringUtils.join(columns, ", ") + from + StringUtils.defaultIfBlank(where, "") + group(groupBy) + order(orderBy); } private String from(String select) { int i = StringUtils.indexOfIgnoreCase(select, " FROM "); if (i < 0) { return null; } int j = StringUtils.indexOfIgnoreCase(select, " WHERE "); if (j < 0) { j = StringUtils.indexOfIgnoreCase(select, " GROUP BY "); } if (j < 0) { j = StringUtils.indexOfIgnoreCase(select, " ORDER BY "); } if (j < 0) { j = select.length(); } if (j < i) { return null; } String substring = select.substring(i, j); return substring; } private String where(String select) { int i = StringUtils.indexOfIgnoreCase(select, " WHERE "); if (i < 0) { return null; } int j = StringUtils.indexOfIgnoreCase(select, " GROUP BY "); if (j < 0) { j = StringUtils.indexOfIgnoreCase(select, " ORDER BY "); } if (j < 0) { j = select.length(); } if (j < i) { return null; } String substring = select.substring(i, j); return substring; } private String group(List<String> list) { return list == null || list.isEmpty() ? "" : " GROUP BY " + StringUtils.join(list, ", "); } private String order(List<String> list) { return list == null || list.isEmpty() ? "" : " ORDER BY " + StringUtils.join(list, ", "); } public boolean generateJasperReport() throws ExcepcionAplicacion { check(); File dir = Reporter.getUserDefinedReportsDir(); if (dir == null) { throw new ExcepcionAplicacion( Bitacora.getTextoMensaje(CBM.RECURSO_NO_DISPONIBLE, EAC.REPORT_SOURCE_DIR)); } String sep = System.getProperties().getProperty("file.separator"); String informe = getReportSourceFileName(); String tempname = "informe" + "-" + _tipo.name().toLowerCase() + "." + "jrxml" + "." + "vm"; String filename = dir.getPath() + sep + informe + "." + "jrxml"; Report report = new Report(this, _tipo); VelocityContext context = VelocityAid.newVelocityContext(); context.put("report", report); context.put("eacode", EAB.ENTERPRISE_APPLICATION_CODE); return write(context, tempname, filename); } private boolean write(VelocityContext context, String tempname, String filename) throws ExcepcionAplicacion { if (VelocityEngineer.init()) { try { VelocityEngineer.write(context, tempname, filename); return true; } catch (Exception ex) { throw new ExcepcionAplicacion(ex); } } throw new ExcepcionAplicacion( Bitacora.getTextoMensaje(CBM.RECURSO_NO_DISPONIBLE, Velocity.class.getName())); } }