/*******************************************************************************
* Australian National University Data Commons
* Copyright (C) 2013 The Australian National University
*
* This file is part of Australian National University Data Commons.
*
* Australian National University Data Commons 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 au.edu.anu.datacommons.report;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import au.edu.anu.datacommons.data.db.dao.GenericDAO;
import au.edu.anu.datacommons.data.db.dao.GenericDAOImpl;
import au.edu.anu.datacommons.data.db.model.FedoraObject;
import au.edu.anu.datacommons.data.db.model.Groups;
import au.edu.anu.datacommons.data.db.model.PublishLocation;
import au.edu.anu.datacommons.data.db.model.Report;
import au.edu.anu.datacommons.data.db.model.ReportParam;
import au.edu.anu.datacommons.report.schedule.ReportScheduler;
import au.edu.anu.datacommons.report.schedule.ScheduledReport;
import au.edu.anu.datacommons.security.service.FedoraObjectService;
import au.edu.anu.datacommons.security.service.GroupService;
import au.edu.anu.datacommons.util.Util;
import com.sun.jersey.api.view.Viewable;
/**
* ReportResource
*
* Australian National University Data Commons
*
* Resource for reporting purposes
*
* JUnit Coverage:
* None
*
* <pre>
* Version Date Developer Description
* 0.1 27/09/2012 Genevieve Turner (GT) Initial
* 0.2 02/10/2012 Genevieve Turner (GT) MOved reload of reports functionality to ReportGenerator class
* 0.3 02/10/2012 Genevieve Turner (GT) Updated to verify the user has permissions to execute a report prior to generating the report
* 0.4 30/10/2012 Genevieve Turner (GT) Updated to make available more report types
* 0.5 12/11/2012 Genevieve Turner (GT) Added web service report type
* </pre>
*
*/
@Component
@Scope("request")
@Path("/report")
public class ReportResource {
static final Logger LOGGER = LoggerFactory.getLogger(ReportResource.class);
@Resource(name = "fedoraObjectServiceImpl")
private FedoraObjectService fedoraObjectService;
@Resource(name = "groupServiceImpl")
private GroupService groupService;
@Resource(name = "reportServiceImpl")
private ReportService reportService;
/**
* getReportPage
*
* Get a page that list the types of reports
*
* <pre>
* Version Date Developer Description
* X.X 30/10/2012 Genevieve Turner(GT) Initial
* </pre>
*
* @return
*/
@GET
@Produces(MediaType.TEXT_HTML)
@PreAuthorize("hasRole('ROLE_ANU_USER')")
public Response getReportPage() {
return Response.ok(new Viewable("/report.jsp")).build();
}
/**
* getSingleItemReportPage
*
* Get the page to ask questions about the report to generate
*
* <pre>
* Version Date Developer Description
* 0.1 27/09/2012 Genevieve Turner(GT) Initial
* 0.2 30/10/2012 Genevieve Turner (GT) Renamed and changed the jsp used
* </pre>
*
* @return
*/
@GET
@Path("single")
@Produces(MediaType.TEXT_HTML)
@PreAuthorize("hasRole('ROLE_ANU_USER')")
public Response getSingleItemReportPage(@QueryParam("pid") String pid) {
Map<String, Object> model = new HashMap<String, Object>();
if (Util.isNotEmpty(pid)) {
model.put("pid", pid);
}
return Response.ok(new Viewable("/report_single.jsp", model)).build();
}
/**
* getPublishedReportPage
*
* Get the page to generate a report that is generated for a particular location
*
* <pre>
* Version Date Developer Description
* 0.4 30/10/2012 Genevieve Turner(GT) Initial
* </pre>
*
* @return
*/
@GET
@Path("published")
@Produces(MediaType.TEXT_HTML)
@PreAuthorize("hasRole('ROLE_ANU_USER')")
public Response getPublishedReportPage() {
GenericDAO<PublishLocation, Long> publishLocationDAO = new GenericDAOImpl<PublishLocation, Long>(PublishLocation.class);
List<PublishLocation> publishLocations = publishLocationDAO.getAll();
Map<String, Object> model = new HashMap<String, Object>();
model.put("publishLocations", publishLocations);
return Response.ok(new Viewable("/report_published.jsp", model)).build();
}
/**
* Get a report by group
*
* @return The report
*/
@GET
@Path("group")
@Produces(MediaType.TEXT_HTML)
@PreAuthorize("hasRole('ROLE_ANU_USER')")
public Response getGroupsReportPage() {
Map<String, Object> model = new HashMap<String, Object>();
List<Groups> groups = groupService.getAll();
model.put("groups", groups);
return Response.ok(new Viewable("/report_group.jsp", model)).build();
}
/**
* getMultipleItemReportPage
*
* Get a page to check the reports for multiple items
*
* <pre>
* Version Date Developer Description
* 0.4 30/10/2012 Genevieve Turner(GT) Initial
* </pre>
*
* @return
*/
@GET
@Path("multiple")
@Produces(MediaType.TEXT_HTML)
@PreAuthorize("hasRole('ROLE_ANU_USER')")
public Response getMultipleItemReportPage() {
return Response.ok(new Viewable("/report_multiple.jsp")).build();
}
/**
* getWebServiceReportPage
*
* Get a page to retrieve reports for the web service
*
* <pre>
* Version Date Developer Description
* 0.5 12/11/2012 Genevieve Turner(GT) Initial
* </pre>
*
* @return
*/
@GET
@Path("webservice")
@Produces(MediaType.TEXT_HTML)
@PreAuthorize("hasRole('ROLE_ANU_USER')")
public Response getWebServiceReportPage() {
return Response.ok(new Viewable("/report_webservice.jsp")).build();
}
/**
* getReport
*
* Get the actual report
*
* <pre>
* Version Date Developer Description
* 0.1 27/09/2012 Genevieve Turner(GT) Initial
* 0.3 02/10/2012 Genevieve Turner (GT) Updated to verify the user has permissions to execute a report prior to generating the report
* </pre>
*
* @param context The context information
* @param request The request information
* @return
*/
@POST
@PreAuthorize("hasRole('ROLE_ANU_USER')")
public Response getReport(@Context ServletContext context, @Context HttpServletRequest request) {
ReportGenerator report = new ReportGenerator(request, context.getRealPath("/"));
String pid = request.getParameter("pid");
if (Util.isNotEmpty(pid)) {
FedoraObject fedoraObject = fedoraObjectService.getItemByPid(pid);
fedoraObjectService.hasReportPermission(fedoraObject);
}
Response response = null;
try {
String format = request.getParameter("format");
response = report.generateReport(format);
}
catch (Exception e) {
LOGGER.error("Exception processing report", e);
throw new WebApplicationException(Response.status(500).entity("Exception processing report").build());
}
if (response == null) {
LOGGER.error("Response is null?");
}
return response;
}
/**
* reloadReports
*
* Reload the reports
*
* <pre>
* Version Date Developer Description
* 0.1 27/09/2012 Genevieve Turner(GT) Initial
* 0.2 02/10/2012 Genevieve Turner (GT) Moved reload to ReportGenerator class
* </pre>
*
* @param context The servlet context information
* @return The response
*/
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/reload")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public Response reloadReports(@Context ServletContext context) {
ReportGenerator.reloadReports(context);
UriBuilder uriBuilder = UriBuilder.fromPath("/reload");
return Response.seeOther(uriBuilder.build()).build();
}
/**
* Reschedule all the automated reports
*
* @param context The servlet context
* @return The response
*/
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/auto/reload")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public Response reloadAutoReports(@Context ServletContext context) {
new ReportScheduler(context).scheduleAll();
UriBuilder uriBuilder = UriBuilder.fromPath("/reload");
return Response.seeOther(uriBuilder.build()).build();
}
/**
* Get the report scheduler page
*
* @param context
* @return
*/
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/schedule")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public Response getScheduleReportsPage() {
Map<String, Object> model = new HashMap<String, Object>();
List<Report> reports = reportService.getAllReports();
model.put("reports", reports);
return Response.ok(new Viewable("/report_scheduler.jsp", model)).build();
}
/**
* Schedule a report to run
*
* @param request The HttpServletRequest
* @param reportId The report id
* @param dayOfWeek The day of the week for the report to run
* @param hour The hour at which to run the report
* @param minute The minute at which to run the report
* @param email The email address to send the report to
* @return The response object
*/
@POST
@Produces(MediaType.TEXT_HTML)
@Path("/schedule")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public Response createScheduledReport(@Context HttpServletRequest request,
@FormParam("report") Long reportId, @FormParam("dayOfWeek") String dayOfWeek, @FormParam("hour") String hour,
@FormParam("minute") String minute, @FormParam("email") String email, @FormParam("format") String format) {
LOGGER.info("Scheduling report {} to run every {} at {}:{} and send it to {}", reportId, dayOfWeek, hour, minute, email);
String cron = reportService.generateCronString(dayOfWeek, hour, minute);
Map<String, String[]> parameterMap = request.getParameterMap();
reportService.schedule(reportId, email, cron, format, parameterMap);
UriBuilder uriBuilder = UriBuilder.fromResource(this.getClass()).path("scheduled");
return Response.seeOther(uriBuilder.build()).build();
}
/**
* Get the list of scheduled reports
*
* @return The response object
*/
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/scheduled")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public Response getScheduledReports() {
Map<String, Object> model = new HashMap<String, Object>();
List<ScheduledReport> scheduledReports = reportService.getScheduledReports();
model.put("scheduled", scheduledReports);
return Response.ok(new Viewable("/report_scheduled.jsp", model)).build();
}
/**
* Delete the scheduled report with the provided id
*
* @param reportAutoId The report auto id
* @return The response object
*/
@DELETE
@Path("scheduled/{reportAutoId}")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public Response deleteScheduledReport(@PathParam("reportAutoId") Long reportAutoId) {
LOGGER.info("Deleting scheduled report with the id {}", reportAutoId);
reportService.deleteScheduledReport(reportAutoId);
return Response.ok().build();
}
/**
* Get the parameters associated with a report
*
* @param reportId The report id
* @return The response object
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/schedule/report-param/{reportId}")
public Response getReportParameters(@PathParam("reportId") Long reportId) {
List<ReportParam> reportParams = reportService.getReportParameters(reportId);
return Response.ok(reportParams).build();
}
/**
* Get the possible groups to associate the report with
*
* @return The response object
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/schedule/groups")
public Response getReportGroups() {
List<Groups> groups = reportService.getGroups();
return Response.ok(groups).build();
}
}