if (report == null) {
throw new JobExecutionException("Report " + reportId + " not found");
}
// 1. create execution
ReportExec execution = new ReportExec();
execution.setStatus(ReportExecStatus.STARTED);
execution.setStartDate(new Date());
execution.setReport(report);
execution = reportExecDAO.save(execution);
report.addExec(execution);
report = reportDAO.save(report);
// 2. define a SAX handler for generating result as XML
TransformerHandler handler;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
zos.setLevel(Deflater.BEST_COMPRESSION);
try {
SAXTransformerFactory tFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
handler = tFactory.newTransformerHandler();
Transformer serializer = handler.getTransformer();
serializer.setOutputProperty(OutputKeys.ENCODING, SyncopeConstants.DEFAULT_ENCODING);
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
// a single ZipEntry in the ZipOutputStream
zos.putNextEntry(new ZipEntry(report.getName()));
// streaming SAX handler in a compressed byte array stream
handler.setResult(new StreamResult(zos));
} catch (Exception e) {
throw new JobExecutionException("While configuring for SAX generation", e, true);
}
execution.setStatus(ReportExecStatus.RUNNING);
execution = reportExecDAO.save(execution);
// 3. actual report execution
StringBuilder reportExecutionMessage = new StringBuilder();
StringWriter exceptionWriter = new StringWriter();
try {
// report header
handler.startDocument();
AttributesImpl atts = new AttributesImpl();
atts.addAttribute("", "", ATTR_NAME, XSD_STRING, report.getName());
handler.startElement("", "", ELEMENT_REPORT, atts);
// iterate over reportlet instances defined for this report
for (ReportletConf reportletConf : report.getReportletConfs()) {
Class<Reportlet> reportletClass =
dataBinder.findReportletClassHavingConfClass(reportletConf.getClass());
if (reportletClass != null) {
Reportlet autowired = (Reportlet) ApplicationContextProvider.getBeanFactory().
createBean(reportletClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
autowired.setConf(reportletConf);
// invoke reportlet
try {
autowired.extract(handler);
} catch (Exception e) {
execution.setStatus(ReportExecStatus.FAILURE);
Throwable t = e instanceof ReportException
? e.getCause()
: e;
exceptionWriter.write(t.getMessage() + "\n\n");
t.printStackTrace(new PrintWriter(exceptionWriter));
reportExecutionMessage.append(exceptionWriter.toString()).append("\n==================\n");
}
}
}
// report footer
handler.endElement("", "", ELEMENT_REPORT);
handler.endDocument();
if (!ReportExecStatus.FAILURE.name().equals(execution.getStatus())) {
execution.setStatus(ReportExecStatus.SUCCESS);
}
} catch (Exception e) {
execution.setStatus(ReportExecStatus.FAILURE);
exceptionWriter.write(e.getMessage() + "\n\n");
e.printStackTrace(new PrintWriter(exceptionWriter));
reportExecutionMessage.append(exceptionWriter.toString());
throw new JobExecutionException(e, true);
} finally {
try {
zos.closeEntry();
zos.close();
baos.close();
} catch (IOException e) {
LOG.error("While closing StreamResult's backend", e);
}
execution.setExecResult(baos.toByteArray());
execution.setMessage(reportExecutionMessage.toString());
execution.setEndDate(new Date());
reportExecDAO.save(execution);
}
}