/** * *************************************************************************** * Copyright (c) 2010 Qcadoo Limited * Project: Qcadoo Framework * Version: 1.4 * * This file is part of Qcadoo. * * Qcadoo is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************** */ package com.qcadoo.report.internal.controller; import static org.apache.commons.io.IOUtils.copy; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.json.JSONException; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.qcadoo.model.api.DataDefinitionService; import com.qcadoo.model.api.Entity; import com.qcadoo.report.api.ReportException; import com.qcadoo.report.api.ReportService; import com.qcadoo.view.api.exception.ClassDrivenExceptionResolver; @Controller public class ReportController { @Autowired private ReportService reportService; @Autowired private DataDefinitionService dataDefinitionService; @Autowired @Qualifier("exceptionResolver") private ClassDrivenExceptionResolver exceptionResolver; @PostConstruct public void init() { exceptionResolver.addExceptionInfoResolver(ReportException.class, new ReportExceptionInfoResolver()); } @RequestMapping(value = "generateReportForEntity/{templatePlugin}/{templateName}", method = RequestMethod.GET) public void generateReportForEntity(@PathVariable("templatePlugin") final String templatePlugin, @PathVariable("templateName") final String templateName, @RequestParam("id") final List<Long> entityIds, @RequestParam("additionalArgs") final String requestAdditionalArgs, final HttpServletRequest request, final HttpServletResponse response, final Locale locale) throws ReportException { ReportService.ReportType reportType = getReportType(request); Map<String, String> additionalArgs = convertJsonStringToMap(requestAdditionalArgs); response.setContentType(reportType.getMimeType()); try { int bytes = copy( new ByteArrayInputStream(reportService.generateReportForEntity(templatePlugin, templateName, reportType, entityIds, additionalArgs, locale)), response.getOutputStream()); response.setContentLength(bytes); } catch (IOException e) { throw new ReportException(ReportException.Type.ERROR_WHILE_COPYING_REPORT_TO_RESPONSE, e); } disableCache(response); } @RequestMapping(value = "generateSavedReport/{plugin}/{model}", method = RequestMethod.GET) public void generateSavedReport(@PathVariable("plugin") final String plugin, @PathVariable("model") final String model, @RequestParam("id") final String id, @RequestParam(value = "reportNo", required = false, defaultValue = "0") final String reportNo, final HttpServletRequest request, final HttpServletResponse response) throws ReportException { ReportService.ReportType reportType = getReportType(request); Entity entity = dataDefinitionService.get(plugin, model).get(Long.parseLong(id)); String filename = entity.getStringField("fileName").split(",")[Integer.valueOf(reportNo)]; String translatedFileName = filename.substring(filename.lastIndexOf(File.separator) + 1) + "." + reportType.getExtension(); response.setHeader("Content-disposition", "inline; filename=" + translatedFileName); response.setContentType(reportType.getMimeType()); try { int bytes = copy(new FileInputStream(new File(filename + "." + reportType.getExtension())), response.getOutputStream()); response.setContentLength(bytes); } catch (IOException e) { throw new IllegalStateException(e.getMessage(), e); } } private ReportService.ReportType getReportType(final HttpServletRequest request) throws ReportException { String uri = request.getRequestURI(); String type = uri.substring(uri.lastIndexOf('.') + 1).toUpperCase(Locale.getDefault()); try { return ReportService.ReportType.valueOf(type); } catch (IllegalArgumentException e) { throw new ReportException(ReportException.Type.WRONG_REPORT_TYPE, e, type); } } private Map<String, String> convertJsonStringToMap(final String jsonText) throws ReportException { Map<String, String> result = new HashMap<String, String>(); try { JSONObject userArgsObject = new JSONObject(jsonText); @SuppressWarnings("unchecked") Iterator<String> it = userArgsObject.keys(); while (it.hasNext()) { String key = it.next(); result.put(key, userArgsObject.getString(key)); } } catch (JSONException e) { throw new ReportException(ReportException.Type.JSON_EXCEPTION, e); } return result; } private void disableCache(final HttpServletResponse response) { response.addHeader("Expires", "Tue, 03 Jul 2001 06:00:00 GMT"); response.addHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0"); response.addHeader("Cache-Control", "post-check=0, pre-check=0"); response.addHeader("Pragma", "no-cache"); } }