ips1ap101.lib.core.db.util.VistaFuncionWrapper.java Source code

Java tutorial

Introduction

Here is the source code for ips1ap101.lib.core.db.util.VistaFuncionWrapper.java

Source

/*
 * 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()));
    }

}