/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package clips.reportgen;
import cli_fmw.delegate.AuditListener;
import framework.beans.reportgen.item.ReportQueryBean;
import framework.beans.reportgen.item.ReportQueryRemote;
import cli_fmw.delegate.DelegateLine2;
import cli_fmw.delegate.cache.Cache;
import cli_fmw.delegate.directory.complex.DirectoryLocator;
import cli_fmw.delegate.directory.complex.reportType.DirectoryReportType;
import cli_fmw.delegate.directory.complex.reportType.DirectoryReportTypeItem;
import cli_fmw.main.ClipsException;
import clips.delegate.directory.ro.DirectoryCollaborator;
import clips.delegate.directory.ro.DirectoryCollaboratorItem;
import framework.beans.reportgen.item.QueryDetails;
import framework.generic.ClipsServerException;
import framework.utils.Converter;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom.Document;
import org.jdom.Element;
import reportgen.factory.ReportVersion;
import reportgen.ren.executer.QueryExecuter;
import reportgen.utils.ReportException;
import reportgen.gui.genepanel.Report;
import reportgen.ren.report.ReportQuery;
import reportgen.factory.ReportFactory;
import reportgen.ren.executer.QueryExecuterSub;
import reportgen.ren.executer.QueryResultsData;
import reportgen.ren.loader.SubQueryLoader;
import reportgen.ren.loader.SubQueryLoaderResult;
import reportgen.ren.report.userinput.UserInputChunk;
/**
*
* @author petr
*/
public class QueryLocal
extends DelegateLine2<ReportQueryRemote, QueryDetails>
implements Report {
private SubQueryLoaderImpl queryLoader = new SubQueryLoaderImpl(getAuditListener());
private boolean wrong = false;
private Cache<ReportQuery> reportQuery = new Cache<ReportQuery>();
private Cache<ReportVersion> version = new Cache<ReportVersion>();
private boolean isDirtyQuery = false;
private int reportContinueID;
public QueryLocal(AuditListener al) throws ClipsException, ReportException {
super(al);
this.reportQuery.set(new ReportQuery());
isDirtyQuery = true;
}
/**
*
*/
public QueryLocal(int id, AuditListener al) throws ClipsException {
super(id, al);
}
public QueryLocal(QueryDetails d, boolean wrong, AuditListener al) throws ClipsException {
super(d, al);
this.wrong = wrong;
}
@Override
protected QueryDetails getNewDetails() {
return new QueryDetails();
}
@Override
protected String getBeanName() {
return ReportQueryBean.class.getSimpleName();
}
@Override
public String getTitle() throws ReportException {
try {
return getDetails().title;
} catch (ClipsException ex) {
throw new ReportException(ex.getLocalizedMessage(), ex);
}
}
@Override
public void setTitle(String title) throws ReportException {
try {
getDetails().title = title;
fireContentStateEvent();
} catch (ClipsException ex) {
throw new ReportException(ex.getLocalizedMessage(), ex);
}
}
public DirectoryReportTypeItem getReportType() throws ClipsException {
DirectoryReportType drt = DirectoryLocator.getDirectory(DirectoryReportType.class, false);
return drt.getItemFromID(getDetails().reportType);
}
public void setReportType(DirectoryReportTypeItem item) throws ClipsException {
getDetails().reportType = item.getID();
fireContentStateEvent();
}
@Override
public String getDescription() throws ReportException {
try {
return getDetails().description;
} catch (ClipsException ex) {
throw new ReportException(ex.getLocalizedMessage(), ex);
}
}
@Override
public void setDescription(String desc) throws ReportException {
try {
getDetails().description = desc;
fireContentStateEvent();
} catch (ClipsException ex) {
throw new ReportException(ex.getLocalizedMessage(), ex);
}
}
public boolean isWrong() {
return wrong;
}
@Override
public boolean isUtility() throws ReportException {
try {
return getDetails().subsidiary;
} catch (ClipsException ex) {
throw new ReportException(ex.getLocalizedMessage(), ex);
}
}
@Override
public void setUtility(boolean utility) throws ReportException {
try {
getDetails().subsidiary = utility;
fireContentStateEvent();
} catch (ClipsException ex) {
throw new ReportException(ex.getLocalizedMessage(), ex);
}
}
@Override
public String toString() {
try {
return getTitle();
} catch (ReportException ex) {
return "<Не удалось получить название отчета>";
}
}
public ReportQuery getQuery() throws ReportException {
if(isWrong()) {
throw new RuntimeException("Отчет не корректен и не может быть изменен");
}
if(!reportQuery.inCache()) {
try {
QueryDetails d = getDetails();
ReportQuery req = ReportFactory.fromString(d.id, d.query, queryLoader);
this.reportQuery.set(req);
} catch (ClipsException ex) {
throw new ReportException("Details receiving failed.", ex);
}
}
return reportQuery.get();
}
public ReportVersion getVersion() throws ReportException {
if(!version.inCache()) {
try {
version.set(ReportFactory.getVersion(getDetails().query));
} catch (ClipsException ex) {
throw new ReportException("Details receiving failed.", ex);
}
}
return version.get();
}
/**
*
* @param query not null
* @throws cli_fmw.main.ClipsException
*/
public void setQuery(ReportQuery queryStr) throws ReportException {
if(isWrong()) {
throw new ReportException("Отчет не корректен и не может быть изменен");
}
if (queryStr == null){
throw new IllegalArgumentException("Параметр не может быть null");
}
reportQuery.set(queryStr);
version.clearCache();
isDirtyQuery = true;
fireContentStateEvent();
}
public String getRaw() throws ClipsException {
return ReportFactory.patch(getDetails().query);
}
public void setRaw(String raw) throws ClipsException {
getDetails().query = raw;
reportQuery.clearCache();
version.clearCache();
}
@Override
public boolean isDirty() {
return isDirtyQuery || super.isDirty();
}
@Override
public void reload() throws ClipsException {
super.reload();
reportQuery.clearCache();
version.clearCache();
isDirtyQuery = false;
}
@Override
public void restore() {
super.restore();
reportQuery.clearCache();
version.clearCache();
isDirtyQuery = false;
}
@Override
public void save1() throws ClipsException {
if(isWrong()) {
throw new ClipsException("Отчет не корректен и не может быть изменен");
} else if(isDirty()) {
try {
Element root = getQuery().toXML();
getDetails().query = Converter.xmlToString(new Document(root));
super.save1();
isDirtyQuery = false;
} catch (ReportException ex) {
throw new ClipsException("Отчет не некорректен", ex);
}
}
//повторный вызов fireContentStateEvent нужен потому как кнопка не гаснет
fireContentStateEvent();
}
@Override
public Object executeTest() throws ReportException {
Object res = null;
try {
reportContinueID = 0;
Element root = reportQuery.get().toXML();
String xmlStr = Converter.xmlToString(new Document(root));
res = getBean().doReport(xmlStr);
if(res instanceof QueryResultsData) {
mergeQueryResultsData(reportContinueID, reportQuery.get(), (QueryResultsData)res);
res = continueReport(null);
}
} catch (Exception ex) {
clearBean();
throw new ReportException("При выполнении отчета произошла ошибка.", ex);
}
return res;
}
@Override
public Object execute() throws ReportException {
Object res = null;
try {
reportContinueID = getSavedId();
res = getBean().doReport(reportContinueID);
if(res instanceof QueryResultsData) {
mergeQueryResultsData(reportContinueID, getQuery(), (QueryResultsData)res);
res = continueReport(null);
}
} catch (ReportException ex) {
throw ex;
} catch (Exception ex) {
clearBean();
throw new ReportException("При выполнении отчета произошла ошибка.", ex);
}
return res;
}
private int getSavedId() throws ReportException, ClipsException {
int id = getDetails().getId();
if(id == 0) {
throw new ReportException("Перед выполнением отчет нужно сохранить.");
}
return id;
}
@Override
public Object continueReport(UserInputChunk userInput) throws ReportException {
Object res = null;
try {
res = getBean().continueReport(userInput);
if(res instanceof QueryResultsData) {
mergeQueryResultsData(reportContinueID, getQuery(), (QueryResultsData)res);
res = continueReport(null);
}
} catch (ReportException ex) {
throw ex;
} catch (Exception ex) {
clearBean();
throw new ReportException("При выполнении отчета произошла ошибка.", ex);
}
return res;
}
/**
* сохраняет данные для одного из подотчетов
* @param rep
* @param queryResultsData
* @return
* @throws ReportException
*/
private static boolean mergeQueryResultsData(int id, ReportQuery rep, QueryResultsData queryResultsData)
throws ReportException {
for(QueryExecuterSub subquery : rep.getSubReports().getList()) {
String iHash = QueryResultsData.makeHash(id, subquery);
if(queryResultsData.hash.equals(iHash)) {
subquery.setResults(queryResultsData.queryResults);
return true;
}
}
for(QueryExecuterSub subquery : rep.getSubReports().getList()) {
QueryExecuter subreport = subquery.getReport();
if(mergeQueryResultsData(subreport.getId(), subreport.getQuery(), queryResultsData)) {
return true;
}
}
assert false :"Unknown result";
return false;
}
/**
* Возвращает список коллабов, которым разрешено выполнять сей отчет
* @return селектор
* @throws ClipsException
*/
public Set<DirectoryCollaboratorItem> getCollabs() throws ClipsException {
Set<Integer> collabs;
try {
collabs = getBean().getCollabs();
} catch (Exception ex) {
clearBean();
try {
collabs = getBean().getCollabs();
} catch (ClipsServerException ex1) {
throw new ClipsException("Не удалось получить список сотрудников", ex);
}
}
Set<DirectoryCollaboratorItem> target = new HashSet<DirectoryCollaboratorItem>();
DirectoryCollaborator dir = DirectoryLocator.getDirectory(DirectoryCollaborator.class);
for (Integer id : collabs) {
target.add(dir.getItemFromID(id));
}
return target;
}
/**
* меняет текущих коллабов
* @param upList
*/
public void setCollabs(Set<DirectoryCollaboratorItem> upList) throws ClipsException {
HashSet<Integer> set = new HashSet<Integer>();
for (DirectoryCollaboratorItem item : upList) {
set.add(item.getID());
}
try {
getBean().setCollabs(set);
} catch (Exception ex) {
try {
clearBean();
getBean().setCollabs(set);
} catch (ClipsServerException ex1) {
throw new ClipsException("Не удалось сохранить список сотрудников", ex);
}
}
}
class SubQueryLoaderImpl implements SubQueryLoader {
AuditListener al;
public SubQueryLoaderImpl(AuditListener al) {
this.al = al;
}
@Override
public SubQueryLoaderResult loadSubReport(int id) throws ReportException {
try {
SubQueryLoaderResult res = new SubQueryLoaderResult();
QueryLocal ql = new QueryLocal(id, al);
res.title = ql.getTitle();
res.description = ql.getDescription();
res.report = ql.getQuery();
return res;
} catch (ClipsException ex) {
throw new ReportException("Ошибка при загрузке подотчета №" + id +
": " + ex.getLocalizedMessage());
}
}
}
}