/*
* Copyright (C) 2006 Erik Swenson - erik@oreports.com
*
* 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 2 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 reserved a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package org.efs.openreports.services;
import com.thoughtworks.xstream.XStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.efs.openreports.ORStatics;
import org.efs.openreports.ReportConstants.DeliveryMethod;
import org.efs.openreports.engine.ReportEngine;
import org.efs.openreports.engine.ReportEngineHelper;
import org.efs.openreports.engine.input.ReportEngineInput;
import org.efs.openreports.engine.output.QueryEngineOutput;
import org.efs.openreports.engine.output.ReportEngineOutput;
import org.efs.openreports.objects.Report;
import org.efs.openreports.objects.ReportLog;
import org.efs.openreports.objects.ReportSchedule;
import org.efs.openreports.objects.ReportUser;
import org.efs.openreports.providers.DataSourceProvider;
import org.efs.openreports.providers.DirectoryProvider;
import org.efs.openreports.providers.ParameterProvider;
import org.efs.openreports.providers.PropertiesProvider;
import org.efs.openreports.providers.ProviderException;
import org.efs.openreports.providers.ReportLogProvider;
import org.efs.openreports.providers.ReportProvider;
import org.efs.openreports.providers.SchedulerProvider;
import org.efs.openreports.providers.UserProvider;
import org.efs.openreports.services.info.ReportInfo;
import org.efs.openreports.services.input.ParameterInput;
import org.efs.openreports.services.input.ReportServiceInput;
import org.efs.openreports.services.output.ReportServiceOutput;
import org.efs.openreports.services.util.Converter;
import org.efs.openreports.util.LocalStrings;
import org.efs.openreports.util.ORUtil;
/**
* ReportService implementation using standard OpenReports providers.
*
* @author Erik Swenson
*/
public class ReportServiceImpl implements ReportService
{
private static Logger log = Logger.getLogger(ReportServiceImpl.class.getName());
private ReportProvider reportProvider;
private ReportLogProvider reportLogProvider;
private SchedulerProvider schedulerProvider;
private UserProvider userProvider;
private DirectoryProvider directoryProvider;
private ParameterProvider parameterProvider;
private DataSourceProvider dataSourceProvider;
private PropertiesProvider propertiesProvider;
private UserService userService;
private XStream xStream;
public ReportServiceImpl()
{
this.xStream = new XStream();
log.info("ReportService: Started");
}
/**
* Generate a Report and return a ReportEngineOutput. Contents of the
* ReportEngineOutput vary with the deliveryMethod and exportType of the
* ReportServiceInput.
*
* Returns errors messages in the message field of the ReportServiceOutput.
*
* Includes Report Logging functionality.
*/
public ReportServiceOutput generateReport(ReportServiceInput reportInput)
{
ReportServiceOutput reportOutput = new ReportServiceOutput();
try
{
userService.authenticate(reportInput.getUser());
}
catch(ServiceException e)
{
reportOutput.setContentMessage(e.getMessage());
return reportOutput;
}
if (reportInput.getReportName() == null)
{
reportOutput.setContentMessage(ServiceMessages.REPORT_NAME_REQUIRED);
return reportOutput;
}
try
{
Report report = reportProvider.getReport(reportInput.getReportName());
if (report == null)
{
reportOutput.setContentMessage("Invalid ReportInput - Report not found: " + reportInput.getReportName());
log.warn("generateReport: request : " + reportInput.getRequestId() + " : " + reportOutput.getContentMessage());
return reportOutput;
}
ReportUser user = userProvider.getUser(reportInput.getUser().getUserName(), reportInput.getUser().getPassword());
if (user == null)
{
reportOutput.setContentMessage("Invalid ReportInput - User not found: " + reportInput.getUser().getUserName());
log.warn("generateReport: request : " + reportInput.getRequestId() + " : " + reportOutput.getContentMessage());
return reportOutput;
}
if (!user.isValidReport(report))
{
reportOutput.setContentMessage("Invalid ReportInput - "
+ user.getName() + " not authorized to run: "
+ reportInput.getReportName());
log.warn("generateReport: request : " + reportInput.getRequestId() + " : " + reportOutput.getContentMessage());
return reportOutput;
}
log.info("generateReport: reserved request : " + reportInput.getRequestId() + " : for report : " + report.getName() + " : from : " + user.getName());
if (reportInput.getDeliveryMethods() == null || reportInput.getDeliveryMethods().length < 1)
{
ReportLog reportLog = null;
try
{
reportLog = new ReportLog(user, report, new Date());
reportLog.setExportType(reportInput.getExportType().getCode());
reportLog = reportLogProvider.insertReportLog(reportLog);
ReportEngine reportEngine = ReportEngineHelper.getReportEngine(report,
dataSourceProvider, directoryProvider, propertiesProvider);
ReportEngineInput engineInput = new ReportEngineInput(report, buildParameterMap(reportInput, report));
engineInput.setExportType(reportInput.getExportType());
engineInput.setXmlInput(reportInput.getXmlInput());
engineInput.setLocale(ORUtil.getLocale(reportInput.getLocale()));
ReportEngineOutput reportEngineOutput = reportEngine.generateReport(engineInput);
reportOutput.setContent(reportEngineOutput.getContent());
reportOutput.setContentType(reportEngineOutput.getContentType());
reportOutput.setContentExtension(reportEngineOutput.getContentExtension());
//convert List of Dynabeans to XML so that it can be serialized
if (reportEngineOutput instanceof QueryEngineOutput)
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
xStream.toXML(((QueryEngineOutput)reportEngineOutput).getResults(), out);
reportOutput.setContent(out.toByteArray());
reportOutput.setContentType(ReportEngineOutput.CONTENT_TYPE_XML);
out.close();
}
reportLog.setStatus(ReportLog.STATUS_SUCCESS);
reportLog.setEndTime(new Date());
reportLogProvider.updateReportLog(reportLog);
}
catch(Exception e)
{
if (reportLog != null && reportLog.getId() != null)
{
reportLog.setStatus(ReportLog.STATUS_FAILURE);
reportLog.setMessage(e.getMessage());
reportLog.setEndTime(new Date());
try
{
reportLogProvider.updateReportLog(reportLog);
}
catch (Exception ex)
{
log.error("Unable to update ReportLog: " + ex.getMessage());
}
}
}
}
else
{
ReportSchedule schedule = new ReportSchedule();
schedule.setReport(report);
schedule.setUser(user);
schedule.setReportParameters(buildParameterMap(reportInput, report));
schedule.setExportType(reportInput.getExportType().getCode());
schedule.setScheduleName(report.getId() + "|" + new Date().getTime());
schedule.setScheduleDescription(reportInput.getScheduleDescription());
schedule.setScheduleType(ReportSchedule.ONCE);
schedule.setXmlInput(reportInput.getXmlInput());
schedule.setDeliveryReturnAddress(reportInput.getDeliveryReturnAddress());
schedule.setRequestId(reportInput.getRequestId());
schedule.setSchedulePriority(reportInput.getSchedulePriority());
schedule.setDeliveryMethods(convertDeliveryMethodsToNames(reportInput.getDeliveryMethods()));
schedule.setLocale(ORUtil.getLocale(reportInput.getLocale()));
if (reportInput.getDeliveryAddress() != null)
{
schedule.setRecipients(reportInput.getDeliveryAddress());
}
else
{
schedule.setRecipients(user.getEmail());
}
// advanced scheduling
if (reportInput.getStartDate() != null)
{
if (!user.isAdvancedScheduler())
{
throw new ProviderException("Not Authorized: Advanced Scheduling permission required");
}
schedule.setScheduleType(reportInput.getScheduleType().getCode());
schedule.setStartDate(reportInput.getStartDate());
schedule.setStartHour(reportInput.getStartHour());
schedule.setStartMinute(reportInput.getStartMinute());
schedule.setStartAmPm(reportInput.getStartAmPm().toString());
schedule.setHours(reportInput.getHours());
schedule.setCronExpression(reportInput.getCronExpression());
}
schedulerProvider.scheduleReport(schedule);
}
reportOutput.setContentMessage(LocalStrings.SERVICE_REQUEST_COMPLETE);
}
catch (Exception e)
{
log.error("generateReport: request : " + reportInput.getRequestId(), e);
reportOutput.setContentMessage(e.getMessage());
}
log.info("generateReport: request : " + reportInput.getRequestId() + " : status : " + reportOutput.getContentMessage());
return reportOutput;
}
public ReportInfo getReportInfo(String reportName)
{
ReportInfo reportInfo = null;
try
{
Report report = reportProvider.getReport(reportName);
if (report != null)
{
reportInfo = Converter.convertToReportInfo(report);
}
}
catch(ProviderException pe)
{
log.warn(pe);
}
return reportInfo;
}
/**
* Builds report parameter map from incoming ReportServiceInput and adds
* standard report parameters.
*/
private Map<String,Object> buildParameterMap(ReportServiceInput reportServiceInput, Report report) throws ProviderException
{
Map<String,Object> inputParameters = new HashMap<String,Object>();
if (reportServiceInput.getParameters() != null)
{
ParameterInput[] parameters = reportServiceInput.getParameters();
for (int i=0; i < parameters.length; i++)
{
inputParameters.put(parameters[i].getName(), parameters[i].getValues());
}
}
Map<String,Object> parsedParameters = parameterProvider.getReportParametersMap(report.getParameters(), inputParameters);
parsedParameters.put(ORStatics.IMAGE_DIR, new File(directoryProvider.getReportImageDirectory()));
parsedParameters.put(ORStatics.REPORT_DIR, new File(directoryProvider.getReportDirectory()));
return parsedParameters;
}
private String[] convertDeliveryMethodsToNames(DeliveryMethod[] deliveryMethods) throws ServiceException
{
if (deliveryMethods == null || deliveryMethods.length < 1 || deliveryMethods[0] == null)
{
throw new ServiceException("Delivery method not specified.");
}
String[] deliveryMethodNames = new String[deliveryMethods.length];
for (int i=0; i < deliveryMethods.length; i++)
{
deliveryMethodNames[i] = deliveryMethods[i].getName();
}
return deliveryMethodNames;
}
public void setDirectoryProvider(DirectoryProvider directoryProvider)
{
this.directoryProvider = directoryProvider;
}
public void setParameterProvider(ParameterProvider parameterProvider)
{
this.parameterProvider = parameterProvider;
}
public void setReportLogProvider(ReportLogProvider reportLogProvider)
{
this.reportLogProvider = reportLogProvider;
}
public void setReportProvider(ReportProvider reportProvider)
{
this.reportProvider = reportProvider;
}
public void setSchedulerProvider(SchedulerProvider schedulerProvider)
{
this.schedulerProvider = schedulerProvider;
}
public void setUserProvider(UserProvider userProvider)
{
this.userProvider = userProvider;
}
public void setDataSourceProvider(DataSourceProvider dataSourceProvider)
{
this.dataSourceProvider = dataSourceProvider;
}
public void setPropertiesProvider(PropertiesProvider propertiesProvider)
{
this.propertiesProvider = propertiesProvider;
}
public void setUserService(UserService userService)
{
this.userService = userService;
}
}