Subversion Repositories bacoAlunos

Rev

Rev 1306 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package pt.estgp.estgweb.services.surveys;

import jomm.dao.impl.AbstractDao;
import jomm.utils.FilesUtils;
import jomm.utils.MessageResources;
import org.apache.log4j.Logger;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.LegendItemCollection;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.text.TextBlockAnchor;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.TextAnchor;
import pt.estgp.estgweb.Globals;
import pt.estgp.estgweb.domain.*;
import pt.estgp.estgweb.domain.dao.DaoFactory;
import pt.estgp.estgweb.domain.views.SurveyView;
import pt.estgp.estgweb.filters.chains.ResourceAccessControlEnum;
import pt.estgp.estgweb.services.data.RepositoryService;
import pt.utl.ist.berserk.logic.serviceManager.IService;
import pt.estgp.estgweb.utils.ConfigProperties;

import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: Duarte Santos
 * @date: 10-08-2011
 * @time: 17:38
 * @email: a12564 [at] estgp [dot] pt
 */


public class GenerateSurveyStatsService implements IService, 1.5.0/docs/api/java/lang/Runnable.html">Runnable
{
    private static final 1.5.0/docs/api/java/util/logging/Logger.html">Logger logger = 1.5.0/docs/api/java/util/logging/Logger.html">Logger.getLogger(GenerateSurveyStatsService.class);
    private static final int MAX_COMMIT = 100;
    private static RepositoryService repositoryService = new RepositoryService();

    private long surveyId;
    private HttpServletRequest request;
    private UserSession userSession;

    public void generateStatsService(long surveyId, HttpServletRequest request, UserSession userSession)
    {
        if(surveyId <= 0) return;

        SurveyImpl survey = DaoFactory.getSurveyDaoImpl().load(surveyId);
        if(survey != null)
        {
            GenerateSurveyStatsService s = new GenerateSurveyStatsService();
            s.request = request;
            s.surveyId = surveyId;
            s.userSession = userSession;

            // start a thread
            1.5.0/docs/api/java/lang/Thread.html">Thread thread = new 1.5.0/docs/api/java/lang/Thread.html">Thread(s);
            thread.start();
            logger.info("Starting thread with id: "+thread.getId());
        }
    }

    private synchronized JFreeChart buildChart(HttpServletRequest request, SurveyQuestion q, SurveyStructuralNode node, UserSession userSession, boolean withCategories)
    {
        // get counted values and labels
        List<Integer> countedValues = new ArrayList<Integer>();
        1.5.0/docs/api/java/lang/String.html">String itemLabels = "";
        1.5.0/docs/api/java/lang/String.html">String candidateLabels = "";
        for(SurveyQuestionItem qi : q.getQuestionItems())
        {
            for(SurveyQuestionCandidateAnswer ca : qi.getCandidadeAnswers())
            {
                int count = DaoFactory.getSurveyQuestionAnswerDaoImpl().countAnswers(ca.getId(), node.getId());
                countedValues.add(count);
                candidateLabels = candidateLabels + ca.getLabelpt() + ",";
            }
            itemLabels = itemLabels + qi.getLabelpt() + ",";
        }
        1.5.0/docs/api/java/lang/String.html">String[] categories = itemLabels.split(",");
        1.5.0/docs/api/java/lang/String.html">String[] series = candidateLabels.split(",");
        int[] values = new int[countedValues.size()];
        for(int i=0; i<countedValues.size(); i++)
            values[i] = countedValues.get(i);

        // create chart
        1.5.0/docs/api/java/lang/String.html">String domainAxisLabel = MessageResources.getMessage(request,"survey.stats.graph.axis.domain.label");
        PlotOrientation orientation = PlotOrientation.HORIZONTAL;
        if(!withCategories)
        {
            categories = null;
            domainAxisLabel = "";
            orientation = PlotOrientation.VERTICAL;
        }

        CategoryDataset dataset = buildCategoryDataset(categories,series,values);
        JFreeChart chart = buildJFreeChart(q.getLabelpt(),domainAxisLabel,MessageResources.getMessage(request,"survey.stats.graph.axis.range.label"),dataset,orientation);

        // chart configs
        final CategoryPlot plot = chart.getCategoryPlot();
        final ValueAxis valueAxis = plot.getRangeAxis();
        final CategoryAxis categoryAxis = plot.getDomainAxis();
        final CategoryLabelPositions positions = categoryAxis.getCategoryLabelPositions();
        1.5.0/docs/api/java/awt/Font.html">Font font = new 1.5.0/docs/api/java/awt/Font.html">Font("Tahoma",1.5.0/docs/api/java/awt/Font.html">Font.PLAIN, 11);
        categoryAxis.setMaximumCategoryLabelLines(3);
        categoryAxis.setTickLabelFont(font);
        CategoryLabelPosition right = new CategoryLabelPosition(RectangleAnchor.RIGHT, TextBlockAnchor.CENTER_RIGHT);
        categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.replaceRightPosition(positions, right));

        return chart;
    }

    public synchronized 1.5.0/docs/api/java/lang/String.html">String storeChartRepository(JFreeChart chart, 1.5.0/docs/api/java/lang/String.html">String filename, 1.5.0/docs/api/java/lang/String.html">String description, 1.5.0/docs/api/java/lang/String.html">String identifier, UserSession userSession)
    {
        try
        {
            1.5.0/docs/api/java/io/File.html">File file = new 1.5.0/docs/api/java/io/File.html">File(Globals.TMP_DIR + filename);
            1.5.0/docs/api/java/lang/String.html">String extension = FilesUtils.getExtension(filename);
            ChartUtilities.saveChartAsPNG(file, chart,
                    ConfigProperties.getIntProperty("surveys.stats.graph.img.width"),
                    ConfigProperties.getIntProperty("surveys.stats.graph.img.height"));
            1.5.0/docs/api/java/io/FileInputStream.html">FileInputStream inputStream = new 1.5.0/docs/api/java/io/FileInputStream.html">FileInputStream(file);

            if(identifier == null)
                identifier = repositoryService.storeRepositoryFile(inputStream,"image/png",extension,(int)file.length(),file.getName(),description,ResourceAccessControlEnum.surveyStatsDomain,userSession);
            else
                repositoryService.updateRepositoryFile(identifier,inputStream,"image/png",extension,(int)file.length(),file.getName(),description,ResourceAccessControlEnum.surveyStatsDomain);

            boolean deleted = file.delete();
            if(!deleted)
                logger.info("Error deleting file: "+filename);
        }
        catch (1.5.0/docs/api/java/io/IOException.html">IOException e)
        {
            logger.info(e);
        }
        return identifier;
    }

    public synchronized JFreeChart buildJFreeChart(1.5.0/docs/api/java/lang/String.html">String chartTitle,1.5.0/docs/api/java/lang/String.html">String domainAxisLabel,1.5.0/docs/api/java/lang/String.html">String rangeAxisLabel,CategoryDataset dataset,PlotOrientation orientation)
    {
        JFreeChart chart = ChartFactory.createBarChart(chartTitle,domainAxisLabel,rangeAxisLabel,dataset,orientation,true,true,false);
        CategoryPlot plot = chart.getCategoryPlot();
        plot.getRangeAxis().setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        return chart;
    }

    public synchronized CategoryDataset buildCategoryDataset(1.5.0/docs/api/java/lang/String.html">String[] categories, 1.5.0/docs/api/java/lang/String.html">String[] series, int[] values)
    {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        int k = 0;
        int serLen = series.length;
        if(categories != null)
        {
            int j = 0;
            int catLen = categories.length;
            for(int i = 0; i < series.length; i++)
            {
                if(i != 0 && i%(serLen/catLen) == 0)
                    j++;
                dataset.addValue(values[k++], series[i], categories[j]);
            }
        }
        else
        {
            for(1.5.0/docs/api/java/lang/String.html">String serie : series)
                dataset.addValue(values[k++], serie, "");
        }
        return dataset;
    }

    public void run()
    {
        logger.info("Running thread...");
        AbstractDao.getCurrentSession().beginTransaction();

        SurveyImpl survey = DaoFactory.getSurveyDaoImpl().load(surveyId);

        survey.setStatusPercentage(0);
        survey.setStatus(SurveyStatusEnum.STATUS_GENERATE_STATS.getStatus());

        AbstractDao.getCurrentSession().getTransaction().commit();
        AbstractDao.getCurrentSession().beginTransaction();

        survey = DaoFactory.getSurveyDaoImpl().load(surveyId);

        GenerateSurveyStatsCsvService service = new GenerateSurveyStatsCsvService();
        service.run(surveyId,userSession);

        List<SurveyStructuralNode> childNodes = ((SurveyStructuralNodeImpl)survey.getStructuralNode()).getChildsStructuralNodes();

        long total = childNodes.size() * survey.getQuestions().size();
        long i = 0;
        int status;
        for(SurveyStructuralNode node : childNodes)
        {
            for(SurveyQuestion question : survey.getQuestions())
            {
                long nodeId = node.getId();
                long questionId = question.getId();

                if (i++ % MAX_COMMIT == 0)
                {
                    status = (int)(((double)i/(double)total)*100);
                    survey.setStatusPercentage(status);
                    AbstractDao.getCurrentSession().getTransaction().commit();
                    AbstractDao.getCurrentSession().beginTransaction();
                    survey = DaoFactory.getSurveyDaoImpl().load(surveyId);
                }
                node = DaoFactory.getSurveyStructuralNodeDaoImpl().load(nodeId);
                question = DaoFactory.getSurveyQuestionDaoImpl().load(questionId);

                JFreeChart chart = null;
                if(question.getType().equals(Globals.SURVEY_QUESTION_TYPE_MATRIX))
                    chart = buildChart(request, question, node, userSession, true);
                else if(question.getType().equals(Globals.SURVEY_QUESTION_TYPE_CHECK) || question.getType().equals(Globals.SURVEY_QUESTION_TYPE_RADIO))
                    chart = buildChart(request, question, node, userSession, false);

                if(chart != null)
                {
                    node = DaoFactory.getSurveyStructuralNodeDaoImpl().load(nodeId);
                    question = DaoFactory.getSurveyQuestionDaoImpl().load(questionId);
                    1.5.0/docs/api/java/lang/String.html">String identifier;
                    1.5.0/docs/api/java/lang/String.html">String filename = "/survey_"+surveyId+"_question_"+question.getId()+"_node_"+node.getId()+".png";
                    SurveyStatsGraphic graph = DaoFactory.getSurveyStatsGraphicDaoImpl().load(question.getId(),node.getId());
                    if(graph == null)
                    {
                        identifier = storeChartRepository(chart,filename,"descricao",null,userSession);
                        if(identifier != null)
                        {
                            graph = DomainObjectFactory.createSurveyStatsGraphicImpl();
                            graph.setQuestion(question);
                            graph.setStructuralNode(node);
                            graph.setIdentifier(identifier);
                            DaoFactory.getSurveyStatsGraphicDaoImpl().save(graph);
                        }
                    }
                    else
                    {
                        identifier = graph.getIdentifier();
                        storeChartRepository(chart,filename,"descricao",identifier,userSession);
                    }
                }
            }
        }

        survey.setStatusPercentage(100);
        survey.setStatus(SurveyStatusEnum.STATUS_STOPPED.getStatus());

        AbstractDao.getCurrentSession().getTransaction().commit();
        logger.info("End of thread...");
    }
}