package gov.samhsa.consent2share.infrastructure.report;
import static gov.samhsa.consent2share.infrastructure.report.JRDataSourceFactory.newJRDataSource;
import java.util.Collection;
import java.util.Map;
import java.util.function.Supplier;
import net.sf.jasperreports.engine.JRDataSource;
import org.springframework.util.Assert;
import org.springframework.web.servlet.ModelAndView;
/**
* This is the base abstract class for the concrete report controllers. For each
* report, there needs to be a separate concrete report controller. This
* abstract controller only defines the dependencies on
* {@link #reportDataProvider} and {@link #abstractReportConfig}, and provides a
* convenience method {@link #reportModelAndView(ReportFormat, Supplier)} to
* build a {@link ModelAndView} from {@link ReportFormat},
* {@link #reportDataProvider} and {@link #abstractReportConfig};
*
* @see ReportDataProvider
* @see AbstractReportConfig
*/
public abstract class AbstractReportController {
/** The report data provider. */
protected final ReportDataProvider reportDataProvider;
/** The abstract report config. */
protected final AbstractReportConfig abstractReportConfig;
/**
* Instantiates a new abstract report controller.
*
* @param reportDataProvider
* the report data provider
* @param abstractReportConfig
* the abstract report config
*/
public AbstractReportController(ReportDataProvider reportDataProvider,
AbstractReportConfig abstractReportConfig) {
super();
this.reportDataProvider = reportDataProvider;
this.abstractReportConfig = abstractReportConfig;
}
/**
* Convenience method to convert the report data to {@link JRDataSource},
* run all the {@link ReportParameterConfigurerTask}s in
* {@link AbstractReportConfig#reportParameterConfigurerChain} by invoking
* {@link AbstractReportConfig#configure(ReportFormat, JRDataSource)},
* instantiates and returns {@link ModelAndView} with the
* <b>{viewName=reportName; model=
* {@link AbstractReportConfig#configure(ReportFormat, JRDataSource)}
* result}. </b>
*
* @param <T>
* the generic type
* @param reportFormat
* the report format
* @param dataSupplier
* the data supplier
* @return the model and view
*/
public final <T> ModelAndView reportModelAndView(ReportFormat reportFormat,
Supplier<? extends Collection<T>> dataSupplier) {
// Prepare datasource for the report
final JRDataSource reportDatasource = newJRDataSource(dataSupplier);
// Configure report parameters
final Map<String, Object> parameters = this.abstractReportConfig
.configure(reportFormat, reportDatasource);
// Build and return ModelAndView
final String reportName = this.abstractReportConfig.getReportName();
Assert.hasText(reportName, "No report name");
Assert.notEmpty(parameters, "Report parameters cannot be empty");
return new ModelAndView(reportName, parameters);
}
/**
* Gets the request scoped parameters instance to set custom parameters to
* the report model/parameters. This method must be used to get
* {@link RequestScopedParameters} from
* {@link RequestScopedParametersProviderImpl}, because it is also asserting
* that the bean's state is valid.
*
* @param requestScopedParametersProvider
* the request scoped parameters provider
* @return the request scoped parameters
*/
public static final RequestScopedParameters getRequestScopedParameters(
RequestScopedParametersProvider requestScopedParametersProvider) {
final RequestScopedParameters bean = requestScopedParametersProvider
.getRequestScopedParameters();
Assert.notNull(bean, "RequestScopedParameters instance cannot be null");
Assert.notNull(bean.getParameters(),
"RequestScopedParameters.parameters cannot be null");
Assert.isTrue(bean.getParameters().size() == 0,
"RequestScopedParameters.parameters must have '0' elements");
return bean;
}
}