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...");
}
}