Java tutorial
/* Mango - Open Source M2M - http://mango.serotoninsoftware.com Copyright (C) 2006-2011 Serotonin Software Technologies Inc. @author Matthew Lohbihler This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.serotonin.mango.rt.maint.work; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.mail.internet.AddressException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.joda.time.DateTime; import com.serotonin.InvalidArgumentException; import com.serotonin.io.StreamUtils; import com.serotonin.mango.Common; import com.serotonin.mango.db.dao.DataPointDao; import com.serotonin.mango.db.dao.MailingListDao; import com.serotonin.mango.db.dao.ReportDao; import com.serotonin.mango.db.dao.UserDao; import com.serotonin.mango.vo.DataPointVO; import com.serotonin.mango.vo.User; import com.serotonin.mango.vo.permission.Permissions; import com.serotonin.mango.vo.report.ImageChartUtils; import com.serotonin.mango.vo.report.ReportChartCreator; import com.serotonin.mango.vo.report.ReportChartCreator.PointStatistics; import com.serotonin.mango.vo.report.ReportInstance; import com.serotonin.mango.vo.report.ReportPointVO; import com.serotonin.mango.vo.report.ReportVO; import com.serotonin.util.ColorUtils; import com.serotonin.util.StringUtils; import com.serotonin.web.email.EmailAttachment; import com.serotonin.web.email.EmailContent; import com.serotonin.web.email.EmailInline; import com.serotonin.web.i18n.LocalizableMessage; ////exchange import com.serotonin.mango.rt.exchange.ExchangeAttachment; import microsoft.exchange.webservices.data.EmailAddress; import com.serotonin.mango.rt.exchange.Content; import com.serotonin.mango.rt.exchange.ExchangeSend; import com.serotonin.mango.db.dao.SystemSettingsDao; /** * @author Matthew Lohbihler */ public class ReportWorkItem implements WorkItem { static final Log LOG = LogFactory.getLog(ReportWorkItem.class); public int getPriority() { return WorkItem.PRIORITY_LOW; } public static void queueReport(ReportVO report) { LOG.info("Queuing report with id " + report.getId()); // Verify that the user is not disabled. User user = new UserDao().getUser(report.getUserId()); if (user.isDisabled()) return; // User is ok. Continue... ReportWorkItem item = new ReportWorkItem(); // Create the database record in process. item.reportConfig = report; ReportInstance reportInstance = new ReportInstance(report); item.user = user; item.reportDao = new ReportDao(); item.reportDao.saveReportInstance(reportInstance); // Start the report work item out of process. item.reportInstance = reportInstance; Common.ctx.getBackgroundProcessing().addWorkItem(item); LOG.info("Queued report with id " + report.getId() + ", instance id " + reportInstance.getId()); } ReportVO reportConfig; private User user; private ReportDao reportDao; private ReportInstance reportInstance; List<File> filesToDelete = new ArrayList<File>(); public void execute() { LOG.info("Running report with id " + reportConfig.getId() + ", instance id " + reportInstance.getId()); reportInstance.setRunStartTime(System.currentTimeMillis()); reportDao.saveReportInstance(reportInstance); ResourceBundle bundle = Common.getBundle(); // Create a list of DataPointVOs to which the user has permission. DataPointDao dataPointDao = new DataPointDao(); List<ReportDao.PointInfo> points = new ArrayList<ReportDao.PointInfo>(reportConfig.getPoints().size()); for (ReportPointVO reportPoint : reportConfig.getPoints()) { DataPointVO point = dataPointDao.getDataPoint(reportPoint.getPointId()); if (point != null && Permissions.hasDataPointReadPermission(user, point)) { String colour = null; try { if (!StringUtils.isEmpty(reportPoint.getColour())) colour = ColorUtils.toHexString(reportPoint.getColour()).substring(1); } catch (InvalidArgumentException e) { // Should never happen since the colour would have been validated on save, so just let it go // as null. } points.add(new ReportDao.PointInfo(point, colour, reportPoint.isConsolidatedChart())); // pointNames.add(point); } } int recordCount = 0; try { if (!points.isEmpty()) recordCount = reportDao.runReport(reportInstance, points, bundle); } catch (RuntimeException e) { recordCount = -1; throw e; } catch (Throwable e) { recordCount = -1; throw new RuntimeException("Report instance failed", e); } finally { reportInstance.setRunEndTime(System.currentTimeMillis()); reportInstance.setRecordCount(recordCount); reportDao.saveReportInstance(reportInstance); } if (reportConfig.isEmail()) { String inlinePrefix = "R" + System.currentTimeMillis() + "-" + reportInstance.getId() + "-"; // List<DataPointVO> pointNames=reportDao.getPointsByInstanceId(reportInstance.getId()); // We are creating an email from the result. Create the content. final ReportChartCreator creator = new ReportChartCreator(bundle); creator.createContent(reportInstance, reportDao, inlinePrefix, reportConfig.isIncludeData()); // Create the to list Set<String> addresses = new MailingListDao().getRecipientAddresses(reportConfig.getRecipients(), new DateTime(reportInstance.getReportStartTime())); String[] toAddrs = addresses.toArray(new String[0]); // Create the email content object. EmailContent emailContent = new EmailContent(null, creator.getHtml(), Common.UTF8); /////////////////////////////////////////////////////// //////exchange boolean isExchange = SystemSettingsDao.isExchange(); List<ExchangeAttachment> attachments = new ArrayList<ExchangeAttachment>(); ///////////////////////////////////////////////////////// // Add the consolidated chart if (creator.getImageData() != null) { if (isExchange) { ExchangeAttachment ea = new ExchangeAttachment( inlinePrefix + ReportChartCreator.IMAGE_CONTENT_ID, true, creator.getImageData()); attachments.add(ea); } else { emailContent.addInline( new EmailInline.ByteArrayInline(inlinePrefix + ReportChartCreator.IMAGE_CONTENT_ID, creator.getImageData(), ImageChartUtils.getContentType())); } } // Add the point charts for (PointStatistics pointStatistics : creator.getPointStatistics()) { if (pointStatistics.getImageData() != null) { if (isExchange) { ExchangeAttachment image = new ExchangeAttachment( inlinePrefix + pointStatistics.getChartName(), true, pointStatistics.getImageData()); attachments.add(image); } else { emailContent.addInline( new EmailInline.ByteArrayInline(inlinePrefix + pointStatistics.getChartName(), pointStatistics.getImageData(), ImageChartUtils.getContentType())); } } } // Add optional images used by the template. for (String s : creator.getInlineImageList()) { if (isExchange) { attachments.add(new ExchangeAttachment(s, true, Common.ctx.getServletContext().getRealPath(s))); } else { addImage(emailContent, s); } } // Check if we need to attach the data. if (reportConfig.isIncludeData()) { if (isExchange) { attachments.add(new ExchangeAttachment("baseData.csv", creator.getExportFile().getPath())); attachments.add(new ExchangeAttachment("Events.csv", creator.getEventFile().getPath())); attachments.add(new ExchangeAttachment("Comments.csv", creator.getCommentFile().getPath())); } else { addFileAttachment(emailContent, "baseData.csv", creator.getExportFile()); addFileAttachment(emailContent, "Events.csv", creator.getEventFile()); addFileAttachment(emailContent, "Comments.csv", creator.getCommentFile()); } } Runnable[] postEmail = null; if (reportConfig.isIncludeData()) { // See that the temp file(s) gets deleted after the email is sent. Runnable deleteTempFile = new Runnable() { public void run() { for (File file : filesToDelete) { if (!file.delete()) LOG.warn("Temp file " + file.getPath() + " not deleted"); } } }; postEmail = new Runnable[] { deleteTempFile }; } try { LocalizableMessage lm = new LocalizableMessage("ftl.scheduledReport", reportConfig.getName()); /////////////////////////////////////////////////////////// //exchange if (isExchange) { List<EmailAddress> address = new ArrayList<EmailAddress>(); for (String email : toAddrs) { EmailAddress add = new EmailAddress(); add.setAddress(email); address.add(add); } Content exchangeContent = new Content(lm.getLocalizedMessage(bundle), creator.getHtml(), creator.getHtml(), null, null); exchangeContent.setSubject(lm.getLocalizedMessage(bundle)); exchangeContent.setAttachments(attachments); ExchangeSend exchangeSend = new ExchangeSend(address, exchangeContent); exchangeSend.sendMail(); } else { EmailWorkItem.queueEmail(toAddrs, lm.getLocalizedMessage(bundle), emailContent, postEmail); } ///////////////////////////////////////////////////////////// } catch (Exception e) { LOG.error(e); } // Delete the report instance. reportDao.deleteReportInstance(reportInstance.getId(), user.getId()); } LOG.info("Finished running report with id " + reportConfig.getId() + ", instance id " + reportInstance.getId()); } private void addImage(EmailContent emailContent, String imagePath) { emailContent.addInline( new EmailInline.FileInline(imagePath, Common.ctx.getServletContext().getRealPath(imagePath))); } private void addFileAttachment(EmailContent emailContent, String name, File file) { if (file != null) { if (reportConfig.isZipData()) { try { File zipFile = File.createTempFile("tempZIP", ".zip"); ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile)); zipOut.putNextEntry(new ZipEntry(name)); FileInputStream in = new FileInputStream(file); StreamUtils.transfer(in, zipOut); in.close(); zipOut.closeEntry(); zipOut.close(); emailContent.addAttachment(new EmailAttachment.FileAttachment(name + ".zip", zipFile)); filesToDelete.add(zipFile); } catch (IOException e) { LOG.error("Failed to create zip file", e); } } else emailContent.addAttachment(new EmailAttachment.FileAttachment(name, file)); filesToDelete.add(file); } } }