net.webpasswordsafe.server.report.JasperReportServlet.java Source code

Java tutorial

Introduction

Here is the source code for net.webpasswordsafe.server.report.JasperReportServlet.java

Source

/*
Copyright 2009-2013 Josh Drummond
    
This file is part of WebPasswordSafe.
    
WebPasswordSafe 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.
    
WebPasswordSafe 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 WebPasswordSafe; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
package net.webpasswordsafe.server.report;

import java.io.IOException;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.springframework.web.context.support.WebApplicationContextUtils;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRRtfExporter;
import net.sf.jasperreports.engine.export.JRXmlExporter;
import net.sf.jasperreports.engine.type.WhenNoDataTypeEnum;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import net.webpasswordsafe.common.model.User;
import net.webpasswordsafe.common.util.Constants;
import net.webpasswordsafe.common.util.Utils;
import net.webpasswordsafe.server.plugin.audit.AuditLogger;
import net.webpasswordsafe.server.plugin.authorization.Authorizer;
import net.webpasswordsafe.server.plugin.encryption.Encryptor;

/**
 * Servlet that handles generation of specified reports using Jasper Reports
 * 
 * @author Josh Drummond
 *
 */
public class JasperReportServlet extends HttpServlet {
    private static Logger LOG = Logger.getLogger(JasperReportServlet.class);
    private static final long serialVersionUID = 2493946517487023931L;
    public static ThreadLocal<Encryptor> encryptorRef = new ThreadLocal<Encryptor>();

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    private void processRequest(HttpServletRequest req, HttpServletResponse res) {
        OutputStream outputStream = null;
        Connection jdbcConnection = null;
        try {
            String reportName = req.getParameter(Constants.NAME);
            String type = req.getParameter(Constants.TYPE).trim().toLowerCase();
            String locale = req.getParameter("locale");
            setNoCache(res);
            if (isAuthorizedReport(req, reportName)) {
                JasperDesign jasperDesign = JRXmlLoader.load(getServletConfig().getServletContext()
                        .getResourceAsStream("/WEB-INF/reports/" + reportName + ".jrxml"));
                JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
                jasperReport.setWhenNoDataType(WhenNoDataTypeEnum.ALL_SECTIONS_NO_DETAIL);
                Map<String, Object> parameters = new HashMap<String, Object>();
                if (null != locale)
                    parameters.put(JRParameter.REPORT_LOCALE, new Locale(locale));
                parameters.put(Constants.SESSION_KEY_USERNAME,
                        (String) req.getSession().getAttribute(Constants.SESSION_KEY_USERNAME));
                parameters.put(Constants.Function.BYPASS_PASSWORD_PERMISSIONS.name(),
                        isAuthorized(req, Constants.Function.BYPASS_PASSWORD_PERMISSIONS.name()) ? "1" : "0");
                ReportConfig reportConfig = (ReportConfig) WebApplicationContextUtils
                        .getWebApplicationContext(getServletContext()).getBean("reportConfig");
                @SuppressWarnings("unchecked")
                Enumeration<String> e = req.getParameterNames();
                while (e.hasMoreElements()) {
                    String param = e.nextElement();
                    if (param.startsWith(Constants.REPORT_PARAM_PREFIX)) {
                        String pKey = param.substring(Constants.REPORT_PARAM_PREFIX.length());
                        String pValue = Utils.safeString(req.getParameter(param));
                        if (reportConfig.isDateParam(reportName, pKey)) {
                            parameters.put(pKey, convertToDateTime(pValue));
                        } else {
                            parameters.put(pKey, pValue);
                        }
                    }
                }
                encryptorRef.set((Encryptor) WebApplicationContextUtils
                        .getWebApplicationContext(getServletContext()).getBean("encryptor"));
                DataSource dataSource = (DataSource) WebApplicationContextUtils
                        .getWebApplicationContext(getServletContext()).getBean("dataSource");
                jdbcConnection = dataSource.getConnection();
                JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, jdbcConnection);
                JRExporter exporter = null;

                if (type.equals(Constants.REPORT_TYPE_PDF)) {
                    res.setContentType("application/pdf");
                    exporter = new JRPdfExporter();
                } else if (type.equals("rtf")) {
                    res.setContentType("application/rtf");
                    exporter = new JRRtfExporter();
                } else if (type.equals(Constants.REPORT_TYPE_CSV)) {
                    res.setContentType("text/csv");
                    exporter = new JRCsvExporter();
                } else if (type.equals("xml")) {
                    res.setContentType("text/xml");
                    exporter = new JRXmlExporter();
                }

                if (exporter != null) {
                    DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
                    res.setHeader("Content-Disposition", "attachment; filename=" + reportName
                            + dateFormat.format(System.currentTimeMillis()) + "." + type);

                    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                    outputStream = res.getOutputStream();
                    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, outputStream);
                    exporter.exportReport();
                } else {
                    throw new RuntimeException("Invalid report type: " + type);
                }
            }
        } catch (Exception e) {
            LOG.error("JasperReportServlet Error " + e.getMessage(), e);
        } finally {
            // close the output stream
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException io) {
                    LOG.error("JasperReportServlet Error " + io.getMessage(), io);
                }
            }
            // close the db connection
            if (jdbcConnection != null) {
                try {
                    jdbcConnection.close();
                } catch (SQLException sql) {
                    LOG.error("JasperReportServlet Error " + sql.getMessage(), sql);
                } finally {
                    jdbcConnection = null;
                }
            }
        }
    }

    private Timestamp convertToDateTime(String pValue) throws ParseException {
        Timestamp pDateValue = null;
        if (!"".equals(pValue)) {
            // try with timestamp
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            try {
                pDateValue = new Timestamp(dateFormat.parse(pValue).getTime());
            } catch (ParseException pe) {
                // try without timestamp
                dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                pDateValue = new Timestamp(dateFormat.parse(pValue).getTime());
                // throw exception if neither parsed
            }
        }
        return pDateValue;
    }

    private boolean isAuthorizedReport(HttpServletRequest req, String reportName) {
        boolean isAuthorized = isAuthorized(req, Constants.VIEW_REPORT_PREFIX + reportName);
        User user = new User();
        user.setUsername((String) req.getSession().getAttribute(Constants.SESSION_KEY_USERNAME));
        AuditLogger auditLogger = (AuditLogger) WebApplicationContextUtils
                .getWebApplicationContext(getServletContext()).getBean("auditLogger");
        auditLogger.log(new Date(), user.getUsername(), req.getRemoteAddr(), "view report", reportName,
                isAuthorized, (isAuthorized ? "" : "not authorized"));
        return isAuthorized;
    }

    @SuppressWarnings("unchecked")
    private boolean isAuthorized(HttpServletRequest req, String action) {
        boolean isAuthorized = false;
        Authorizer authorizer = (Authorizer) WebApplicationContextUtils
                .getWebApplicationContext(getServletContext()).getBean("authorizer");
        User user = new User();
        user.setUsername((String) req.getSession().getAttribute(Constants.SESSION_KEY_USERNAME));
        user.setRoles((Set<Constants.Role>) req.getSession().getAttribute(Constants.SESSION_KEY_ROLES));
        try {
            isAuthorized = authorizer.isAuthorized(user, action);
        } catch (Exception e) {
            isAuthorized = false;
        }
        return isAuthorized;
    }

    private void setNoCache(HttpServletResponse res) {
        res.setHeader("Pragma", "no-cache");
        res.setHeader("Cache-Control", "no-cache,no-store");
        res.setDateHeader("Expires", 0);
    }
}