mirror of
https://github.com/apache/struts.git
synced 2026-08-05 22:56:59 +00:00
WW-5455 Defines a new plugin to support Jasper Reports 7 (#1124)
* WW-5455 Defines a new plugin to support Jasper Reports 7 * WW-5455 Allows action to modify result behaviour * WW-5455 Defines exporter as an extension point * WW-5455 Extracts logic to create connection or dataSource * WW-5455 Uses defaultDelimiter as more meaningful name * WW-5455 Fixes parent version after re-basing * WW-5455 Updates pom to match the latest SNAPSHOT version * WW-5455 Cleans up code * WW-5455 Adds the new plugin to BOM * WW-5455 Fixes broken test
This commit is contained in:
@@ -172,6 +172,11 @@
|
||||
<artifactId>struts2-jasperreports-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-jasperreports7-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-jfreechart-plugin</artifactId>
|
||||
|
||||
@@ -86,6 +86,11 @@
|
||||
<artifactId>struts2-jasperreports-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-jasperreports7-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-javatemplates-plugin</artifactId>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Jasper Reports plugin
|
||||
This plugin allows to use Jasper reports as a one of the result types.
|
||||
You will find more details in [documentation](https://struts.apache.org/plugins/jasperreports/).
|
||||
|
||||
## Installation
|
||||
Just drop this plugin JAR into `WEB-INF/lib` folder or add it as a Maven dependency.
|
||||
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>7.0.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jasperreports7-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Struts 2 Jasper Reports 7 Plugin [EXPERIMENTAL]</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<jasperreports7.version>7.0.1</jasperreports7.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sf.jasperreports</groupId>
|
||||
<artifactId>jasperreports</artifactId>
|
||||
<version>${jasperreports7.version}</version>
|
||||
<exclusions>
|
||||
<!-- not necessary to compile and it force dependency convergence issues -->
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.jasperreports</groupId>
|
||||
<artifactId>jasperreports-pdf</artifactId>
|
||||
<version>${jasperreports7.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-junit-plugin</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7;
|
||||
|
||||
import net.sf.jasperreports.engine.JasperReport;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.StrutsException;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public interface JasperReport7Aware {
|
||||
|
||||
/**
|
||||
* Used to perform an action before report is going to be generated
|
||||
*
|
||||
* @param invocation current {@link ActionInvocation}
|
||||
*/
|
||||
default void beforeReportGeneration(ActionInvocation invocation) throws StrutsException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to perform an action before report is going to be generated
|
||||
*
|
||||
* @param invocation current {@link ActionInvocation}
|
||||
*/
|
||||
default void afterReportGeneration(ActionInvocation invocation, JasperReport jasperReport) throws StrutsException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to specify action specific CSV delimiter, if returns null,
|
||||
* default one specified by {@link JasperReport7Constants#STRUTS_JASPER_REPORT_CSV_DELIMITER} will be used
|
||||
*
|
||||
* @return delimiter or null
|
||||
*/
|
||||
default String getCsvDelimiter(ActionInvocation invocation) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to specify different local than used by the framework or an action
|
||||
*
|
||||
* @param invocation current {@link ActionInvocation}
|
||||
* @return locale or null
|
||||
*/
|
||||
default Locale getReportLocale(ActionInvocation invocation) {
|
||||
return invocation.getInvocationContext().getLocale();
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7;
|
||||
|
||||
public interface JasperReport7Constants {
|
||||
|
||||
/**
|
||||
* PDF format constant
|
||||
*/
|
||||
String FORMAT_PDF = "pdf";
|
||||
|
||||
/**
|
||||
* XML format constant
|
||||
*/
|
||||
String FORMAT_XML = "xml";
|
||||
|
||||
/**
|
||||
* HTML format constant
|
||||
*/
|
||||
String FORMAT_HTML = "html";
|
||||
|
||||
/**
|
||||
* XLSX format constant
|
||||
*/
|
||||
String FORMAT_XLSX = "xlsx";
|
||||
|
||||
/**
|
||||
* CSV format constant
|
||||
*/
|
||||
String FORMAT_CSV = "csv";
|
||||
|
||||
/**
|
||||
* RTF format constant
|
||||
*/
|
||||
String FORMAT_RTF = "rtf";
|
||||
|
||||
/**
|
||||
* Allows to define a custom default delimiter when exporting report into CSV file
|
||||
*/
|
||||
String STRUTS_JASPER_REPORT_CSV_DELIMITER = "struts.jasperReport7.csv.defaultDelimiter";
|
||||
|
||||
/**
|
||||
* Allows to define a custom url to image servlet used when exporting report into HTML
|
||||
*/
|
||||
String STRUTS_JASPER_REPORT_HTML_IMAGE_SERVLET_URL = "struts.jasperReport7.html.imageServletUrl";
|
||||
|
||||
}
|
||||
+384
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.sf.jasperreports.engine.JRException;
|
||||
import net.sf.jasperreports.engine.JRParameter;
|
||||
import net.sf.jasperreports.engine.JasperFillManager;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.JasperReport;
|
||||
import net.sf.jasperreports.engine.util.JRLoader;
|
||||
import net.sf.jasperreports.export.Exporter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.result.StrutsResultSupport;
|
||||
import org.apache.struts2.security.NotExcludedAcceptedPatternsChecker;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
import org.apache.struts2.views.jasperreports7.export.JasperReport7ExporterProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: description -->
|
||||
* <p>
|
||||
* Generates a JasperReports report using the specified format or PDF if no
|
||||
* format is specified.
|
||||
* </p>
|
||||
* <!-- END SNIPPET: description -->
|
||||
* <p>
|
||||
* <b>This result type takes the following parameters:</b>
|
||||
* </p>
|
||||
* <!-- START SNIPPET: params -->
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li><b>location (default)</b> - the location where the compiled jasper report
|
||||
* definition is (foo.jasper), relative from current URL.</li>
|
||||
* <li><b>dataSource (required)</b> - the EL expression used to retrieve the
|
||||
* datasource from the value stack (usually a List).</li>
|
||||
* <li><b>parse</b> - true by default. If set to false, all the parameters will
|
||||
* not be parsed for EL expressions.</li>
|
||||
* <li><b>format</b> - the format in which the report should be generated. Valid
|
||||
* values can be found in {@link JasperReport7Constants}. If no format is
|
||||
* specified, PDF will be used.</li>
|
||||
* <li><b>contentDisposition</b> - disposition (defaults to "inline", values are
|
||||
* typically <i>filename="document.pdf"</i>).</li>
|
||||
* <li><b>documentName</b> - name of the document (will generate the http header
|
||||
* <code>Content-disposition = X; filename=X.[format]</code>).</li>
|
||||
* <li>
|
||||
* <b>reportParameters</b> - an expression used to retrieve a map of
|
||||
* report parameters from the value stack. The parameters may be accessed
|
||||
* in the report via the usual JR mechanism and might include data not
|
||||
* part of the dataSource, such as the user name of the report creator, etc.
|
||||
* </li>
|
||||
* <li>
|
||||
* <b>connection</b> - a JDBC Connection which can be passed to the
|
||||
* report instead of dataSource
|
||||
* </li>
|
||||
* <li><b>wrapField</b> - defines if fields should warp with ValueStackDataSource
|
||||
* see <a href="https://issues.apache.org/jira/browse/WW-3698">WW-3698</a> for more details
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* This result follows the same rules from {@link StrutsResultSupport}.
|
||||
* Specifically, all parameters will be parsed if the "parse" parameter
|
||||
* is not set to false.
|
||||
* </p>
|
||||
* <!-- END SNIPPET: params -->
|
||||
* <p><b>Example:</b></p>
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: example1 -->
|
||||
* <result name="success" type="jasperReport7">
|
||||
* <param name="location">foo.jasper</param>
|
||||
* <param name="dataSource">mySource</param>
|
||||
* <param name="format">CSV</param>
|
||||
* </result>
|
||||
* <!-- END SNIPPET: example1 -->
|
||||
* </pre>
|
||||
* <p>
|
||||
* or for pdf
|
||||
*
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: example2 -->
|
||||
* <result name="success" type="jasperReport7">
|
||||
* <param name="location">foo.jasper</param>
|
||||
* <param name="dataSource">mySource</param>
|
||||
* </result>
|
||||
* <!-- END SNIPPET: example2 -->
|
||||
* </pre>
|
||||
*/
|
||||
public class JasperReport7Result extends StrutsResultSupport implements JasperReport7Constants {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(JasperReport7Result.class);
|
||||
|
||||
private String parsedDataSource;
|
||||
|
||||
protected String dataSource;
|
||||
protected String format;
|
||||
protected String documentName;
|
||||
protected String contentDisposition;
|
||||
protected String timeZone;
|
||||
|
||||
protected boolean wrapField = true;
|
||||
|
||||
/**
|
||||
* Connection can be passed to the report instead of dataSource.
|
||||
*/
|
||||
protected String connection;
|
||||
|
||||
/**
|
||||
* Names a report parameters map stack value, allowing additional report parameters from the action.
|
||||
*/
|
||||
protected String reportParameters;
|
||||
private String parsedReportParameters;
|
||||
|
||||
/**
|
||||
* Parameters validator, excludes not accepted params
|
||||
*/
|
||||
private NotExcludedAcceptedPatternsChecker notExcludedAcceptedPatterns;
|
||||
|
||||
public JasperReport7Result() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setNotExcludedAcceptedPatterns(NotExcludedAcceptedPatternsChecker notExcludedAcceptedPatterns) {
|
||||
this.notExcludedAcceptedPatterns = notExcludedAcceptedPatterns;
|
||||
}
|
||||
|
||||
protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
|
||||
initializeProperties(invocation);
|
||||
|
||||
LOG.debug("Creating JasperReport for dataSource: {} and format: {}", dataSource, format);
|
||||
// Construct the data source for the report.
|
||||
ValueStack stack = invocation.getStack();
|
||||
Connection reportConnection = (Connection) stack.findValue(connection);
|
||||
ValueStackDataSource reportDataSource = null;
|
||||
if (reportConnection == null) {
|
||||
reportDataSource = prepareDataSource(stack);
|
||||
}
|
||||
|
||||
if (invocation.getAction() instanceof JasperReport7Aware action) {
|
||||
LOG.debug("Passing control to action: {} before generating report", invocation.getInvocationContext().getActionName());
|
||||
action.beforeReportGeneration(invocation);
|
||||
}
|
||||
|
||||
ServletContext servletContext = invocation.getInvocationContext().getServletContext();
|
||||
String systemId = servletContext.getRealPath(finalLocation);
|
||||
Map<String, Object> parameters = new ValueStackShadowMap(stack);
|
||||
File directory = new File(systemId.substring(0, systemId.lastIndexOf(File.separator)));
|
||||
parameters.put("reportDirectory", directory);
|
||||
|
||||
applyLocale(invocation, parameters);
|
||||
applyTimeZone(invocation, parameters);
|
||||
applyCustomParameters(stack, parameters);
|
||||
|
||||
JasperPrint jasperPrint;
|
||||
|
||||
// Fill the report and produce a print object
|
||||
try {
|
||||
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(new File(systemId));
|
||||
if (reportConnection == null) {
|
||||
jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, reportDataSource);
|
||||
} else {
|
||||
jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, reportConnection);
|
||||
}
|
||||
|
||||
if (invocation.getAction() instanceof JasperReport7Aware action) {
|
||||
LOG.debug("Passing control to action: {} after generating report: {}",
|
||||
invocation.getInvocationContext().getActionName(), jasperReport.getName());
|
||||
action.afterReportGeneration(invocation, jasperReport);
|
||||
}
|
||||
} catch (JRException e) {
|
||||
LOG.error("Error building report for uri: {}", systemId, e);
|
||||
throw new ServletException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
try {
|
||||
LOG.debug("Export the print object to the desired output format: {}", format);
|
||||
JasperReport7ExporterProvider<?> exporterProvider = invocation.getInvocationContext().getContainer().getInstance(JasperReport7ExporterProvider.class, format);
|
||||
if (exporterProvider == null) {
|
||||
throw new StrutsException("No exporter found for format: " + format);
|
||||
}
|
||||
exportReport(invocation, jasperPrint, exporterProvider);
|
||||
} catch (StrutsException e) {
|
||||
LOG.error("Error producing: {} report for uri: {}", format, systemId, e);
|
||||
throw new ServletException(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
if (reportConnection != null) {
|
||||
reportConnection.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Could not close db connection properly", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ValueStackDataSource prepareDataSource(ValueStack stack) throws ServletException {
|
||||
boolean evaluated = parsedDataSource != null && !parsedDataSource.equals(dataSource);
|
||||
boolean reevaluate = !evaluated || isAcceptableExpression(parsedDataSource);
|
||||
if (reevaluate) {
|
||||
return new ValueStackDataSource(stack, parsedDataSource, wrapField);
|
||||
} else {
|
||||
throw new ServletException(String.format("Unaccepted dataSource expression [%s]", parsedDataSource));
|
||||
}
|
||||
}
|
||||
|
||||
protected void applyLocale(ActionInvocation invocation, Map<String, Object> parameters) {
|
||||
Locale locale = null;
|
||||
if (invocation.getAction() instanceof JasperReport7Aware action) {
|
||||
locale = action.getReportLocale(invocation);
|
||||
}
|
||||
if (locale == null) {
|
||||
locale = invocation.getInvocationContext().getLocale();
|
||||
}
|
||||
|
||||
LOG.debug("Using locale: {} to generate report", locale);
|
||||
parameters.put(JRParameter.REPORT_LOCALE, locale);
|
||||
}
|
||||
|
||||
protected void applyTimeZone(ActionInvocation invocation, Map<String, Object> parameters) {
|
||||
if (timeZone != null) {
|
||||
timeZone = conditionalParse(timeZone, invocation);
|
||||
LOG.debug("Puts timezone in jasper report parameter: {}", timeZone);
|
||||
final TimeZone tz = TimeZone.getTimeZone(timeZone);
|
||||
if (tz != null) {
|
||||
parameters.put(JRParameter.REPORT_TIME_ZONE, tz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void applyCustomParameters(ValueStack stack, Map<String, Object> parameters) {
|
||||
boolean evaluated = parsedReportParameters != null && !parsedReportParameters.equals(reportParameters);
|
||||
boolean reevaluate = !evaluated || isAcceptableExpression(parsedReportParameters);
|
||||
Map<String, Object> reportParams = reevaluate ? (Map<String, Object>) stack.findValue(parsedReportParameters) : null;
|
||||
if (reportParams != null) {
|
||||
LOG.debug("Found report parameters: {}", reportParams);
|
||||
parameters.putAll(reportParams);
|
||||
}
|
||||
}
|
||||
|
||||
protected void exportReport(ActionInvocation invocation, JasperPrint jasperPrint, JasperReport7ExporterProvider<?> exporterProvider) throws StrutsException {
|
||||
HttpServletResponse response = prepapreHttpServletResponse(invocation);
|
||||
try {
|
||||
Exporter<?, ?, ?, ?> exporter = exporterProvider.createExporter(invocation, jasperPrint);
|
||||
|
||||
LOG.debug("Exporting report: {} as: {} and flushing response stream", jasperPrint.getName(), format);
|
||||
exporter.exportReport();
|
||||
response.getOutputStream().flush();
|
||||
} catch (Exception e) {
|
||||
throw new StrutsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private HttpServletResponse prepapreHttpServletResponse(ActionInvocation invocation) {
|
||||
HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
|
||||
|
||||
if (contentDisposition != null || documentName != null) {
|
||||
final StringBuilder tmp = new StringBuilder();
|
||||
tmp.append((contentDisposition == null) ? "inline" : contentDisposition);
|
||||
|
||||
if (documentName != null) {
|
||||
tmp.append("; filename=");
|
||||
tmp.append(documentName);
|
||||
tmp.append(".");
|
||||
tmp.append(format);
|
||||
}
|
||||
|
||||
response.setHeader("Content-disposition", tmp.toString());
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up result properties, parsing etc.
|
||||
*
|
||||
* @param invocation Current invocation.
|
||||
*/
|
||||
private void initializeProperties(ActionInvocation invocation) {
|
||||
if (dataSource == null && connection == null) {
|
||||
String message = "No dataSource specified...";
|
||||
LOG.error(message);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
if (dataSource != null) {
|
||||
parsedDataSource = conditionalParse(dataSource, invocation);
|
||||
}
|
||||
|
||||
format = conditionalParse(format, invocation);
|
||||
if (StringUtils.isEmpty(format)) {
|
||||
format = FORMAT_PDF;
|
||||
}
|
||||
|
||||
if (contentDisposition != null) {
|
||||
contentDisposition = conditionalParse(contentDisposition, invocation);
|
||||
}
|
||||
|
||||
if (documentName != null) {
|
||||
documentName = conditionalParse(documentName, invocation);
|
||||
}
|
||||
|
||||
parsedReportParameters = conditionalParse(reportParameters, invocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if expression doesn't contain vulnerable code
|
||||
*
|
||||
* @param expression of result
|
||||
* @return true|false
|
||||
* @since 6.0.0
|
||||
*/
|
||||
protected boolean isAcceptableExpression(String expression) {
|
||||
NotExcludedAcceptedPatternsChecker.IsAllowed isAllowed = notExcludedAcceptedPatterns.isAllowed(expression);
|
||||
if (isAllowed.isAllowed()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG.warn("Expression [{}] isn't allowed by pattern [{}]! See Accepted / Excluded patterns at\n" +
|
||||
"https://struts.apache.org/security/", expression, isAllowed.getAllowedPattern());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setDataSource(String dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
public void setFormat(String format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public void setDocumentName(String documentName) {
|
||||
this.documentName = documentName;
|
||||
}
|
||||
|
||||
public void setContentDisposition(String contentDisposition) {
|
||||
this.contentDisposition = contentDisposition;
|
||||
}
|
||||
|
||||
public void setTimeZone(final String timeZone) {
|
||||
this.timeZone = timeZone;
|
||||
}
|
||||
|
||||
public void setWrapField(boolean wrapField) {
|
||||
this.wrapField = wrapField;
|
||||
}
|
||||
|
||||
public void setReportParameters(String reportParameters) {
|
||||
this.reportParameters = reportParameters;
|
||||
}
|
||||
|
||||
public void setConnection(String connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7;
|
||||
|
||||
import net.sf.jasperreports.engine.JRException;
|
||||
import net.sf.jasperreports.engine.JRField;
|
||||
import net.sf.jasperreports.engine.JRRewindableDataSource;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.util.MakeIterator;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Ported to Struts.
|
||||
*/
|
||||
public class ValueStackDataSource implements JRRewindableDataSource {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(ValueStackDataSource.class);
|
||||
|
||||
private final ValueStack valueStack;
|
||||
private final String dataSource;
|
||||
private final boolean wrapField;
|
||||
|
||||
private Iterator<?> iterator;
|
||||
|
||||
private boolean firstTimeThrough = true;
|
||||
|
||||
/**
|
||||
* Create a value stack data source on the given iterable property
|
||||
*
|
||||
* @param valueStack The value stack to base the data source on
|
||||
* @param dataSourceParam The property to iterate over for the report
|
||||
*/
|
||||
public ValueStackDataSource(ValueStack valueStack, String dataSourceParam, boolean wrapField) {
|
||||
this.valueStack = valueStack;
|
||||
this.dataSource = dataSourceParam;
|
||||
this.wrapField = wrapField;
|
||||
|
||||
Object dataSourceValue = valueStack.findValue(dataSource);
|
||||
|
||||
if (dataSourceValue != null) {
|
||||
if (MakeIterator.isIterable(dataSourceValue)) {
|
||||
iterator = MakeIterator.convert(dataSourceValue);
|
||||
} else {
|
||||
Object[] array = new Object[1];
|
||||
array[0] = dataSourceValue;
|
||||
iterator = MakeIterator.convert(array);
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Data source value for data source: {} was null", dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of a given field
|
||||
*
|
||||
* @param field The field to get the value for. The expression language to get the value
|
||||
* of the field is either taken from the description property or from the name of the field
|
||||
* if the description is <code>null</code>.
|
||||
* @return an <code>Object</code> containing the field value or a new
|
||||
* <code>ValueStackDataSource</code> object if the field value evaluates to
|
||||
* an object that can be iterated over.
|
||||
*/
|
||||
public Object getFieldValue(JRField field) {
|
||||
String expression = field.getName();
|
||||
|
||||
Object value = valueStack.findValue(expression);
|
||||
LOG.debug("Field [{}] = [{}]", field.getName(), value);
|
||||
|
||||
if (!wrapField && MakeIterator.isIterable(value) && field.getValueClass().isInstance(value)) {
|
||||
return value;
|
||||
} else if (MakeIterator.isIterable(value)) {
|
||||
// wrap value with ValueStackDataSource if not already wrapped
|
||||
return new ValueStackDataSource(this.valueStack, expression, wrapField);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move to the first item.
|
||||
*/
|
||||
public void moveFirst() {
|
||||
Object dataSourceValue = valueStack.findValue(dataSource);
|
||||
if (dataSourceValue != null) {
|
||||
if (MakeIterator.isIterable(dataSourceValue)) {
|
||||
iterator = MakeIterator.convert(dataSourceValue);
|
||||
} else {
|
||||
Object[] array = new Object[1];
|
||||
array[0] = dataSourceValue;
|
||||
iterator = MakeIterator.convert(array);
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Data source value for data source [{}] was null", dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there any more data
|
||||
*
|
||||
* @return <code>true</code> if there are more elements to iterate over and
|
||||
* <code>false</code> otherwise
|
||||
* @throws JRException if there is a problem determining whether there
|
||||
* is more data
|
||||
*/
|
||||
public boolean next() throws JRException {
|
||||
if (firstTimeThrough) {
|
||||
firstTimeThrough = false;
|
||||
} else {
|
||||
valueStack.pop();
|
||||
}
|
||||
|
||||
if ((iterator != null) && (iterator.hasNext())) {
|
||||
valueStack.push(iterator.next());
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Pushed next value: {}", valueStack.findValue("."));
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
LOG.debug("No more values");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7;
|
||||
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* Ported to Struts:
|
||||
*/
|
||||
public class ValueStackShadowMap extends HashMap<String, Object> {
|
||||
|
||||
/**
|
||||
* valueStack reference
|
||||
*/
|
||||
transient ValueStack valueStack;
|
||||
|
||||
/**
|
||||
* Constructs an instance of ValueStackShadowMap.
|
||||
*
|
||||
* @param valueStack - the underlying valuestack
|
||||
*/
|
||||
public ValueStackShadowMap(ValueStack valueStack) {
|
||||
this.valueStack = valueStack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of containsKey(), overriding HashMap implementation.
|
||||
*
|
||||
* @param key - The key to check in HashMap and if not found to check on valueStack.
|
||||
* @return <tt>true</tt>, if contains key, <tt>false</tt> otherwise.
|
||||
* @see java.util.HashMap#containsKey
|
||||
*/
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
boolean hasKey = super.containsKey(key);
|
||||
|
||||
if (!hasKey && key != null && valueStack.findValue(key.toString()) != null) {
|
||||
hasKey = true;
|
||||
}
|
||||
|
||||
return hasKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of get(), overriding HashMap implementation.
|
||||
*
|
||||
* @param key - The key to get in HashMap and if not found there from the valueStack.
|
||||
* @return value - The object from HashMap or if null, from the valueStack.
|
||||
* @see java.util.HashMap#get
|
||||
*/
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
Object value = super.get(key);
|
||||
|
||||
if (key != null && value == null) {
|
||||
value = valueStack.findValue(key.toString());
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7.export;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.export.JRCsvExporter;
|
||||
import net.sf.jasperreports.export.SimpleCsvExporterConfiguration;
|
||||
import net.sf.jasperreports.export.SimpleExporterInput;
|
||||
import net.sf.jasperreports.export.SimpleWriterExporterOutput;
|
||||
import net.sf.jasperreports.export.WriterExporterOutput;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.views.jasperreports7.JasperReport7Aware;
|
||||
import org.apache.struts2.views.jasperreports7.JasperReport7Constants;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class JasperReport7CsvExporterProvider implements JasperReport7ExporterProvider<JRCsvExporter> {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(JasperReport7CsvExporterProvider.class);
|
||||
|
||||
/**
|
||||
* A delimiter used when generating CSV report. By default, "," is used.
|
||||
*/
|
||||
private String defaultDelimiter = ",";
|
||||
|
||||
@Inject
|
||||
public JasperReport7CsvExporterProvider(
|
||||
@Inject(value = JasperReport7Constants.STRUTS_JASPER_REPORT_CSV_DELIMITER, required = false)
|
||||
String defaultDelimiter
|
||||
) {
|
||||
if (StringUtils.isNoneEmpty(defaultDelimiter)) {
|
||||
LOG.debug("Using custom default delimiter [{}]", defaultDelimiter);
|
||||
this.defaultDelimiter = defaultDelimiter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JRCsvExporter createExporter(ActionInvocation invocation, JasperPrint jasperPrint) throws StrutsException {
|
||||
LOG.debug("Creating: {} exporter", this.getClass().getSimpleName());
|
||||
|
||||
HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
|
||||
response.setContentType("text/csv");
|
||||
|
||||
JRCsvExporter exporter = new JRCsvExporter();
|
||||
|
||||
String reportDelimiter = null;
|
||||
if (invocation.getAction() instanceof JasperReport7Aware action) {
|
||||
reportDelimiter = action.getCsvDelimiter(invocation);
|
||||
}
|
||||
if (StringUtils.isEmpty(reportDelimiter)) {
|
||||
reportDelimiter = defaultDelimiter;
|
||||
}
|
||||
LOG.debug("Using delimiter: [{}]", reportDelimiter);
|
||||
|
||||
SimpleCsvExporterConfiguration config = new SimpleCsvExporterConfiguration();
|
||||
config.setFieldDelimiter(reportDelimiter);
|
||||
config.setRecordDelimiter(reportDelimiter);
|
||||
exporter.setConfiguration(config);
|
||||
|
||||
SimpleExporterInput input = new SimpleExporterInput(jasperPrint);
|
||||
exporter.setExporterInput(input);
|
||||
|
||||
try (OutputStream responseStream = response.getOutputStream()) {
|
||||
WriterExporterOutput exporterOutput = new SimpleWriterExporterOutput(responseStream);
|
||||
exporter.setExporterOutput(exporterOutput);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error writing CSV report output using: {}", JasperReport7CsvExporterProvider.class.getName(), e);
|
||||
throw new StrutsException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return exporter;
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7.export;
|
||||
|
||||
import net.sf.jasperreports.engine.JRAbstractExporter;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.export.JRExporterContext;
|
||||
import net.sf.jasperreports.export.ExporterConfiguration;
|
||||
import net.sf.jasperreports.export.ExporterOutput;
|
||||
import net.sf.jasperreports.export.ReportExportConfiguration;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.StrutsException;
|
||||
|
||||
public interface JasperReport7ExporterProvider<T extends JRAbstractExporter<? extends ReportExportConfiguration, ? extends ExporterConfiguration, ? extends ExporterOutput, ? extends JRExporterContext>> {
|
||||
|
||||
T createExporter(ActionInvocation invocation, JasperPrint jasperPrint) throws StrutsException;
|
||||
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7.export;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.export.HtmlExporter;
|
||||
import net.sf.jasperreports.engine.export.HtmlResourceHandler;
|
||||
import net.sf.jasperreports.export.SimpleExporterInput;
|
||||
import net.sf.jasperreports.export.SimpleHtmlExporterOutput;
|
||||
import net.sf.jasperreports.web.util.WebHtmlResourceHandler;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.inject.Inject;
|
||||
import org.apache.struts2.views.jasperreports7.JasperReport7Constants;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class JasperReport7HtmlExporterProvider implements JasperReport7ExporterProvider<HtmlExporter> {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(JasperReport7HtmlExporterProvider.class);
|
||||
|
||||
/**
|
||||
* Name of the url that, when prefixed with the context page, can return report images
|
||||
*/
|
||||
private String imageServletUrl = "/images/";
|
||||
|
||||
@Inject
|
||||
public JasperReport7HtmlExporterProvider(
|
||||
@Inject(value = JasperReport7Constants.STRUTS_JASPER_REPORT_HTML_IMAGE_SERVLET_URL, required = false)
|
||||
String imageServletUrl
|
||||
) {
|
||||
if (StringUtils.isNoneEmpty(imageServletUrl)) {
|
||||
LOG.debug("Using custom image servlet url: {}", imageServletUrl);
|
||||
this.imageServletUrl = imageServletUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlExporter createExporter(ActionInvocation invocation, JasperPrint jasperPrint) throws StrutsException {
|
||||
LOG.debug("Creating: {} exporter with image servlet url: {}", this.getClass().getSimpleName(), imageServletUrl);
|
||||
|
||||
HttpServletRequest request = invocation.getInvocationContext().getServletRequest();
|
||||
HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
|
||||
|
||||
response.setContentType("text/html");
|
||||
HtmlExporter exporter = new HtmlExporter();
|
||||
|
||||
SimpleExporterInput input = new SimpleExporterInput(jasperPrint);
|
||||
exporter.setExporterInput(input);
|
||||
|
||||
try (OutputStream responseStream = response.getOutputStream()) {
|
||||
SimpleHtmlExporterOutput exporterOutput = new SimpleHtmlExporterOutput(responseStream);
|
||||
HtmlResourceHandler imageHandler = new WebHtmlResourceHandler(request.getContextPath() + imageServletUrl + "%s");
|
||||
exporterOutput.setImageHandler(imageHandler);
|
||||
exporter.setExporterOutput(exporterOutput);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error writing HTML report output using: {}", JasperReport7HtmlExporterProvider.class.getName(), e);
|
||||
throw new StrutsException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return exporter;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7.export;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.export.OutputStreamExporterOutput;
|
||||
import net.sf.jasperreports.export.SimpleExporterInput;
|
||||
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
|
||||
import net.sf.jasperreports.pdf.JRPdfExporter;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.StrutsException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class JasperReport7PdfExporterProvider implements JasperReport7ExporterProvider<JRPdfExporter> {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(JasperReport7PdfExporterProvider.class);
|
||||
|
||||
@Override
|
||||
public JRPdfExporter createExporter(ActionInvocation invocation, JasperPrint jasperPrint) throws StrutsException {
|
||||
LOG.debug("Creating: {} exporter", this.getClass().getSimpleName());
|
||||
|
||||
HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
|
||||
response.setContentType("application/pdf");
|
||||
|
||||
JRPdfExporter exporter = new JRPdfExporter();
|
||||
|
||||
SimpleExporterInput input = new SimpleExporterInput(jasperPrint);
|
||||
exporter.setExporterInput(input);
|
||||
|
||||
try (OutputStream responseStream = response.getOutputStream()) {
|
||||
OutputStreamExporterOutput exporterOutput = new SimpleOutputStreamExporterOutput(responseStream);
|
||||
exporter.setExporterOutput(exporterOutput);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error writing PDF report output using: {}", JasperReport7PdfExporterProvider.class.getName(), e);
|
||||
throw new StrutsException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return exporter;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7.export;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.export.JRRtfExporter;
|
||||
import net.sf.jasperreports.export.SimpleExporterInput;
|
||||
import net.sf.jasperreports.export.SimpleWriterExporterOutput;
|
||||
import net.sf.jasperreports.export.WriterExporterOutput;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.StrutsException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class JasperReport7RtfExporterProvider implements JasperReport7ExporterProvider<JRRtfExporter> {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(JasperReport7RtfExporterProvider.class);
|
||||
|
||||
@Override
|
||||
public JRRtfExporter createExporter(ActionInvocation invocation, JasperPrint jasperPrint) throws StrutsException {
|
||||
LOG.debug("Creating: {} exporter", this.getClass().getSimpleName());
|
||||
|
||||
HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
|
||||
response.setContentType("application/rtf");
|
||||
|
||||
JRRtfExporter exporter = new JRRtfExporter();
|
||||
|
||||
SimpleExporterInput input = new SimpleExporterInput(jasperPrint);
|
||||
exporter.setExporterInput(input);
|
||||
|
||||
try (OutputStream responseStream = response.getOutputStream()) {
|
||||
WriterExporterOutput exporterOutput = new SimpleWriterExporterOutput(responseStream);
|
||||
exporter.setExporterOutput(exporterOutput);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error writing RTF report output using: {}", JasperReport7RtfExporterProvider.class.getName(), e);
|
||||
throw new StrutsException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return exporter;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7.export;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
|
||||
import net.sf.jasperreports.export.OutputStreamExporterOutput;
|
||||
import net.sf.jasperreports.export.SimpleExporterInput;
|
||||
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.StrutsException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class JasperReport7XlsxExporterProvider implements JasperReport7ExporterProvider<JRXlsxExporter> {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(JasperReport7XlsxExporterProvider.class);
|
||||
|
||||
@Override
|
||||
public JRXlsxExporter createExporter(ActionInvocation invocation, JasperPrint jasperPrint) throws StrutsException {
|
||||
LOG.debug("Creating: {} exporter", this.getClass().getSimpleName());
|
||||
|
||||
HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
|
||||
JRXlsxExporter exporter = new JRXlsxExporter();
|
||||
|
||||
SimpleExporterInput input = new SimpleExporterInput(jasperPrint);
|
||||
exporter.setExporterInput(input);
|
||||
|
||||
try (OutputStream responseStream = response.getOutputStream()) {
|
||||
OutputStreamExporterOutput exporterOutput = new SimpleOutputStreamExporterOutput(responseStream);
|
||||
exporter.setExporterOutput(exporterOutput);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error writing XLSX report output using: {}", JasperReport7XlsxExporterProvider.class.getName(), e);
|
||||
throw new StrutsException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return exporter;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7.export;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.export.JRXmlExporter;
|
||||
import net.sf.jasperreports.export.SimpleExporterInput;
|
||||
import net.sf.jasperreports.export.SimpleXmlExporterOutput;
|
||||
import net.sf.jasperreports.export.XmlExporterOutput;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ActionInvocation;
|
||||
import org.apache.struts2.StrutsException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class JasperReport7XmlExporterProvider implements JasperReport7ExporterProvider<JRXmlExporter> {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(JasperReport7XmlExporterProvider.class);
|
||||
|
||||
@Override
|
||||
public JRXmlExporter createExporter(ActionInvocation invocation, JasperPrint jasperPrint) throws StrutsException {
|
||||
LOG.debug("Creating: {} exporter", this.getClass().getSimpleName());
|
||||
|
||||
HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
|
||||
response.setContentType("text/xml");
|
||||
|
||||
JRXmlExporter exporter = new JRXmlExporter();
|
||||
|
||||
SimpleExporterInput input = new SimpleExporterInput(jasperPrint);
|
||||
exporter.setExporterInput(input);
|
||||
|
||||
try (OutputStream responseOutput = response.getOutputStream()) {
|
||||
XmlExporterOutput exporterOutput = new SimpleXmlExporterOutput(responseOutput);
|
||||
exporter.setExporterOutput(exporterOutput);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error writing report XML output using: {}", JRXmlExporter.class.getName(), e);
|
||||
throw new StrutsException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return exporter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,5 @@
|
||||
Apache Struts
|
||||
Copyright 2000-2024 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
|
||||
"https://struts.apache.org/dtds/struts-6.0.dtd">
|
||||
|
||||
<struts>
|
||||
<constant name="struts.jasperReport7.csv.defaultDelimiter" value=","/>
|
||||
|
||||
<bean name="pdf"
|
||||
class="org.apache.struts2.views.jasperreports7.export.JasperReport7PdfExporterProvider"
|
||||
type="org.apache.struts2.views.jasperreports7.export.JasperReport7ExporterProvider"/>
|
||||
|
||||
<bean name="csv"
|
||||
class="org.apache.struts2.views.jasperreports7.export.JasperReport7CsvExporterProvider"
|
||||
type="org.apache.struts2.views.jasperreports7.export.JasperReport7ExporterProvider"/>
|
||||
|
||||
<bean name="html"
|
||||
class="org.apache.struts2.views.jasperreports7.export.JasperReport7HtmlExporterProvider"
|
||||
type="org.apache.struts2.views.jasperreports7.export.JasperReport7ExporterProvider"/>
|
||||
|
||||
<bean name="xlsx"
|
||||
class="org.apache.struts2.views.jasperreports7.export.JasperReport7XlsxExporterProvider"
|
||||
type="org.apache.struts2.views.jasperreports7.export.JasperReport7ExporterProvider"/>
|
||||
|
||||
<bean name="xml"
|
||||
class="org.apache.struts2.views.jasperreports7.export.JasperReport7XmlExporterProvider"
|
||||
type="org.apache.struts2.views.jasperreports7.export.JasperReport7ExporterProvider"/>
|
||||
|
||||
<bean name="rtf"
|
||||
class="org.apache.struts2.views.jasperreports7.export.JasperReport7RtfExporterProvider"
|
||||
type="org.apache.struts2.views.jasperreports7.export.JasperReport7ExporterProvider"/>
|
||||
|
||||
<package name="jasperreports7-default" extends="struts-default">
|
||||
<result-types>
|
||||
<result-type name="jasperReport7" class="org.apache.struts2.views.jasperreports7.JasperReport7Result"/>
|
||||
</result-types>
|
||||
</package>
|
||||
|
||||
</struts>
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<project name="Apache Struts">
|
||||
<skin>
|
||||
<groupId>org.apache.maven.skins</groupId>
|
||||
<artifactId>maven-fluido-skin</artifactId>
|
||||
<version>${fluido-skin.version}</version>
|
||||
</skin>
|
||||
<bannerLeft>
|
||||
<name>Apache Software Foundation</name>
|
||||
<src>http://www.apache.org/images/asf-logo.gif</src>
|
||||
<href>http://www.apache.org/</href>
|
||||
</bannerLeft>
|
||||
<bannerRight>
|
||||
<name>Apache Struts</name>
|
||||
<src>http://struts.apache.org/img/struts-logo.svg</src>
|
||||
<href>http://struts.apache.org/</href>
|
||||
</bannerRight>
|
||||
<publishDate position="left"/>
|
||||
<version position="right"/>
|
||||
<body>
|
||||
<links>
|
||||
<item name="Apache" href="http://www.apache.org/"/>
|
||||
<item name="Struts" href="http://struts.apache.org/"/>
|
||||
</links>
|
||||
|
||||
<menu ref="parent"/>
|
||||
<menu ref="reports"/>
|
||||
|
||||
<footer>
|
||||
<![CDATA[<div class="row span12">
|
||||
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts project
|
||||
logos are trademarks of The Apache Software Foundation.
|
||||
</div>]]>
|
||||
</footer>
|
||||
</body>
|
||||
</project>
|
||||
+368
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.views.jasperreports7;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import net.sf.jasperreports.engine.JasperCompileManager;
|
||||
import org.apache.struts2.ActionContext;
|
||||
import org.apache.struts2.junit.StrutsTestCase;
|
||||
import org.apache.struts2.mock.MockActionInvocation;
|
||||
import org.apache.struts2.security.NotExcludedAcceptedPatternsChecker;
|
||||
import org.apache.struts2.util.ClassLoaderUtil;
|
||||
import org.apache.struts2.util.ValueStack;
|
||||
|
||||
import java.net.URL;
|
||||
import java.sql.Connection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expectLastCall;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
|
||||
public class JasperReport7ResultTest extends StrutsTestCase {
|
||||
|
||||
private MockActionInvocation invocation;
|
||||
private ValueStack stack;
|
||||
private JasperReport7Result result;
|
||||
|
||||
public void testConnClose() throws Exception {
|
||||
// given
|
||||
Connection connection = createMock(Connection.class);
|
||||
final Boolean[] closed = {Boolean.FALSE};
|
||||
connection.close();
|
||||
expectLastCall().andAnswer(() -> {
|
||||
closed[0] = true;
|
||||
return null;
|
||||
});
|
||||
replay(connection);
|
||||
|
||||
stack.push(connection);
|
||||
result.setConnection("top");
|
||||
assertFalse(closed[0]);
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
verify(connection);
|
||||
assertTrue(closed[0]);
|
||||
}
|
||||
|
||||
public void testDataSourceNotAccepted() throws Exception {
|
||||
// given
|
||||
stack.push(new Object() {
|
||||
public String getDatasourceName() {
|
||||
return "getDatasource()";
|
||||
}
|
||||
|
||||
public List<Map<String, String>> getDatasource() {
|
||||
return JR_MAP_ARRAY_DATA_SOURCE;
|
||||
}
|
||||
});
|
||||
result.setDataSource("${datasourceName}");
|
||||
|
||||
try {
|
||||
result.execute(this.invocation);
|
||||
} catch (ServletException e) {
|
||||
assertEquals("Unaccepted dataSource expression [getDatasource()]", e.getMessage());
|
||||
}
|
||||
|
||||
// verify that above test has really effect
|
||||
result.setNotExcludedAcceptedPatterns(NO_EXCLUSION_ACCEPT_ALL_PATTERNS_CHECKER);
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("text/xml");
|
||||
assertThat(response.getContentAsString()).contains("Hello Foo Bar!");
|
||||
}
|
||||
|
||||
public void testDataSourceAccepted() throws Exception {
|
||||
// given
|
||||
stack.push(new Object() {
|
||||
public String getDatasourceName() {
|
||||
return "datasource";
|
||||
}
|
||||
|
||||
public List<Map<String, String>> getDatasource() {
|
||||
return JR_MAP_ARRAY_DATA_SOURCE;
|
||||
}
|
||||
});
|
||||
result.setDataSource("${datasourceName}");
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("text/xml");
|
||||
assertTrue(response.getContentAsString().contains("Hello Foo Bar!"));
|
||||
}
|
||||
|
||||
public void testDataSourceExpressionAccepted() throws Exception {
|
||||
// given
|
||||
result.setDataSource("{#{'firstName':'Qux', 'lastName':'Quux'}}");
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("text/xml");
|
||||
assertThat(response.getContentAsString()).contains("Hello Qux Quux!");
|
||||
}
|
||||
|
||||
public void testReportParametersNotAccepted() throws Exception {
|
||||
// given
|
||||
result.setDataSource("{#{'firstName':'ignore', 'lastName':'ignore'}}");
|
||||
|
||||
stack.push(new Object() {
|
||||
public String getReportParametersName() {
|
||||
return "getReportParameters()";
|
||||
}
|
||||
|
||||
public Map<String, String> getReportParameters() {
|
||||
return new HashMap<>() {{
|
||||
put("title", "Baz");
|
||||
}};
|
||||
}
|
||||
});
|
||||
|
||||
result.setReportParameters("${reportParametersName}");
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
assertTrue(response.getContentAsString().contains("null Report"));
|
||||
|
||||
// verify that above test has really effect
|
||||
response.setCommitted(false);
|
||||
response.reset();
|
||||
result.setNotExcludedAcceptedPatterns(NO_EXCLUSION_ACCEPT_ALL_PATTERNS_CHECKER);
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("text/xml");
|
||||
assertTrue(response.getContentAsString().contains("Baz Report"));
|
||||
}
|
||||
|
||||
public void testReportParametersAccepted() throws Exception {
|
||||
// given
|
||||
result.setDataSource("{#{'firstName':'ignore', 'lastName':'ignore'}}");
|
||||
|
||||
stack.push(new Object() {
|
||||
public String getReportParametersName() {
|
||||
return "reportParameters";
|
||||
}
|
||||
|
||||
public Map<String, String> getReportParameters() {
|
||||
return new HashMap<>() {{
|
||||
put("title", "Baz");
|
||||
}};
|
||||
}
|
||||
});
|
||||
|
||||
result.setReportParameters("${reportParametersName}");
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("text/xml");
|
||||
assertThat(response.getContentAsString()).contains("Baz Report");
|
||||
}
|
||||
|
||||
public void testExportToXml() throws Exception {
|
||||
// given
|
||||
result.setDataSource("{#{'firstName':'ignore', 'lastName':'ignore'}}");
|
||||
result.setReportParameters("#{'title':'Qux'}");
|
||||
result.setFormat(JasperReport7Constants.FORMAT_XML);
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("text/xml");
|
||||
assertThat(response.getContentAsString()).contains("Qux Report");
|
||||
}
|
||||
|
||||
public void testExportToCsv() throws Exception {
|
||||
// given
|
||||
result.setDataSource("{#{'firstName':'ignore', 'lastName':'ignore'}}");
|
||||
result.setReportParameters("#{'title':'Qux'}");
|
||||
result.setFormat(JasperReport7Constants.FORMAT_CSV);
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("text/csv");
|
||||
assertThat(response.getContentAsString()).contains("Qux Report");
|
||||
}
|
||||
|
||||
public void testExportToRtf() throws Exception {
|
||||
// given
|
||||
result.setDataSource("{#{'firstName':'ignore', 'lastName':'ignore'}}");
|
||||
result.setReportParameters("#{'title':'Qux'}");
|
||||
result.setFormat(JasperReport7Constants.FORMAT_RTF);
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("application/rtf");
|
||||
assertThat(response.getContentAsString()).contains("Qux Report");
|
||||
}
|
||||
|
||||
public void testExportToPdf() throws Exception {
|
||||
// given
|
||||
result.setDataSource("{#{'firstName':'ignore', 'lastName':'ignore'}}");
|
||||
result.setReportParameters("#{'title':'Qux'}");
|
||||
result.setFormat(JasperReport7Constants.FORMAT_PDF);
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("application/pdf");
|
||||
assertThat(response.getContentAsByteArray()).hasSizeGreaterThan(0);
|
||||
}
|
||||
|
||||
public void testExportToHtml() throws Exception {
|
||||
// given
|
||||
result.setDataSource("{#{'firstName':'ignore', 'lastName':'ignore'}}");
|
||||
result.setReportParameters("#{'title':'Qux'}");
|
||||
result.setFormat(JasperReport7Constants.FORMAT_HTML);
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("text/html");
|
||||
assertThat(response.getContentAsString()).contains("Qux Report");
|
||||
}
|
||||
|
||||
public void testExportToXlsx() throws Exception {
|
||||
// given
|
||||
result.setDataSource("{#{'firstName':'ignore', 'lastName':'ignore'}}");
|
||||
result.setReportParameters("#{'title':'Qux'}");
|
||||
result.setFormat(JasperReport7Constants.FORMAT_XLSX);
|
||||
|
||||
// when
|
||||
result.execute(this.invocation);
|
||||
|
||||
// then
|
||||
assertThat(response.getContentType()).isEqualTo("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
assertThat(response.getContentAsByteArray()).hasSizeGreaterThan(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
this.request.setRequestURI("http://someuri");
|
||||
ActionContext context = ActionContext.getContext()
|
||||
.withServletResponse(this.response)
|
||||
.withServletRequest(this.request)
|
||||
.withServletContext(this.servletContext);
|
||||
this.stack = context.getValueStack();
|
||||
|
||||
this.invocation = new MockActionInvocation();
|
||||
this.invocation.setInvocationContext(context);
|
||||
this.invocation.setStack(this.stack);
|
||||
|
||||
result = new JasperReport7Result();
|
||||
container.inject(result);
|
||||
URL url = ClassLoaderUtil.getResource("org/apache/struts2/views/jasperreports7/simple.jrxml", this.getClass());
|
||||
JasperCompileManager.compileReportToFile(url.getFile(), url.getFile() + ".jasper");
|
||||
result.setLocation("org/apache/struts2/views/jasperreports7/simple.jrxml.jasper");
|
||||
result.setFormat(JasperReport7Constants.FORMAT_XML);
|
||||
}
|
||||
|
||||
private static final List<Map<String, String>> JR_MAP_ARRAY_DATA_SOURCE = Stream.<Map<String, String>>of(
|
||||
new HashMap<>() {{
|
||||
put("firstName", "Foo");
|
||||
put("lastName", "Bar");
|
||||
}}
|
||||
).toList();
|
||||
|
||||
private static final NotExcludedAcceptedPatternsChecker NO_EXCLUSION_ACCEPT_ALL_PATTERNS_CHECKER
|
||||
= new NotExcludedAcceptedPatternsChecker() {
|
||||
@Override
|
||||
public IsAllowed isAllowed(String value) {
|
||||
return IsAllowed.yes("*");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsAccepted isAccepted(String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAcceptedPatterns(String commaDelimitedPatterns) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAcceptedPatterns(String[] patterns) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAcceptedPatterns(Set<String> patterns) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Pattern> getAcceptedPatterns() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsExcluded isExcluded(String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExcludedPatterns(String commaDelimitedPatterns) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExcludedPatterns(String[] patterns) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExcludedPatterns(Set<String> patterns) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Pattern> getExcludedPatterns() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<Configuration>
|
||||
<Appenders>
|
||||
<Console name="STDOUT" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="[%-5p] %C{2} (%F:%L) - %m%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info">
|
||||
<AppenderRef ref="STDOUT"/>
|
||||
</Root>
|
||||
<Logger name="org.apache.struts2.views.jasperreports7" level="info"/>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<jasperReport name="SimpleReport" language="java" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802"
|
||||
uuid="3de5a1ab-15fd-4dec-bc88-dc18453bf715">
|
||||
<parameter name="title"/>
|
||||
<field name="firstName"/>
|
||||
<field name="lastName"/>
|
||||
|
||||
<title height="40">
|
||||
<element kind="textField" x="0" y="10" width="515" height="30" fontSize="22.0" hTextAlign="Center"
|
||||
uuid="26fc2f4f-de0f-411a-b386-e67caf96f441">
|
||||
<expression><![CDATA[$P{title}]]> + " Report"</expression>
|
||||
</element>
|
||||
</title>
|
||||
<detail>
|
||||
<band height="16">
|
||||
<element kind="textField" x="0" y="0" width="100" height="16"
|
||||
uuid="ef0654b5-f925-42ed-a611-bc5b3db61c43">
|
||||
<expression>"Hello " + <![CDATA[$F{firstName}]]> + " " + <![CDATA[$F{lastName}]]> + "!"</expression>
|
||||
</element>
|
||||
</band>
|
||||
</detail>
|
||||
</jasperReport>
|
||||
@@ -39,6 +39,7 @@
|
||||
<module>config-browser</module>
|
||||
<module>convention</module>
|
||||
<module>jasperreports</module>
|
||||
<module>jasperreports7</module>
|
||||
<module>javatemplates</module>
|
||||
<module>jfreechart</module>
|
||||
<module>json</module>
|
||||
|
||||
Reference in New Issue
Block a user