ar.com.fdvs.dj.struts2.DJStruts2Result.java Source code

Java tutorial

Introduction

Here is the source code for ar.com.fdvs.dj.struts2.DJStruts2Result.java

Source

/*
 * DynamicJasper: A library for creating reports dynamically by specifying
 * columns, groups, styles, etc. at runtime. It also saves a lot of development
 * time in many cases! (http://sourceforge.net/projects/dynamicjasper)
 *
 * Copyright (C) 2008  FDV Solutions (http://www.fdvsolutions.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 *
 * License as published by the Free Software Foundation; either
 *
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 *
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 *
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *
 */

package ar.com.fdvs.dj.struts2;

import java.io.IOException;
import java.sql.ResultSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JRResultSetDataSource;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanArrayDataSource;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.StrutsException;
import org.apache.struts2.StrutsStatics;
import org.apache.struts2.views.jasperreports.JasperReportsResult;
import org.apache.struts2.views.jasperreports.ValueStackShadowMap;

import ar.com.fdvs.dj.core.DJException;
import ar.com.fdvs.dj.core.DynamicJasperHelper;
import ar.com.fdvs.dj.core.layout.ClassicLayoutManager;
import ar.com.fdvs.dj.core.layout.LayoutManager;
import ar.com.fdvs.dj.core.layout.ListLayoutManager;
import ar.com.fdvs.dj.domain.DynamicReport;
import ar.com.fdvs.dj.output.FormatInfoRegistry;
import ar.com.fdvs.dj.output.ReportWriter;
import ar.com.fdvs.dj.output.ReportWriterFactory;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.util.TextParseUtil;

/**
 * @author Alejandro Gomez, Juan Alvarez
 *         Date: Feb 22, 2007
 *         Time: 4:32:34 PM
 */
public class DJStruts2Result extends JasperReportsResult {

    private static final long serialVersionUID = -5135527859073133975L;

    private static final Log LOG = LogFactory.getLog(DJStruts2Result.class);

    public static final String LAYOUT_CLASSIC = "classic";
    public static final String LAYOUT_LIST = "list";

    protected String dynamicReport;

    protected String documentFormat;

    /**
     * The layout manager to use. Possible values are: classic, list, or a fully qualified java name
     */
    protected String layoutManager;

    protected String exportParams;

    protected String parameters;

    /**
     * Due to private access in StrutsResultSupport we our own copy.
     */
    private boolean parse;

    public void setDynamicReport(final String _dynamicReport) {
        dynamicReport = _dynamicReport;
    }

    public void setParse(final boolean _parse) {
        super.setParse(_parse);
        parse = _parse;
    }

    /**
     * Executes the result given a final location (jsp page, action, etc) and the action invocation
     * (the state in which the action was executed). Subclasses must implement this class to handle
     * custom logic for result handling.
     *
     * @param _finalLocation the location (jsp page, action, etc) to go to.
     * @param _invocation    the execution state of the action.
     * @throws Exception if an error occurs while executing the result.
     */
    protected void doExecute(final String _finalLocation, final ActionInvocation _invocation) throws Exception {
        checkParams();
        documentFormat = getFormat(_invocation);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Creating JasperReport for dynamicReport, format = " + documentFormat);
        }

        Map actionParametersMap = getParametersMap(_invocation);

        final JRDataSource ds = buildJRDataSource(_invocation.getStack().findValue(dataSource));

        // (Map) ActionContext.getContext().getSession().get("IMAGES_MAP");

        final HttpServletRequest request = (HttpServletRequest) _invocation.getInvocationContext()
                .get(StrutsStatics.HTTP_REQUEST);
        final HttpServletResponse response = (HttpServletResponse) _invocation.getInvocationContext()
                .get(StrutsStatics.HTTP_RESPONSE);

        if ("contype".equals(request.getHeader("User-Agent"))) {
            // Code to handle "contype" request from IE
            handleConTypeRequest(response);
        } else {
            ValueStackShadowMap parameters = new ValueStackShadowMap(_invocation.getStack());
            parameters.putAll(actionParametersMap);

            parameters.put(JRParameter.REPORT_LOCALE, _invocation.getInvocationContext().getLocale());
            LayoutManager layoutManagerObj = getLayOutManagerObj(_invocation);

            JasperPrint jasperPrint = null;
            if (ds != null)
                jasperPrint = DynamicJasperHelper.generateJasperPrint(getDynamicReport(_invocation),
                        layoutManagerObj, ds, parameters);
            else
                jasperPrint = DynamicJasperHelper.generateJasperPrint(getDynamicReport(_invocation),
                        layoutManagerObj, parameters);

            // Export the print object to the desired output format
            writeReponse(request, response, jasperPrint, _invocation);
        }
    }

    /**
     * Returns the object pointed by the result-type parameter "parameters"
     * @param _invocation
     * @return
     */
    protected Map getParametersMap(ActionInvocation _invocation) {
        Map map = (Map) _invocation.getStack().findValue(this.parameters);
        if (map == null)
            map = new HashMap();
        return map;
    }

    /**
     * returns the JRDataSource pointed by the result-type parameter "dataSource"
     * Accepts JRDataSource, Collection, ResultSet and Object[]
     * @param dsCandidate
     * @return
     */
    protected JRDataSource buildJRDataSource(Object dsCandidate) {
        if (dsCandidate == null)
            return null;

        if (dsCandidate instanceof JRDataSource)
            return (JRDataSource) dsCandidate;

        if (dsCandidate instanceof Collection)
            return new JRBeanCollectionDataSource((Collection) dsCandidate);

        if (dsCandidate instanceof ResultSet)
            return new JRResultSetDataSource((ResultSet) dsCandidate);

        if (dsCandidate.getClass().isArray())
            return new JRBeanArrayDataSource((Object[]) dsCandidate);

        throw new DJException("class " + dsCandidate.getClass().getName() + " is not supported "
                + "from the DynamicJasper WebWorK result type. Provide a JRDataSource implementation instead");
    }

    /**
     * Returns the export format indicated in the result-type parameter "layoutManager"
     * @param _invocation
     * @return
     */
    protected LayoutManager getLayOutManagerObj(ActionInvocation _invocation) {
        if (layoutManager == null || "".equals(layoutManager)) {
            LOG.warn("No valid LayoutManager, using ClassicLayoutManager");
            return new ClassicLayoutManager();
        }

        Object los = conditionalParse(layoutManager, _invocation);

        if (los instanceof LayoutManager) {
            return (LayoutManager) los;
        }

        LayoutManager lo = null;
        if (los instanceof String) {
            if (LAYOUT_CLASSIC.equalsIgnoreCase((String) los))
                lo = new ClassicLayoutManager();
            else if (LAYOUT_LIST.equalsIgnoreCase((String) los))
                lo = new ListLayoutManager();
            else {
                try {
                    lo = (LayoutManager) Class.forName((String) los).newInstance();
                } catch (Exception e) {
                    LOG.warn("No valid LayoutManager: " + e.getMessage(), e);
                }
            }
        }

        return lo;
    }

    protected void handleConTypeRequest(final HttpServletResponse _response) throws ServletException {
        try {
            _response.setContentType(FormatInfoRegistry.getInstance().getContentType(documentFormat)); //
            _response.setContentLength(0);
            _response.getOutputStream().close();
        } catch (IOException ex) {
            LOG.error("Error writing report output", ex);
            throw new ServletException(ex.getMessage(), ex);
        }
    }

    protected void checkParams() {
        if (dynamicReport == null) {
            final String message = "No dynamicReport specified...";
            LOG.error(message);
            throw new StrutsException(message);
        }

        //Some reports may not need specifically a datasource
        if (dataSource == null) {
            final String message = "No dataSource specified...";
            LOG.debug(message);
        }
    }

    protected void setResponseHeaders(final HttpServletResponse _response, final ActionInvocation _invocation) {
        if (contentDisposition != null || documentName != null) {
            final StringBuffer buffer = new StringBuffer();
            buffer.append(getContentDisposition(_invocation));
            if (documentName != null) {
                buffer.append("; filename=");
                buffer.append(getDocumentName(_invocation));
                buffer.append(".");
                buffer.append(documentFormat.toLowerCase());
            }
            _response.setHeader("Content-disposition", buffer.toString());
        }
        _response.setContentType(FormatInfoRegistry.getInstance().getContentType(documentFormat));
    }

    protected void writeReponse(final HttpServletRequest _request, final HttpServletResponse _response,
            final JasperPrint _jasperPrint, final ActionInvocation _invocation) throws JRException, IOException {
        setResponseHeaders(_response, _invocation);
        final HashMap parameters = new HashMap(getExportParams(_invocation));
        parameters.put(JRHtmlExporterParameter.IMAGES_URI, _request.getContextPath() + imageServletUrl);

        final ReportWriter reportWriter = ReportWriterFactory.getInstance().getReportWriter(_jasperPrint,
                documentFormat, parameters);

        if (FORMAT_HTML.equals(documentFormat)) {
            Map imagesMap = new HashMap();
            JRExporter exporter = reportWriter.getExporter();
            exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesMap);
            exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, _request.getContextPath() + imageServletUrl);
            // Needed to support chart images:
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, _jasperPrint);
            _request.getSession().setAttribute("net.sf.jasperreports.j2ee.jasper_print", _jasperPrint);
        }

        reportWriter.writeTo(_response);
    }

    protected Map getExportParams(final ActionInvocation _invocation) {
        Map params = (Map) conditionalParse(exportParams, _invocation, Map.class);
        if (params == null) {
            params = new HashMap();
        }
        return params;
    }

    protected DynamicReport getDynamicReport(final ActionInvocation _invocation) {
        return (DynamicReport) _invocation.getStack().findValue(dynamicReport);
    }

    protected String getFormat(final ActionInvocation _invocation) {
        final String parsedFormat = conditionalParse(format == null ? FORMAT_PDF : format, _invocation);
        return StringUtils.isEmpty(parsedFormat) ? FORMAT_PDF : parsedFormat;
    }

    protected String getDocumentName(final ActionInvocation _invocation) {
        return conditionalParse(documentName, _invocation);
    }

    protected String getContentDisposition(final ActionInvocation _invocation) {
        final String parsedContentDisposition = conditionalParse(contentDisposition, _invocation);
        return parsedContentDisposition == null ? "inline" : parsedContentDisposition;
    }

    protected Object conditionalParse(final String _param, final ActionInvocation _invocation, final Class _type) {
        if (parse && _param != null && _invocation != null) {
            return TextParseUtil.translateVariables('$', _param, _invocation.getStack(), _type, null);
        } else {
            return _param;
        }
    }

    public String getLayoutManager() {
        return layoutManager;
    }

    public void setLayoutManager(String layoutManager) {
        this.layoutManager = layoutManager;
    }

    public String getExportParams() {
        return exportParams;
    }

    public void setExportParams(String exportParams) {
        this.exportParams = exportParams;
    }

    public void setParameters(String parameters) {
        this.parameters = parameters;
    }
}