/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package cli_fmw.report.implemenatation;
import cli_fmw.delegate.AuditListener;
import cli_fmw.delegate.report.FileLocal;
import cli_fmw.delegate.report.ReportLocal;
import cli_fmw.main.ClipsException;
import cli_fmw.report.ReporterFactoryBaseProperties;
import cli_fmw.utils.MessageBox;
import framework.beans.report.ReportBaseConstant;
import framework.beans.report.ReportDefinition;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Map;
import net.sf.jasperreports.JRCostumFileSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;
/**
*
* @author finder
*/
public class JasperReportLoader implements JRCostumFileSource {
/**
* Папка в которой будут искатся локальные для JasperFormReporter отчеты
*/
private enum PathType{
serverPath,
relativeForm,
relativeFormSampleName,
relativeFormFull,
relativeReporter
}
/**
* Класс обьекта для которого печатается отчет, используется
*для создания пути к отчету, и поиска его ресурса.
*/
private Class formClass;
/**
* Тип отчета, число от 0 до Integer.MAX_VALUE, номер отчета, для панелей у
* которых несколько отчетов. Если меньше нуля то игнорируется, если ноль,
* то будет произведенна попытка сгенерировать отчет.
*/
private int reportType;
/**
* Имя именовоного отчета, несли не null то будет произведен поиск файла отчета с таким именем.
*/
private String reportName;
private ReportLocal serverRepors;
private String lastLoadedFileName;
public JasperReportLoader(Class formClass, int reportType, String reportName) {
this.formClass = formClass;
this.reportType = reportType;
this.reportName = reportName;
}
/**
* возвращает списак путей с именми файлов, где может находится отчет
* @param clazz - клас относительно пути которого будет выводится список путей.
* либо клас обекта для которого печатается отчет, либо JasperFormReporter.class
* @return массив всех возможных путей относительно класса clazz
*/
private ArrayList<String> getPath(PathType type){
ArrayList<String> target = new ArrayList<String>();
String className;
switch (type){
case serverPath:
className = formClass.getName();
break;
case relativeFormSampleName:
className = formClass.getSimpleName();
break;
case relativeFormFull:
className = formClass.getName();
break;
case relativeReporter:
className = ReporterFactoryBaseProperties.getReportDirectory() + "/" + formClass.getName();
break;
default:
throw new RuntimeException("Неподдкрживаемый тип пути");
}
if (reportType == 1){
target.add(className);
}
target.add(className + "." + reportType);
target.add(className + "/" + reportType);
if (reportName != null){
target.add(className + "." + reportType + "/" + reportName);
target.add(className + "/" + reportName);
target.add(reportName);
/* }
if (reportName != null){*/
if (type == PathType.relativeReporter) {
target.add(ReporterFactoryBaseProperties.getReportDirectory() + "/" + reportName);
}
else {
target.add(reportName);
}
if (reportType >= 0) {
target.add(className + "." + reportType + "/" + reportName);
target.add(className + "/" + reportType + "/" + reportName);
}
}
return target;
}
private ArrayList<String> getFileList(PathType type, String fileName){
ArrayList<String> path = null;
if (type == PathType.relativeForm){
path = getPath(PathType.relativeFormFull);
path.addAll(getPath(PathType.relativeFormSampleName));
}
else {
path = getPath(type);
}
ArrayList<String> files = new ArrayList<String>();
if (fileName != null) {
ArrayList<String> names = ReportBaseConstant.remapFile(fileName);
for (String curPath : path) {
for (String name : names) {
files.add(curPath + '/' + name);
}
}
if (type == PathType.serverPath) {
files.addAll(names);
}
}
else {
for (String curPath : path){
for (String ex : ReportBaseConstant.JASPER_REPORT_EXTENSION) {
files.add(curPath + ex);
}
}
}
return files;
}
/**
* Загружает шаблон корневого отчета, и возаращает его
* @return
* @throws ClipsException
*/
public JasperReport loadReport() throws ClipsException{
InputStream is = getInputStream(null);
try {
if (is != null){
try{
JasperReport report = (JasperReport) JRLoader.loadObject(is);
return report;
}
catch(JRException ex){
// дропается, возможно отчет не был скомпилирован
}
catch(ClassCastException ex){
throw new ClipsException("Файл " + lastLoadedFileName + " не является файлом отчета!", ex);
}
try {
is.close();
is = null;
} catch (IOException ex) {
ex.printStackTrace();
}
}
is = getInputStream(null);
if (is != null){
try{
JasperReport report = JasperCompileManager.compileReport(is);
return report;
}
catch(Exception ex){
MessageBox.asyncShowExceptionOnly(ex, true);
}
}
}
finally {
try {
if (is != null){
is.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return null;
}
private InputStream getInputStreamFromPathList(ArrayList<String> paths, Class clazz){
for (String path : paths) {
lastLoadedFileName = path;
InputStream is = clazz.getResourceAsStream(path);
if (is != null) {
return is;
}
}
if (paths.size() > 0) {
lastLoadedFileName = paths.get(0);
}
else {
lastLoadedFileName = null;
}
return null;
}
/**
* Функция спецального итерфейса, передаваемого в JasperReport служит для
* изменения путей загрузки дополнительных файлов отчета.
* @param fileName - имя файла с относительны путем, по которому будет загружатся отчет
* @return - поток для загрузки дополнительных данных
*/
@Override
public InputStream getInputStream(String fileName) {
ReportLocal rl = getServerRepors(null);
ArrayList<String> files = getFileList(PathType.serverPath, fileName);
try {
for (String str : files) {
lastLoadedFileName = str;
FileLocal fileLocal = rl.getFile(str);
if (fileLocal != null) {
return new ByteArrayInputStream(fileLocal.getFileCompiledData());
}
}
}
catch (ClipsException ex) {
MessageBox.asyncShowExceptionOnly(ex, true);
return null;
}
files = getFileList(PathType.relativeForm, fileName);
InputStream is = getInputStreamFromPathList(files, formClass);
if (is != null) {
return is;
}
files = getFileList(PathType.relativeReporter, fileName);
is = getInputStreamFromPathList(files, ReporterFactoryBaseProperties.getReportDirectoryClass());
if (is != null) {
return is;
}
return null;
}
public ReportLocal getServerRepors(AuditListener al) {
if (serverRepors == null) {
serverRepors = new ReportLocal(ReportDefinition.REPORT_CLIENT_SIDE_REPORTS, al);
}
return serverRepors;
}
public Map<String, Object> getDefaultParameters() throws ClipsException{
return getServerRepors(null).getDefaultParameters();
}
public String getLastLoadedFileName() {
return lastLoadedFileName;
}
}