/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package framework.beans.report;
import framework.audit.AuditDoc;
import framework.beans.FacadeBean;
import framework.beans.HardCodedIDs;
import framework.beans.config.server.ConfigBeanRemoteM;
import framework.beans.security.BeanRights;
import framework.beans.EntityDetails;
import framework.beans.config.server.ConfigBeanM;
import framework.generic.ClipsServerException;
import framework.generic.EDataIntegrity;
import framework.generic.ESecurity;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import framework.security.RightChecker;
import framework.security.UserRightsSetAbstract;
import net.sf.jasperreports.JRCostumFileSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.query.JRJpaQueryExecuterFactory;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.util.JRResourcesUtil;
/**
* @author finder
*/
public abstract class ReportBeanAbstract extends FacadeBean<ReportDefinition>
implements ReportBeanAbstractRemote, JRCostumFileSource {
public static final int COMMAND_READ_REPORT = 4;
public ReportBeanAbstract() {
super(ReportDefinition.class);
}
@Override
protected void initBeanRights() {
int[] r = new int[5];
if (getId() == ReportDefinition.REPORT_CLIENT_SIDE_REPORTS) {
r[COMMAND_READ] = UserRightsSetAbstract.READ_REPORT_STRUCTURE.id;
} else {
r[COMMAND_READ] = RightPresence(UserRightsSetAbstract.READ_REPORT_STRUCTURE.id);
}
int cmr = RightPresence(UserRightsSetAbstract.WRITE_REGION_ADMIN_DIRECTORY.id);
r[COMMAND_CREATE] = cmr;
r[COMMAND_MODIFY] = cmr;
r[COMMAND_REMOVE] = cmr;
r[COMMAND_READ_REPORT] = RightPresence(UserRightsSetAbstract.EXECUTE_REPORT.id);
rights = new BeanRights(r);
}
@Override
protected void onRemove(ReportDefinition entity, List<AuditDoc> audit) throws ClipsServerException {
if (!HardCodedIDs.canRemove(entity.getClass(), entity.getId())) {
throw new EDataIntegrity("Попытка удалить специальный отчет");
}
FileTable file = null;
ArrayList<FileDetails> files = getFiles();
for (FileDetails fileDetails : files) {
removeFile(fileDetails.id);
}
}
@Override
protected void onUpdate(ReportDefinition entity, EntityDetails details,
AuditDoc auditDoc, List<AuditDoc> auditDocList) throws ClipsServerException {
ReportDetail det = (ReportDetail) details;
entity.setReportName(det.reportName);
entity.setReportComment(det.reportName);
entity.setMainFileName(det.mainFile);
entity.setReportParams(det.reportParms);
if (!isJustCreated()) {
entity.setReportVersion(entity.getReportVersion() + 1);
}
}
protected abstract void getExtraDefaultParameters(Map<String, Object> target, ConfigBeanRemoteM config) throws ClipsServerException;
@Override
public Map<String, Object> getDefaultParameters() throws ClipsServerException{
try{
HashMap<String, Object> target = new HashMap<String, Object>();
ConfigBeanRemoteM config = getBean(ConfigBeanRemoteM.class);
getExtraDefaultParameters(target, config);
return target;
} catch (RuntimeException ex) {
throw new ClipsServerException("Ошибка получения параметров отчета", ex);
}
}
HashMap<String, Object> putParams(Map<String, Object> params, JasperReport report) throws ClipsServerException {
HashMap<String, Object> target = new HashMap<String, Object>();
Set<Entry<String, Object>> set;
if (params != null) {
target.putAll(params);
}
target.putAll(getDefaultParameters());
target.put(JRJpaQueryExecuterFactory.PARAMETER_JPA_ENTITY_MANAGER, manager);
return target;
}
@Override
public JasperPrint getReport(Map<String, Object> params) throws ESecurity, ClipsServerException, JRException {
ReportDefinition entity = getExistentEntity();
if (entity.getId() == ReportDefinition.REPORT_CLIENT_SIDE_REPORTS) {
throw new ESecurity("Невозможно выполнить на сервере отчеты клиента!");
}
try {
checkCommandAccessibility(COMMAND_READ_REPORT);
try {
ReportBaseConstant.initReportsFonts();
} catch (IOException ex) {
throw new ClipsServerException("Ошибка при загрузке шрифтов отчета", ex);
}
JRResourcesUtil.setThreadJRCostumFileSource(this);
JasperPrint report;
try {
@SuppressWarnings("unchecked")
InputStream is = getInputStream(entity.getMainFileName());
if (is == null) {
throw new ClipsServerException("Файл отчета не найден");
}
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);
HashMap<String, Object> map = putParams(params, jasperReport);
report = JasperFillManager.fillReport(jasperReport, map);
try {
is.close();
} catch (IOException ex) {
throw new ClipsServerException("Ошибка закрытия виртуального потока", ex);
}
} finally {
JRResourcesUtil.resetJRCostumFileSource();
}
return report;
} catch (JRException ex) {
// work around - для глюка в маршаленге исключений
ex.getStackTrace();
throw ex;
} catch (RuntimeException ex) {
throw new ClipsServerException("Ошибка при заполнении отчета", ex);
}
}
@Override
public FileDetails getFileData(int fileID) throws ESecurity, ClipsServerException {
checkCommandAccessibility(COMMAND_READ);
ReportDefinition entity = getExistentEntity();
FileTable file = findEntity(FileTable.class, fileID);
checkForMyFile(entity, file);
return loadFileData(file.getDetails((RightChecker) this));
}
@Override
public ArrayList<FileDetails> getFiles() throws ClipsServerException {
ReportDefinition entity = getExistentEntity();
checkCommandAccessibility(COMMAND_READ);
if (entity.getId() == 0) {
return new ArrayList<FileDetails>();
}
ArrayList<FileDetails> target = new ArrayList<FileDetails>();
@SuppressWarnings("unchecked")
List<FileTable> fileList = findEntityList(FileTable.class, "report", entity);
for (FileTable fileTable : fileList) {
target.add(fileTable.getDetails((RightChecker) this));
}
return target;
}
private FileDetails loadFileData(FileDetails file) throws ESecurity, ClipsServerException {
FileData data = getDataToFile(findEntity(FileTable.class, file.getId()));
if (data != null) {
file.fileData = data.getFileData();
file.fileSourceData = data.getFileSourseData();
} else {
file.fileData = null;
file.fileSourceData = null;
}
return file;
}
@Override
public void removeFile(int id) throws ClipsServerException {
checkCommandAccessibility(COMMAND_MODIFY);
ReportDefinition entity = getExistentEntity();
FileTable file = findEntity(FileTable.class, id);
checkForMyFile(entity, file);
FileData data = getDataToFile(file);
if (data != null) {
manager.remove(data);
}
manager.remove(file);
}
private FileData getDataToFile(FileTable fileTable) {
List fileList = findEntityList(FileData.class, "fileTable", fileTable);
if (fileList.size() > 0) {
return (FileData) fileList.get(0);
} else {
return null;
}
}
@Override
public int saveFile(FileDetails file) throws ClipsServerException {
checkCommandAccessibility(COMMAND_MODIFY);
ReportDefinition entity = getExistentEntity();
try {
FileTable entFile;
FileData entData = null;
if (file.getId() != 0) {
entFile = findEntity(FileTable.class, file.getId());
checkForMyFile(entity, entFile);
} else {
entFile = new FileTable();
entFile.setReport(entity);
}
entFile.setFileName(file.fileName);
entFile.setFileTypeId(file.fileTypeID);
if (file.fileData == null && entData == null) {
throw new EDataIntegrity("Файл должен содержать данные");
}
entFile = saveFile(entFile);
entData = getDataToFile(entFile);
if (file.fileData != null) {
if (entData == null) {
entData = new FileData();
}
entData.setFileData(file.fileData);
entData.setFileSourseData(file.fileSourceData);
entData.setFileTable(entFile);
saveFileData(entData);
}
return entFile.getId();
} catch (RuntimeException ex) {
throw new ClipsServerException("Не удалось сохранить файл отчета!", ex);
}
}
private FileTable saveFile(FileTable file) throws ESecurity, ClipsServerException {
List<FileTable> files = findFilesByName(file.getFileName(), getExistentEntity());
for (FileTable fileTable : files) {
if (fileTable.getId() != file.getId()) {
if (file.getId() == 0) {
fileTable.setFileName(file.getFileName());
fileTable.setFileTypeId(file.getFileTypeId());
file = fileTable;
break;
} else {
throw new EDataIntegrity("Попытка задать файлу имя уже существующего файла");
}
}
}
if (file.getId() != 0) {
return manager.merge(file);
} else {
manager.persist(file);
manager.flush();
manager.refresh(file);
return file;
}
}
private int saveFileData(FileData data) {
if (data.getId() != 0) {
manager.merge(data);
return data.getId();
} else {
manager.persist(data);
manager.flush();
manager.refresh(data);
return data.getId();
}
}
private List<FileTable> findFilesByName(String fileName, ReportDefinition entity) throws ClipsServerException {
ArrayList<FileTable> target = new ArrayList<FileTable>(1);
ArrayList<String> names = ReportBaseConstant.remapFile(fileName);
for (String string : names) {
target.addAll(getFilesByName(string, entity));
}
return target;
}
private List<FileTable> getFilesByName(String fileName, ReportDefinition entity) throws ClipsServerException {
if (entity.getId() != 0) {
Field[] fiels = new Field[]{
new Field("report", entity),
new Field("fileName", fileName)};
@SuppressWarnings("unchecked")
List<FileTable> files = findEntityList(FileTable.class, fiels);
return files;
} else {
return new ArrayList<FileTable>();
}
}
@Override
public InputStream getInputStream(String fileName) {
try {
List<FileTable> files = findFilesByName(fileName, getExistentEntity());
if (files == null || files.size() == 0) {
files = findFilesByName(fileName, findEntity(ReportDefinition.class, ReportDefinition.REPORT_GLOBAL_REPORTS));
}
if (files != null && files.size() > 0) {
FileData data = getDataToFile(files.get(0));
if (data != null) {
return new ByteArrayInputStream(data.getFileData());
} else {
return null;
}
}
return null;
} catch (ClipsServerException ex) {
ex.printStackTrace();
return null;
}
}
private boolean isMyFile(ReportDefinition entity, FileTable file) throws ClipsServerException {
if (file.getReport() == null) {
return true;
}
return entity.getId() == file.getReport().getId();
}
/**
* @param file
* @throws generic.EDataIntegrity
* @throws generic.ClipsServerException
*/
private void checkForMyFile(ReportDefinition entity, FileTable file) throws EDataIntegrity, ClipsServerException {
if (!isMyFile(entity, file)) {
String fileReportID;
if (file.getReport() == null) {
fileReportID = "<нет>";
} else {
fileReportID = file.getReport().getId() == 0
? "<несохранен>"
: String.valueOf(file.getReport().getId());
}
throw new EDataIntegrity("Указан неверный идентификатор файла: ID отчета:"
+ entity.getId() + ", ID отчета в файле: " + fileReportID);
}
}
}