⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractjasperreportsview.java

📁 Spring API核心源代码 Spring API核心源代码 Spring API核心源代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	 * Finds the report data to use for rendering the report and then invokes the
	 * <code>renderReport</code> method that should be implemented by the subclass.
	 * @param model the model map, as passed in for view rendering. Must contain
	 * a report data value that can be converted to a <code>JRDataSource</code>,
	 * acccording to the <code>getReportData</code> method.
	 * @see #getReportData
	 */
	protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		if (this.subReports != null) {
			// Expose sub-reports as model attributes.
			model.putAll(this.subReports);

			// Transform any collections etc into JRDataSources for sub reports.
			if (this.subReportDataKeys != null) {
				for (int i = 0; i < this.subReportDataKeys.length; i++) {
					String key = this.subReportDataKeys[i];
					model.put(key, convertReportData(model.get(key)));
				}
			}
		}

		// Expose Spring-managed Locale and MessageSource.
		exposeLocalizationContext(model, request);

		// Fill the report.
		JasperPrint filledReport = fillReport(model);
		postProcessReport(filledReport, model);

		// Prepare response and render report.
		response.reset();
		populateHeaders(response);
		renderReport(filledReport, model, response);
	}

	/**
	 * Expose current Spring-managed Locale and MessageSource to JasperReports i18n
	 * ($R expressions etc). The MessageSource should only be exposed as JasperReports
	 * resource bundle if no such bundle is defined in the report itself.
	 * <p>Default implementation exposes the Spring RequestContext Locale and a
	 * MessageSourceResourceBundle adapter for the Spring ApplicationContext,
	 * analogous to the <code>JstlUtils.exposeLocalizationContext</code> method.
	 * @see org.springframework.web.servlet.support.RequestContextUtils#getLocale
	 * @see org.springframework.context.support.MessageSourceResourceBundle
	 * @see #getApplicationContext()
	 * @see net.sf.jasperreports.engine.JRParameter#REPORT_LOCALE
	 * @see net.sf.jasperreports.engine.JRParameter#REPORT_RESOURCE_BUNDLE
	 * @see org.springframework.web.servlet.support.JstlUtils#exposeLocalizationContext
	 */
	protected void exposeLocalizationContext(Map model, HttpServletRequest request) {
		Locale locale = RequestContextUtils.getLocale(request);
		model.put(JRParameter.REPORT_LOCALE, locale);
		if (this.report.getResourceBundle() == null) {
			ResourceBundle bundle = new MessageSourceResourceBundle(getApplicationContext(), locale);
			model.put(JRParameter.REPORT_RESOURCE_BUNDLE, bundle);
		}
	}

	/**
	 * Create a populated <code>JasperPrint</code> instance from the configured
	 * <code>JasperReport</code> instance.
	 * <p>By default, thois method will use any <code>JRDataSource</code> instance
	 * (or wrappable <code>Object</code>) that can be located using {@link #getReportData}.
	 * If no <code>JRDataSource</code> can be found, this method will use a JDBC
	 * <code>Connection</code> obtained from the configured <code>javax.sql.DataSource</code>
	 * (or a DataSource attribute in the model). If no JDBC DataSource can be found
	 * either, the JasperReports engine will be invoked with plain model Map,
	 * assuming that the model contains parameters that identify the source
	 * for report data (e.g. Hibernate or JPA queries).
	 * @param model the model for this request
	 * @throws IllegalArgumentException if no <code>JRDataSource</code> can be found
	 * and no <code>javax.sql.DataSource</code> is supplied
	 * @throws SQLException if there is an error when populating the report using
	 * the <code>javax.sql.DataSource</code>
	 * @throws JRException if there is an error when populating the report using
	 * a <code>JRDataSource</code>
	 * @return the populated <code>JasperPrint</code> instance
	 * @see #getReportData
	 * @see #setJdbcDataSource
	 */
	protected JasperPrint fillReport(Map model) throws IllegalArgumentException, SQLException, JRException {
		// Determine JRDataSource for main report.
		JRDataSource jrDataSource = getReportData(model);

		if (jrDataSource != null) {
			// Use the JasperReports JRDataSource.
			if (logger.isDebugEnabled()) {
				logger.debug("Filling report with JRDataSource [" + jrDataSource + "].");
			}
			return JasperFillManager.fillReport(this.report, model, jrDataSource);
		}

		else {
			if (this.jdbcDataSource == null) {
				this.jdbcDataSource = (DataSource) CollectionUtils.findValueOfType(model.values(), DataSource.class);
			}

			if (this.jdbcDataSource != null) {
				// Use the JDBC DataSource.
				if (logger.isDebugEnabled()) {
					logger.debug("Filling report with JDBC DataSource [" + this.jdbcDataSource + "].");
				}
				Connection con = this.jdbcDataSource.getConnection();
				try {
					return JasperFillManager.fillReport(this.report, model, con);
				}
				finally {
					try {
						con.close();
					}
					catch (SQLException ex) {
						logger.debug("Could not close JDBC Connection", ex);
					}
				}
			}

			else {
				// Assume that the model contains parameters that identify
				// the source for report data (e.g. Hibernate or JPA queries).
				return JasperFillManager.fillReport(this.report, model);
			}
		}
	}

	/**
	 * Populates the headers in the <code>HttpServletResponse</code> with the
	 * headers supplied by the user.
	 */
	private void populateHeaders(HttpServletResponse response) {
		// Apply the headers to the response.
		for (Enumeration en = this.headers.propertyNames(); en.hasMoreElements();) {
			String key = (String) en.nextElement();
			response.addHeader(key, this.headers.getProperty(key));
		}
	}

	/**
	 * Find an instance of <code>JRDataSource</code> in the given model map or create an
	 * appropriate JRDataSource for passed-in report data.
	 * <p>The default implementation checks for a model object under the
	 * specified "reportDataKey" first, then falls back to looking for a value
	 * of type <code>JRDataSource</code>, <code>java.util.Collection</code>,
	 * object array (in that order).
	 * @param model the model map, as passed in for view rendering
	 * @return the <code>JRDataSource</code> or <code>null</code> if the data source is not found
	 * @see #setReportDataKey
	 * @see #convertReportData
	 * @see #getReportDataTypes
	 */
	protected JRDataSource getReportData(Map model) {
		// Try model attribute with specified name.
		if (this.reportDataKey != null) {
			Object value = model.get(this.reportDataKey);
			return convertReportData(value);
		}

		// Try to find matching attribute, of given prioritized types.
		Object value = CollectionUtils.findValueOfType(model.values(), getReportDataTypes());

		if (value != null) {
			return convertReportData(value);
		}

		return null;
	}

	/**
	 * Convert the given report data value to a <code>JRDataSource</code>.
	 * <p>The default implementation delegates to <code>JasperReportUtils</code> unless
	 * the report data value is an instance of <code>JRDataSourceProvider</code>.
	 * A <code>JRDataSource</code>, <code>JRDataSourceProvider</code>,
	 * <code>java.util.Collection</code> or object array is detected.
	 * <code>JRDataSource</code>s are returned as is, whilst <code>JRDataSourceProvider</code>s
	 * are used to create an instance of <code>JRDataSource</code> which is then returned.
	 * The latter two are converted to <code>JRBeanCollectionDataSource</code> or
	 * <code>JRBeanArrayDataSource</code>, respectively.
	 * @param value the report data value to convert
	 * @return the JRDataSource
	 * @throws IllegalArgumentException if the value could not be converted
	 * @see org.springframework.ui.jasperreports.JasperReportsUtils#convertReportData
	 * @see net.sf.jasperreports.engine.JRDataSource
	 * @see net.sf.jasperreports.engine.JRDataSourceProvider
	 * @see net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
	 * @see net.sf.jasperreports.engine.data.JRBeanArrayDataSource
	 */
	protected JRDataSource convertReportData(Object value) throws IllegalArgumentException {
		if (value instanceof JRDataSourceProvider) {
			try {
				return ((JRDataSourceProvider) value).create(this.report);
			}
			catch (JRException ex) {
				throw new IllegalArgumentException("Supplied JRDataSourceProvider is invalid: " + ex);
			}
		}
		else {
			return JasperReportsUtils.convertReportData(value);
		}
	}

	/**
	 * Return the value types that can be converted to a <code>JRDataSource</code>,
	 * in prioritized order. Should only return types that the
	 * {@link #convertReportData} method is actually able to convert.
	 * <p>Default value types are: <code>JRDataSource</code>,
	 * <code>JRDataSourceProvider</code> <code>java.util.Collection</code>
	 * and <code>Object</code> array.
	 * @return the value types in prioritized order
	 */
	protected Class[] getReportDataTypes() {
		return new Class[] {JRDataSource.class, JRDataSourceProvider.class, Collection.class, Object[].class};
	}

	/**
	 * Allows sub-classes to get access to the <code>JasperReport</code> instance
	 * loaded by Spring.
	 * @return an instance of <code>JasperReport</code>
	 */
	protected JasperReport getReport() {
		return this.report;
	}


	/**
	 * Template method to be overridden for custom post-processing of the
	 * populated report. Invoked after filling but before rendering.
	 * <p>The default implementation is empty.
	 * @param populatedReport the populated <code>JasperPrint</code>
	 * @param model the map containing report parameters
	 * @throws Exception if post-processing failed
	 */
	protected void postProcessReport(JasperPrint populatedReport, Map model) throws Exception {
	}

	/**
	 * Subclasses should implement this method to perform the actual rendering process.
	 * <p>Note that the content type has not been set yet: Implementors should build
	 * a content type String and set it via <code>response.setContentType</code>.
	 * If necessary, this can include a charset clause for a specific encoding.
	 * The latter will only be necessary for textual output onto a Writer, and only
	 * in case of the encoding being specified in the JasperReports exporter parameters.
	 * <p><b>WARNING:</b> Implementors should not use <code>response.setCharacterEncoding</code>
	 * unless they are willing to depend on Servlet API 2.4 or higher. Prefer a
	 * concatenated content type String with a charset clause instead.
	 * @param populatedReport the populated <code>JasperPrint</code> to render
	 * @param model the map containing report parameters
	 * @param response the HTTP response the report should be rendered to
	 * @throws Exception if rendering failed
	 * @see #getContentType()
	 * @see javax.servlet.ServletResponse#setContentType
	 * @see javax.servlet.ServletResponse#setCharacterEncoding
	 */
	protected abstract void renderReport(JasperPrint populatedReport, Map model, HttpServletResponse response)
			throws Exception;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -