/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package cli_fmw.report.implemenatation;
import cli_fmw.report.FormReportCreator;
import cli_fmw.report.TableReportOptions;
import cli_fmw.utils.MessageBox;
import cli_fmw.main.ClipsException;
import java.awt.EventQueue;
import java.io.Reader;
import java.io.StringReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.table.TableModel;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRTableModelDataSource;
import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory;
import net.sf.jasperreports.engine.util.JRXmlUtils;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
/**
* Ищен готовый отчет, если найти не удалось, тиа отчета был равен 0,
* и были передан список полей, то генирирует новый шаблон отчета.
* Не может сгенерировать отчет по переданной XML
* @author finder
*/
public class JasperFormReporter extends JasperReporter<TableReportOptions> implements FormReportCreator {
/**
* модель таблицы, для передачи повторяющихся данных в отчет.
* Для каждого элемента будет вызван метод RepoterFactory.convertDataToString()
*/
TableModel table;
/**
* стандартный XML файл загруженный в строку
*/
String xml;
/**
* поток для чтения текстового XML файла
*/
Reader xmlReader;
/**
*
* @param formClass - Класс обьекта для которого печатается отчет, используется
* для создания пути к отчету, и поиска его ресурса.
* @param reportType - Тип отчета, число от 0 до Integer.MAX_VALUE, номер
* отчета, для панелей у которых несколько отчетов.
* Если меньше нуля то игнорируется, если ноль,
* то будет произведенна попытка сгенерировать отчет.
* @param reportName - Имя именовоного отчета, несли не null то будет
* произведен поиск файла отчета с таким именем.
*/
public JasperFormReporter(Class formClass, int reportType, String reportName) {
super(formClass, reportType, reportName);
}
/**
* Заполняет шаблон отчета по данным находящимся в XML
* @param xml - стандартный XML файл загруженный в строку
*/
@Override
synchronized public void createReport(String xml) {
if (xml == null) {
throw new IllegalArgumentException("xml can not be null");
}
setInit();
this.xml = xml;
}
/**
* Заполняет шаблон отчета по данным находящимся в XML
* @param xmlReader - поток для чтения текстового XML файла
*/
@Override
synchronized public void createReport(Reader xmlReader) {
if (xmlReader == null) {
throw new IllegalArgumentException("xml can not be null");
}
setInit();
this.xmlReader = xmlReader;
}
/**
* Формирует отчет по данным из модели таблицы и приведенному списку полей.
* Также можно передовать допольнительные параметры (параметры зависят от отчета);
* Любые из параметров могут быть NULL в зависимости от отчета.
*
* @param title - заголовок отчета, имеет смысл только при автогенерации отчета
* @param options - параметры отчета, (орентация страницы, и тп),
* имеет смысл только при автогенерации отчета
* @param topExtraFields - дополнительные параметры, в качестве ключа должна
* использоватся строка (String) c внутренним именем параметра.
* Дополнительные параметры индеведулальны для каждого отчета
*
* Для для настройки автогенерации формы, в качестве дополнительнго параметра
* надо прередовать класс ExtraField, если форма была создана в ручную то
* у этого класса будет использовано только поле data.
* @param table - модель таблицы, для передачи повторяющихся данных в отчет.
* Для каждого элемента будет вызван метод
* ReporterFactory.convertDataToString()
*/
@Override
synchronized public void createReport(String title, TableReportOptions options, Collection<Map.Entry<String, Object>> topExtraFields, TableModel table) {
createReport(title, options, topExtraFields, null, table);
}
/**
* Формирует отчет по данным из модели таблицы и приведенному списку полей.
* Также можно передовать допольнительные параметры (параметры зависят от отчета);
* Любые из параметров могут быть NULL в зависимости от отчета.
*
* @param title - заголовок отчета, имеет смысл только при автогенерации отчета
* @param options - параметры отчета, (орентация страницы, и тп), имеет смысл только при автогенерации отчета
* @param topExtraFields - дополнительные параметры, в качестве ключа должна
* использоватся строка (String) c внутренним именем параметра.
* Дополнительные параметры индеведулальны для каждого отчета
*
* Для для настройки автогенерации формы, в качестве дополнительнго параметра
* надо прередовать класс ExtraField, если форма была создана в ручную то
* у этого класса будет использовано только поле data.
* @param bottomExtraFields - эти занчения будут добавленны после отчета,
* имеет смысл только при автогенерации отчета
* @param table - модель таблицы, для передачи повторяющихся данных в отчет.
* Для каждого элемента будет вызван метод
* ReporterFactory.convertDataToString()
*/
@Override
public void createReport(String title, TableReportOptions options, Collection<Entry<String, Object>> topExtraFields, Collection<Entry<String, Object>> bottomExtraFields, TableModel table) {
setInit();
this.title = title;
setOptions(options);
this.topExtraFields = topExtraFields;
this.bottomExtraFields = bottomExtraFields;
if (table != null) {
this.table = copyTableModel(table);
}
else {
this.table = null;
}
if (!isCreateReportByTableModelCalled()) {
throw new IllegalArgumentException("all params of createReport can not be null");
}
}
/**
* Формирует отчет по данным из модели таблицы.
* @param topExtraFields - дополнительные параметры, в качестве ключа должна
* использоватся строка (String) c внутренним именем параметра.
* Дополнительные параметры индеведулальны для каждого отчета
*
* Для для настройки автогенерации формы, в качестве дополнительнго параметра
* надо прередовать класс ExtraField, если форма была создана в ручную то
* у этого класса будет использовано только поле data.
* @param table - модель таблицы, для передачи повторяющихся данных в отчет.
* Для каждого элемента будет вызван метод
* ReporterFactory.convertDataToString()
*/
@Override
public void createReport(Map<String, Object> extraFields, TableModel table) {
createReport(null, null, extraFields == null? null: extraFields.entrySet(), table);
}
/**
* Инициализируе параметры отчета, для генераци отчета по XML
* @param params - параметры будущего отчета
* @throws net.sf.jasperreports.engine.JRException - при ошибках в XML
*/
void initXmlParams(HashMap<String, Object> params) throws JRException, ClipsException{
if (xmlReader == null) {
xmlReader = new StringReader(xml);
}
Document doc = JRXmlUtils.parse(new InputSource(xmlReader));
params.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, doc);
params.put(JRXPathQueryExecuterFactory.XML_LOCALE, RUS_LOCALE);
params.putAll(getLoader().getDefaultParameters());
}
/**
* Инициализирует параметры отчета, для генераци отчета по коллекции
* параметров, и модели таблицы.
* @param params - параметры будущего отчета
*/
void initTableParams(HashMap<String, Object> params, boolean isAutoGenerated) throws ClipsException{
initFieldParams(params, isAutoGenerated);
if (table != null) {
params.put(JRParameter.REPORT_DATA_SOURCE, new JRTableModelDataSource(table));
}
params.putAll(getLoader().getDefaultParameters());
}
/**
* Проверяеть была ли вызвана функция createReport со списком полей, или моделью таблицы
* @return - истину если была
*/
protected boolean isCreateReportByTableModelCalled(){
return title != null || getOptions() != null || topExtraFields != null || bottomExtraFields != null || table != null;
}
/**
* Проверяеть была ли вызвана функция createReport с XML
* @return - истину если была
*/
protected boolean isCreateReportByXmlModelCalled(){
return xml != null || xmlReader != null;
}
/**
* Возвращяет список параметров отчета, которы нужны для его постраения,
* параметры строятся, на основе переданынх в createReport данных.
* @return карту имя рараметра-заначение
* @throws net.sf.jasperreports.engine.JRException
* @throws cli_fmw.main.ClipsException
*/
@Override
public Map<String, ?> getParameters() throws JRException, ClipsException {
isInit();
HashMap<String, Object> params = new HashMap<String, Object>();
params.put(JRParameter.REPORT_LOCALE, RUS_LOCALE);
if (isCreateReportByTableModelCalled()){
initTableParams(params, isAutoGenerated());
}
else if (isCreateReportByXmlModelCalled()) {
initXmlParams(params);
}
else {
throw new IllegalArgumentException("Перед вывододм отчета должна быть "
+ "вызвана хоть одна функция createReport, и "
+ "ей должны быть переданны данные");
}
return params;
}
/**
* Возвращает загруженный и скомпелированный шаблон отчета, предназначеный
* для заполнения с помощью параметров
* @return - шаблон отчета
* @throws net.sf.jasperreports.engine.JRException
* @throws cli_fmw.main.ClipsException
*/
public JasperReport getTemplateImp() throws JRException, ClipsException {
isInit();
JasperReport report = getLoader().loadReport();
if (report != null) {
return report;
}
if (isCreateReportByTableModelCalled()){
if (reportType == 0){
if (getOptions() == null) {
setOptions(new TableReportOptions());
}
JasperTableBuilder tableBilder = new JasperTableBuilder(getOptions(), table);
JasperReportBuilder generator = new JasperReportBuilder(title, getOptions(), topExtraFields, bottomExtraFields, tableBilder);
report = generator.buildReport();
}
}
if (report == null){
throw new ClipsException("Не удалось найти файл " + getLoader().getLastLoadedFileName());
}
return report;
}
/**
* Копирует модель таблицы
* (В текущей версии при сопирования все поля заменяются их строковыми
* заняениями с помощью ReporterFactory.convertDataToString)
* @param tm - модель для копрования
* @return новая модель содержащая копию данных
*/
private TableModel copyTableModel(TableModel tm){
return new StringTableModel(tm);
}
}