/* * Sistema de Ouvidoria: um canal através do qual os usuários * podem encaminhar suas reclamações, elogios e sugestões. * * Copyright (C) 2011 SERPRO * * Este programa é software livre; você pode redistribuí-lo e/ou * modificá-lo sob os termos da Licença Pública Geral GNU, conforme * publicada pela Free Software Foundation; tanto a versão 2 da * Licença como (a seu critério) qualquer versão mais nova. * * Este programa é distribuído na expectativa de ser útil, mas SEM * QUALQUER GARANTIA; sem mesmo a garantia implícita de * COMERCIALIZAÇÃO ou de ADEQUAÇÃO A QUALQUER PROPÓSITO EM * PARTICULAR. Consulte a Licença Pública Geral GNU para obter mais * detalhes. * * Você deve ter recebido uma cópia da Licença Pública Geral GNU, * sob o título "LICENCA.txt", junto com esse programa. Se não, * acesse o Portal do Software Público Brasileiro no endereço * http://www.softwarepublico.gov.br/ ou escreva para a Fundação do * Software Livre (FSF) Inc., 51 Franklin St, Fifth Floor, Boston, * MA 02111-1301, USA. * * Contatos através do seguinte endereço internet: * http://www.serpro.gov.br/sistemaouvidoria/ */ package br.gov.serpro.ouvidoria.util; import java.sql.ResultSet; import java.sql.SQLException; import java.text.MessageFormat; import java.text.NumberFormat; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.oro.text.perl.Perl5Util; import org.jfree.chart.labels.CategoryLabelGenerator; import org.jfree.data.category.CategoryDataset; import br.gov.serpro.ouvidoria.controller.gerencial.administracao.OrgaoCtrl; import br.gov.serpro.ouvidoria.dao.DaoFactory; import br.gov.serpro.ouvidoria.dao.hibernate.HibernateDaoFactory; import br.gov.serpro.ouvidoria.model.Orgao; import br.gov.serpro.ouvidoria.util.freechart.data.CategoryDatasetFilterListener; import br.gov.serpro.ouvidoria.util.freechart.data.DBUtilsKit; import br.gov.serpro.ouvidoria.util.freechart.data.JDBCFlatCategoryDataset; /** * * @author SERPRO * @version $Revision: 1.1.2.4 $, $Date: 2011/10/21 18:53:46 $ * @version 0.1, Date: 2005/01/28 */ public class ReportHelperFormula { private static final class TotalQueryFilter implements CategoryDatasetFilterListener, CategoryLabelGenerator { private Map map = null; private NumberFormat formatter; private static Double DOUBLE_ZERO = new Double(0); public TotalQueryFilter() { this.map = new HashMap(); formatter = NumberFormat.getPercentInstance(); formatter.setMinimumFractionDigits(2); } public final Number filterValue(Number value, Comparable rowKey, Comparable columnKey, Object data) { double total; try { total = ((ResultSet) data).getDouble("COUNT"); } catch (SQLException e) { e.printStackTrace(); total = -100d; } double p = value.doubleValue() / total; if (p == 0) return DOUBLE_ZERO; this.map.put(rowKey.toString() + "|" + columnKey.toString(), this.formatter.format(p) + " (" + value.toString() + ")"); return new Double(p * 100d); } public final String generateLabel(CategoryDataset dataset, int series, int category) { Object result = this.map.get(dataset.getRowKey(series).toString() + "|" + dataset.getColumnKey(category).toString()); return result == null ? "" : result.toString(); } } private final static Perl5Util p5Util = new Perl5Util(); public static List getRecordList(HttpServletRequest request) throws SQLException { String query = getQuery(request); List result = DBUtilsKit.selectAsListMap(query); result.add(new Double(100f / ReportKit.getCountFromList(result))); return result; } public static Object getDataSet(String h_formula, String chart_type, boolean detailed, String timeDomain, String h_locais, Orgao orgao, String txt_periodo_i, String txt_periodo_f) throws SQLException { Object ds = ReportKit.getDataSet(chart_type, false, null, false); String query = getQuery(h_formula.split(","), chart_type, detailed, timeDomain, h_locais, orgao, txt_periodo_i, txt_periodo_f); boolean isLine = chart_type.indexOf("line") >= 0; JDBCFlatCategoryDataset dataSet = (JDBCFlatCategoryDataset) ds; dataSet.getColumnHelper().setCustomMapping( detailed ? (!isLine ? new int[] { 1, 2, 4 } : new int[] { 2, 1, 4 }) : (isLine ? new int[] { -1, 1, 3 } : new int[] { 1, -2, 3 })); TotalQueryFilter tqf = new TotalQueryFilter(); dataSet.setFilter(tqf); dataSet.setLabelGenerator(tqf); dataSet.executeQuery(query, true); dataSet.fillGaps(); return dataSet; } public static String getQuery(HttpServletRequest request) { boolean detail = false; final DaoFactory daoFactory = new HibernateDaoFactory(); if ("d".equalsIgnoreCase(request.getParameter("r_modo_exibicao"))) detail = true; OrgaoCtrl orgaoCtrl = new OrgaoCtrl(daoFactory); Orgao orgao = (Orgao) orgaoCtrl.get((String) request.getSession() .getAttribute(Constants.ID_SESSAO_ORGAO)); String[] formulaItems = request.getParameter("h_formula").split(","); return getQuery(formulaItems, request.getParameter("sel_tipo_grafico"), detail, request.getParameter("sel_agrupamento"), request.getParameter("h_locais"), orgao, request.getParameter("txt_periodo_i"), request.getParameter("txt_periodo_f")); } private final static int[] hasAcionadorArray = { 1, 2, 3, 6, 7, 9, 10 }; /** * @param formulaItems * @param chart_type * @param detailed * @param timeDomain * @param h_locais * @param orgao * @param txt_periodo_i * @param txt_periodo_f * @return A query correspondente aos parâmetros passados. */ public static String getQuery(String[] formulaItems, String chart_type, boolean detailed, String timeDomain, String h_locais, Orgao orgao, String txt_periodo_i, String txt_periodo_f) { final String baseQuery = ReportKit.getConfig().getString( "if.base.select"); String groupBy = ""; String dateCrit = ReportKit.getDateCrit(txt_periodo_i, txt_periodo_f); String locCrit = ReportKit.getLocationCrit(h_locais); String firstFields = ""; String fromTable = ""; String fromTableSub = ""; String index = ""; String tableValue = ""; final String timeField = ReportKit.getConfig().getString( "ie.time." + timeDomain) + ", "; firstFields = timeField; boolean usesAcionador = false; String formulaCrit = ""; for (int i = 0; i < formulaItems.length; i++) { String[] tableValues = formulaItems[i].split("="); index = tableValues[0]; tableValue = tableValues.length < 2 ? "" : tableValues[1]; fromTableSub += " " + ReportKit.getConfig() .getString("if.from_tables." + index); formulaCrit += (formulaCrit.length() == 0 ? "" : " AND ") + ReportKit.getConfig().getString( "if.where_tables." + index); formulaCrit += " AND " + (tableValue.length() == 0 ? "IFNULL(" + ReportKit.getConfig().getString( "ii.case_field.cons." + index) + ", '') = ''" : ReportKit.getConfig().getString( "ii.case_field.cons." + index) + "=" + ("1".equals(index) ? "'" : "") + tableValue + ("1".equals(index) ? "'" : "")); if (!usesAcionador && Arrays.binarySearch(hasAcionadorArray, Integer.parseInt(index)) >= 0) usesAcionador = true; } if (usesAcionador) { fromTableSub += ", acionador c "; formulaCrit += " AND a_in.COD_ACNDOR = c.COD_ACNDOR"; } if (detailed) { firstFields += (firstFields.length() > 0 ? " " : "") + ReportKit.getConfig().getString("loco.fields") + ", "; fromTable += " " + ReportKit.getConfig().getString("loco.left_join"); groupBy += (groupBy.length() > 0 ? ", " : ", ") + ReportKit.getConfig().getString("loco.fields"); } final String A_LOCO_DOT = "s/(\\s|\\(|^)(loco|a)([. ])/$1$2_in$3/ig"; String locoDotProc = p5Util.substitute(A_LOCO_DOT, dateCrit.substring(5) + locCrit); String subSelect = ReportKit.getConfig().getString("if.base_subselect"); subSelect = MessageFormat .format(subSelect, new Object[] { fromTableSub, detailed ? p5Util .substitute( "s/(a_in.COD_LOCAL_OCORR)\\s(IN \\(.*?\\))/$1 = a.COD_LOCAL_OCORR/", locoDotProc) : locoDotProc, p5Util.substitute(A_LOCO_DOT, p5Util .substitute("s/\\sAS\\sTIME,//i", timeField)), p5Util.substitute(A_LOCO_DOT, formulaCrit) + (detailed ? "" : "") }); String query = MessageFormat.format(baseQuery, new Object[] { firstFields, fromTable, dateCrit.substring(5) + locCrit, groupBy, subSelect }); return query; } }