controllers.Senadores.java Source code

Java tutorial

Introduction

Here is the source code for controllers.Senadores.java

Source

/* Copyright 2013 de Kellyton Brito. Este arquivo  parte 
* do programa MeuCongressoNacional.com . O MeuCongressoNacional.com 
*  um software livre; voc pode redistribu-lo e/ou modific-lo 
* dentro dos termos da GNU Affero General Public License como 
* publicada pela Fundao do Software Livre (FSF) na verso 3 
* da Licena. Este programa  distribudo na esperana que possa 
* ser til, mas SEM NENHUMA GARANTIA; sem uma garantia implcita 
* de ADEQUAO a qualquer MERCADO ou APLICAO EM PARTICULAR. Veja 
* a licena para maiores detalhes, disponvel em 
* meucongressonacional.com/license. Voc deve ter recebido uma cpia 
* da GNU Affero General Public License, sob o ttulo "LICENCA.txt", 
* junto com este programa, se no, acesse http://www.gnu.org/licenses/
**/

package controllers;

/**
 * TODO: Fazer um clculo decente de quantos dias ele realmente estava em exerccio.
 * Tem que procurar onde achar esse dado
 */
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import models.DeputadoFederal;
import models.Senador;
import models.SenadorGasto;
import models.TotalData;
import models.TotalTipo;
import models.util.GastoTotal;

import play.db.jpa.JPA;
import play.db.jpa.Transactional;
import play.libs.WS;
import play.libs.F.Promise;
import play.mvc.Controller;
import play.mvc.Result;
import util.NamesMap;

public class Senadores extends Controller {

    //30 seconds timeout
    private static final Long timeout = 30000L;

    public static final String hostSenado = "http://legis.senado.gov.br/dadosabertos";
    public static final String pathGetSenadores = "/senador/lista/atual";

    @Transactional
    public static List<Senador> getMelhores() {
        List<Senador> senMelhores = JPA.em().createQuery("FROM Senador ORDER BY gastopordia ASC").setMaxResults(5)
                .getResultList();
        return senMelhores;
    }

    @Transactional
    public static List<Senador> getPiores() {
        List<Senador> senPiores = JPA.em().createQuery("FROM Senador ORDER BY gastopordia DESC").setMaxResults(5)
                .getResultList();
        return senPiores;
    }

    @Transactional
    public static Result show(String id) {
        Senador senador;
        List<TotalTipo> totalTipo;
        List<TotalData> totalData;
        List<Object> resultList;

        System.out.println("ID = " + id);

        //Traz o senador
        try {
            senador = (Senador) JPA.em().createQuery("FROM Senador where codParlamentar = :id")
                    .setParameter("id", id).getSingleResult();
        } catch (Exception e) {
            e.printStackTrace();
            return badRequest("Error getting Senador " + id + ". Message: " + e.getMessage() + " - "
                    + e.getLocalizedMessage());
        }

        //Traz os resultados agrupados por tipo de gasto
        try {
            String query = "select cnpj_cpf, tipo_depesa, detalhamento," + " sum(valor_reembolsado) as TotalGasto"
                    + " from SenadorGasto" + " where senador = :id"
                    + " group by tipo_depesa, detalhamento order by 2,3,4 desc";

            resultList = JPA.em().createNativeQuery(query).setParameter("id", senador.getNomeParlamentar())
                    .getResultList();

            totalTipo = new LinkedList<TotalTipo>();
            TotalTipo tt;

            for (Object result : resultList) {
                tt = new TotalTipo();

                Object[] items = (Object[]) result;
                tt.setCnpj((String) items[0]);
                tt.setDescricao((String) items[1]);
                tt.setDetalhe((String) items[2]);
                tt.setTotalGasto((Double) items[3]);

                totalTipo.add(tt);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return badRequest("Error getting Senador  " + senador.getNomeParlamentar() + ". Message: "
                    + e.getMessage() + " - " + e.getLocalizedMessage());
        }

        //Traz os resultados por data
        try {
            String query = " select ano, mes," + " sum(valor_reembolsado) as TotalGasto" + " from SenadorGasto"
                    + " where senador = :id" + " group by ano, mes order by 1,2";

            resultList = JPA.em().createNativeQuery(query).setParameter("id", senador.getNomeParlamentar())
                    .getResultList();

            totalData = new LinkedList<TotalData>();
            TotalData td;

            for (Object result : resultList) {
                td = new TotalData();

                Object[] items = (Object[]) result;
                td.setAno((Integer) items[0]);
                td.setMes((Integer) items[1]);
                td.setTotalGasto((Double) items[2]);

                totalData.add(td);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return badRequest("Error getting Deputado  " + id + ". Message: " + e.getMessage() + " - "
                    + e.getLocalizedMessage());
        }

        List<GastoTotal> categoriaGasto = getCategoriaGasto(senador);

        return ok(views.html.depfederaldetalhe.render(null, senador, null, null, totalTipo, totalData,
                categoriaGasto));
    }

    private static List<GastoTotal> getCategoriaGasto(Senador senador) {
        String query = "SELECT tipo_depesa, sum(valor_reembolsado)" + " FROM senadorgasto"
                + " WHERE senador = :senador" + " GROUP BY tipo_depesa" + " ORDER BY 2 DESC";

        List<Object> resultList = JPA.em().createNativeQuery(query)
                .setParameter("senador", senador.getNomeParlamentar()).getResultList();
        List<GastoTotal> gastosTipo = new ArrayList<GastoTotal>(10);

        GastoTotal gastoTipo;

        for (Object result : resultList) {
            gastoTipo = new GastoTotal();

            Object[] items = (Object[]) result;
            try {
                gastoTipo.setNome(NamesMap.getShortName(NamesMap.SENADOR, (String) items[0]));
                gastoTipo.setValor((Double) items[1]);

                gastosTipo.add(gastoTipo);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return gastosTipo;
    }

    @Transactional
    public static Result senadores() {

        List<Senador> senList = JPA.em().createQuery("FROM Senador ORDER BY nomeParlamentar").getResultList();

        // TODO Probably get once and then get 5 best and worst is faster
        List<Senador> senMelhores = JPA.em().createQuery("FROM Senador ORDER BY gastopordia asc").setMaxResults(5)
                .getResultList();

        List<Senador> senPiores = JPA.em().createQuery("FROM Senador ORDER BY gastopordia desc").setMaxResults(5)
                .getResultList();

        return ok(views.html.depfederal.render(null, null, null, senList, senMelhores, senPiores));
    }

    @Transactional
    public static Result getAllData() {
        try {
            System.out.println("Iniciando atualizao dos senadores: " + new Date());

            getProfileData();
            JPA.em().getTransaction().commit();

            JPA.em().getTransaction().begin();
            getExpensesData();
            JPA.em().getTransaction().commit();

            JPA.em().getTransaction().begin();
            getTotalsData();

            System.out.println("Finalizada atualizao dos senadores: " + new Date());

            return ok("Success");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return badRequest(e.getLocalizedMessage());

        }

    }

    @Transactional
    private static void getProfileData() {
        String url = hostSenado + pathGetSenadores;
        ArrayList<Senador> senadores = new ArrayList<Senador>();

        try {

            Promise<WS.Response> result = WS.url(url).get();
            InputStream is = new ByteArrayInputStream(result.get(timeout).asByteArray());

            System.out.println("Processando Senadores...");

            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            SenadorXMLHandler dhandler = new SenadorXMLHandler(senadores);
            saxParser.parse(is, dhandler);

            //For each deputado, get details and insert
            for (Senador senador : senadores) {
                try {
                    JPA.em().persist(senador);
                } catch (Exception e) {
                    System.out.println("Erro salvando " + senador.getNomeParlamentar() + ". " + e.getMessage());
                    e.printStackTrace();
                }
            }

            System.out.println("Sucesso processando Senadores!");

        } catch (Exception e) {
            System.out.println("Erro salvando senadores: " + e.getMessage());
            e.printStackTrace();
        }

    }

    @Transactional
    private static void getExpensesData() throws IOException {

        System.out.println("Processando despesas dos Senadores...");

        int semData = 0;

        String[] filenames = { "./data/CotaSenado2009.csv", "./data/CotaSenado2010.csv",
                "./data/CotaSenado2011.csv", "./data/CotaSenado2012.csv", "./data/CotaSenado2013.csv" };

        BufferedReader br;
        String line;
        String fields[];
        String csvSplitBy = "\";\"";
        String d;

        LinkedList<SenadorGasto> gastos;
        SenadorGasto gasto;

        //For each file
        for (int i = 0; i < filenames.length; i++) {

            System.out.println("Processing file: " + filenames[i]);

            //br = new BufferedReader(new FileReader(filenames[i]));
            //Senado  tudo ansi
            br = new BufferedReader(new InputStreamReader(new FileInputStream(filenames[i]), "Cp1252"));

            //Jump 2 first lines: header
            line = br.readLine();
            line = br.readLine();
            while ((line = br.readLine()) != null) {
                gasto = new SenadorGasto();

                if (line.length() < 5)
                    continue;

                //remove first and last "
                line = line.substring(1, line.length() - 1);

                fields = line.split(csvSplitBy);
                if (fields.length < 10)
                    continue;

                gasto.setAno(Integer.valueOf(fields[0]));
                gasto.setMes(Integer.valueOf(fields[1]));
                gasto.setSenador(fields[2]);
                gasto.setTipo_depesa(fields[3]);
                gasto.setCnpj_cpf(fields[4]);
                gasto.setFornecedor(fields[5]);
                gasto.setDocumento(fields[6]);
                d = fields[7];
                if (d != null && d.trim().length() > 0) {
                    try {
                        gasto.setData(new SimpleDateFormat("dd/MM/yy", Locale.ENGLISH).parse(d));
                    } catch (ParseException e) {
                        System.out.println("Error getting date from expenditure of Senador: " + gasto.getSenador()
                                + ". Error: " + e.getMessage() + ". Setting data to 01/01/2009");
                        //All missing dates are from 2009
                        try {
                            gasto.setData(new SimpleDateFormat("dd/MM/yy", Locale.ENGLISH).parse("01/01/2009"));
                        } catch (ParseException e1) {
                            System.out.println();
                        }
                    }
                } else {
                    ++semData;
                }

                if (fields[8].length() > 255) {
                    fields[8] = fields[8].substring(0, 254);
                }
                gasto.setDetalhamento(fields[8]);
                gasto.setValor_reembolsado(Float.valueOf(fields[9].replace(',', '.')));

                JPA.em().persist(gasto);
            }
            System.out.println("Sem data: " + semData);
            semData = 0;
        }
        System.out.println("Sucesso processando despesas dos Senadores!");
    }

    /**
     * Dados de 2010 at a ltima data disponvel
     * TODO: Calcular os dias corretamente, com os afastamentos
     * @throws Exception 
     */
    @Transactional
    private static void getTotalsData() throws Exception {

        System.out.println("Processando totais dos Senadores...");

        //Pega o ltimo dia com registro
        Date mostRecentDate = (Date) JPA.em()
                .createNativeQuery("Select max(data) FROM SenadorGasto WHERE data < NOW()").getSingleResult();

        Date olderDate;

        try {
            olderDate = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2010-01-01");
        } catch (ParseException e) {
            throw new Exception("Error getting mostRecentDate. " + e.getLocalizedMessage());
        }

        int days = Days.daysBetween(new DateTime(olderDate), new DateTime(mostRecentDate)).getDays();

        List<Senador> senadores = JPA.em().createQuery("FROM Senador").getResultList();

        Double gasto;
        for (Senador senador : senadores) {
            senador.setDiasTrabalhados(days);

            Object o = JPA.em()
                    .createNativeQuery("select sum(valor_reembolsado) from SenadorGasto where senador = :nome")
                    .setParameter("nome", senador.getNomeParlamentar()).getSingleResult();

            if (o != null) {
                gasto = (Double) o;
                senador.setGastoTotal(gasto);

                senador.setGastoPorDia(gasto / days);
            }
            JPA.em().persist(senador);
        }

        JPA.em().getTransaction().commit();
        JPA.em().getTransaction().begin();

        /**
         * Calcula o ndice do candidato
         * 100*gasto/max
         * Ou seja: o candidato que gastou MAIS tem valor 0, o candidato que gastou NADA tem valor 100 
         */

        Double maxGasto = (Double) JPA.em().createNativeQuery("Select max(gastoPorDia) FROM Senador")
                .getSingleResult();
        Double senTempIndice;

        for (Senador sen : senadores) {
            gasto = sen.getGastoPorDia();

            senTempIndice = (100 * gasto / maxGasto);

            sen.setIndice(senTempIndice.intValue());

            JPA.em().persist(sen);
        }
        System.out.println("Sucesso processando totais dos Senadores!");
    }

}

class SenadorXMLHandler extends DefaultHandler {
    private boolean codParlamentar;
    private boolean nome;
    private boolean nomeParlamentar;
    private boolean sexo;
    private boolean uf;
    private boolean partido;
    private boolean fone;
    private boolean email;
    private boolean nascimento;
    private boolean photoURL;

    ArrayList<Senador> senadores;
    Senador senador;

    public SenadorXMLHandler(ArrayList<Senador> senadores) {
        this.senadores = senadores;
    }

    public void startElement(String uri, String localName, String qName, Attributes attributes)
            throws SAXException {

        if (qName.equalsIgnoreCase("CodigoParlamentar")) {
            codParlamentar = true;
        } else if (qName.equalsIgnoreCase("nomeParlamentar")) {
            nomeParlamentar = true;
        } else if (qName.equalsIgnoreCase("NomeCompleto")) {
            nome = true;
        } else if (qName.equalsIgnoreCase("Sexo")) {
            sexo = true;
        } else if (qName.equalsIgnoreCase("Foto")) {
            photoURL = true;
        } else if (qName.equalsIgnoreCase("EnderecoEletronico")) {
            email = true;
        } else if (qName.equalsIgnoreCase("DataNascimento")) {
            nascimento = true;
        } else if (qName.equalsIgnoreCase("TelefoneParlamentar")) {
            fone = true;
        } else if (qName.equalsIgnoreCase("SiglaPartido")) {
            partido = true;
        } else if (qName.equalsIgnoreCase("SiglaUf")) {
            uf = true;
        }
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
    }

    public void characters(char ch[], int start, int length) throws SAXException {
        if (codParlamentar) {
            //Comeando novo deputado
            senador = new Senador();
            String s = new String(ch, start, length);
            senador.setCodParlamentar(s);
            codParlamentar = false;
        }
        if (nome) {
            String s = new String(ch, start, length);
            senador.setNome(s);
            nome = false;
        }
        if (nomeParlamentar) {
            String s = new String(ch, start, length);
            senador.setNomeParlamentar(s);
            nomeParlamentar = false;
        }
        if (sexo) {
            String s = new String(ch, start, length);
            senador.setSexo(s);
            sexo = false;
        }
        if (partido) {
            String s = new String(ch, start, length);
            senador.setPartido(s);
            partido = false;
        }
        if (fone) {
            String s = new String(ch, start, length);
            senador.setFone(s);
            fone = false;
        }
        if (email) {
            String s = new String(ch, start, length);
            senador.setEmail(s);
            email = false;
        }
        if (nascimento) {
            String s = new String(ch, start, length);

            try {
                Date d = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse(s);
                senador.setNascimento(d);
            } catch (Exception e) {
                System.out.println(
                        "Error getting born date of: " + senador.getNomeParlamentar() + " - " + e.getMessage());
            }
            nascimento = false;
        }
        if (photoURL) {
            String s = new String(ch, start, length);
            senador.setPhotoURL(s);
            photoURL = false;
        }
        if (uf) {
            String s = new String(ch, start, length);
            senador.setUf(s);
            uf = false;
            //Acabou o senador. Adicionar na lista
            senadores.add(senador);
            senador = new Senador();
        }

    }
}