/*
* Copyright (C) 2010---2014 星星(wuweixing)<349446658@qq.com>
*
* This file is part of Wabacus
*
* Wabacus is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wabacus.config.component.application.report;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.wabacus.config.Config;
import com.wabacus.config.component.ComponentConfigLoadAssistant;
import com.wabacus.exception.WabacusConfigLoadingException;
import com.wabacus.system.ReportRequest;
import com.wabacus.system.inputbox.AbsSelectBox;
import com.wabacus.util.Consts;
import com.wabacus.util.Tools;
public class SqlBean extends AbsConfigBean
{
private Boolean isPreparedStatement=null;
private Boolean isSelectPreparedStatement=null;//在<select/>标签中配置的preparedstatement属性
private String datasource;//此报表所使用的数据源,默认为wabacus.cfg.xml中<datasources/>标签中的default属性配置的值
// private Object searchTemplateObj;//搜索栏的显示模板,可能是字符串或TemplateBean
private List<ConditionBean> lstConditions=new ArrayList<ConditionBean>();
private Map<String,ConditionBean> mConditions;//运行时由lstConditions生成,方便根据<condition/>的name属性取到对应的ConditionBean对象
private List<String> lstConditionFromRequestNames;
private String beforeSearchMethod;
private List<ReportDataSetBean> lstDatasetBeans;//存放所有<value/>子标签,存放顺序为它们的执行顺序
private Map<String,ReportDataSetBean> mDatasetBeans;//根据lstDatasetBeans生成
private List<List<ReportDataSetBean>> lstDatasetGroupBeans;//根据<dataset/>的groupid进行分组存放,相同的groupid存放在一个List中
private ReportDataSetBean hdsOnlyTitleDatasetBean;//只查询动态标题的label和value的<dataset/>
private List<List<ReportDataSetBean>> lstHdsDataDatasetGroupBeans;//如果横向数据集中存在只查询标题的<dataset/>,则除去lstDatasetGroupBeans中只查询标题的<dataset/>,即查询数据部分的<dataset/>
private String hdsTitleLabelColumn;//如果是横向数据集,这里存放查询标题显示label的<col/>的column属性配置值
private String hdsTitleValueColumn;//如果是横向数据集,这里存放查询标题数据的<col/>的column属性配置值
private ColBean hdsTitleLabelCbean;//横向数据集中查询标题label的<col/>,在doPostLoad()方法中根据hdsTitleLabelColumn构造
private ColBean hdsTitleValueCbean;//横向数据集中查询标题数据的<col/>,在doPostLoad()方法中根据hdsTitleValueColumn构造
private String titlecolumndatasetid;//在横向数据集中,如果配置了多个<dataset/>,则指定以哪个<dataset/>查询出的标题行为标准,即它查出了多少条记录,就显示多少个列。如果没有配置或配置为空,则以查出最多记录的<dataset/>为准,其它如果没有相应标题的列,则数据部分显示为空。
public SqlBean(AbsConfigBean parent)
{
super(parent);
}
public String getBeforeSearchMethod()
{
return beforeSearchMethod;
}
public void setBeforeSearchMethod(String beforeSearchMethod)
{
this.beforeSearchMethod=beforeSearchMethod;
}
public boolean isPreparedStatement()
{
if(isPreparedStatement==null)
{
isPreparedStatement=Config.getInstance().getSystemConfigValue("default-preparedstatement-sql","true").equalsIgnoreCase("true");
}
return isPreparedStatement;
}
public void setPreparedStatement(String isPreparedStatement)
{
if(isPreparedStatement==null||isPreparedStatement.trim().equals(""))
{
this.isPreparedStatement=null;
}else
{
this.isPreparedStatement=isPreparedStatement.trim().equalsIgnoreCase("true");
}
}
public boolean isSelectPreparedStatement()
{
if(isSelectPreparedStatement==null)
{
isSelectPreparedStatement=this.isPreparedStatement();
}
return isSelectPreparedStatement;
}
public void setSelectPreparedStatement(String isPreparedStatement)
{
if(isPreparedStatement==null||isPreparedStatement.trim().equals(""))
{
this.isSelectPreparedStatement=null;
}else
{
this.isSelectPreparedStatement=isPreparedStatement.trim().equalsIgnoreCase("true");
}
}
public List<ConditionBean> getLstConditions()
{
return lstConditions;
}
public void setLstConditions(List<ConditionBean> lstConditions)
{
this.lstConditions=lstConditions;
}
public String getDatasource()
{
return datasource;
}
public void setDatasource(String datasource)
{
this.datasource=datasource;
}
public List<ReportDataSetBean> getLstDatasetBeans()
{
return lstDatasetBeans;
}
public void setLstDatasetBeans(List<ReportDataSetBean> lstDatasetBeans)
{
this.lstDatasetBeans=lstDatasetBeans;
if(lstDatasetBeans==null||lstDatasetBeans.size()==0)
{
this.mDatasetBeans=null;
}else
{
this.mDatasetBeans=new HashMap<String,ReportDataSetBean>();
for(ReportDataSetBean dsbeanTmp:this.lstDatasetBeans)
{
mDatasetBeans.put(dsbeanTmp.getId(),dsbeanTmp);
}
}
}
public List<List<ReportDataSetBean>> getLstDatasetGroupBeans()
{
return lstDatasetGroupBeans;
}
public List<List<ReportDataSetBean>> getLstHdsDataDatasetGroupBeans()
{
return lstHdsDataDatasetGroupBeans;
}
public void setHdsTitleLabelColumn(String hdsTitleLabelColumn)
{
this.hdsTitleLabelColumn=hdsTitleLabelColumn;
}
public void setHdsTitleValueColumn(String hdsTitleValueColumn)
{
this.hdsTitleValueColumn=hdsTitleValueColumn;
}
public String getHdsTitleLabelColumn()
{
return hdsTitleLabelColumn;
}
public String getHdsTitleValueColumn()
{
return hdsTitleValueColumn;
}
public ColBean getHdsTitleLabelCbean()
{
return hdsTitleLabelCbean;
}
public ColBean getHdsTitleValueCbean()
{
return hdsTitleValueCbean;
}
public boolean isMultiDatasetRows(boolean isOnlyDatasetForData)
{
if(!this.isHorizontalDataset()||this.hdsOnlyTitleDatasetBean==null||!isOnlyDatasetForData)
{
return this.lstDatasetBeans!=null&&this.lstDatasetBeans.size()>1;
}else
{
if(this.lstHdsDataDatasetGroupBeans==null) return false;
if(this.lstHdsDataDatasetGroupBeans.size()>1) return true;
return this.lstHdsDataDatasetGroupBeans.get(0).size()>1;
}
}
public boolean isMultiDatasetGroups(boolean isOnlyDatasetForData)
{
if(!this.isHorizontalDataset()||this.hdsOnlyTitleDatasetBean==null||!isOnlyDatasetForData)
{
return this.lstDatasetGroupBeans!=null&&this.lstDatasetGroupBeans.size()>1;
}else
{
return this.lstHdsDataDatasetGroupBeans!=null&&this.lstHdsDataDatasetGroupBeans.size()>1;
}
}
public boolean isMultiDataSetCols()
{
if(this.lstDatasetBeans==null||this.lstDatasetBeans.size()==0) return false;
for(ReportDataSetBean datasetBeanTmp:this.lstDatasetBeans)
{
if(datasetBeanTmp.getLstValueBeans()!=null&&datasetBeanTmp.getLstValueBeans().size()>1) return true;
}
return false;
}
public boolean isHorizontalDataset()
{
return !Tools.isEmpty(this.hdsTitleLabelColumn)||!Tools.isEmpty(this.hdsTitleValueColumn);
}
public ReportDataSetBean getDatasetBeanById(String datasetid)
{
if(this.mDatasetBeans==null) return null;
if(datasetid==null||datasetid.trim().equals("")) datasetid=Consts.DEFAULT_KEY;
return this.mDatasetBeans.get(datasetid);
}
public List<ReportDataSetValueBean> getLstDatasetValueBeansByValueid(String valueid)
{
if(this.mDatasetBeans==null) return null;
if(valueid==null||valueid.trim().equals("")) valueid=Consts.DEFAULT_KEY;
List<ReportDataSetValueBean> lstResults=new ArrayList<ReportDataSetValueBean>();
ReportDataSetValueBean dsvbeanTmp;
for(ReportDataSetBean dsbeanTmp:this.lstDatasetBeans)
{
dsvbeanTmp=dsbeanTmp.getDatasetValueBeanById(valueid);
if(dsvbeanTmp!=null) lstResults.add(dsvbeanTmp);
}
return lstResults;
}
public List<ReportDataSetValueBean> getLstDatasetValueBeansOfCbean(ColBean cbean)
{
if(this.mDatasetBeans==null) return null;
List<ReportDataSetValueBean> lstResults=new ArrayList<ReportDataSetValueBean>();
ReportDataSetValueBean dsvbeanTmp;
for(ReportDataSetBean dsbeanTmp:this.lstDatasetBeans)
{
if(this.isHorizontalDataset()
&&(cbean.getColumn().equals(this.hdsTitleLabelCbean.getColumn())||cbean.getColumn().equals(this.hdsTitleValueCbean.getColumn())))
{//如果是横向数据集,且当前<col/>就是查询标题行的各列数据或显示label,则所有<value/>都会查询这两列数据
lstResults.addAll(dsbeanTmp.getLstValueBeans());
}else
{
dsvbeanTmp=dsbeanTmp.getDatasetValueBeanOfCbean(cbean);
if(dsvbeanTmp!=null) lstResults.add(dsvbeanTmp);
}
}
return lstResults;
}
public boolean isExistDependentDataset(String dsvalueid)
{
if(lstDatasetBeans==null) return false;
if(dsvalueid==null||dsvalueid.trim().equals("")) dsvalueid=Consts.DEFAULT_KEY;
for(ReportDataSetBean dsbeanTmp:lstDatasetBeans)
{
if(dsbeanTmp.isDependentDatasetValue(dsvalueid)) return true;
}
return false;
}
public List<String> getLstConditionFromUrlNames()
{
if(lstConditionFromRequestNames==null&&lstConditions!=null&&lstConditions.size()>0)
{
List<String> lstConditionFromRequestNamesTmp=new ArrayList<String>();
for(ConditionBean cbeanTmp:lstConditions)
{
if(cbeanTmp==null||cbeanTmp.isConstant()) continue;
if(cbeanTmp.isConditionValueFromUrl()) lstConditionFromRequestNamesTmp.add(cbeanTmp.getName());
}
this.lstConditionFromRequestNames=lstConditionFromRequestNamesTmp;
}
return lstConditionFromRequestNames;
}
public void setLstConditionFromRequestNames(List<String> lstConditionFromRequestNames)
{
this.lstConditionFromRequestNames=lstConditionFromRequestNames;
}
public String getTitlecolumndatasetid()
{
return titlecolumndatasetid;
}
public void setTitlecolumndatasetid(String titlecolumndatasetid)
{
this.titlecolumndatasetid=titlecolumndatasetid;
}
public ConditionBean getConditionBeanByName(String name)
{
if(name==null||name.trim().equals("")) return null;
if(this.lstConditions==null||this.lstConditions.size()==0) return null;
if(this.mConditions==null)
{//还没有初始化此容器
Map<String,ConditionBean> mConditionsTmp=new HashMap<String,ConditionBean>();
for(ConditionBean cbTmp:lstConditions)
{
mConditionsTmp.put(cbTmp.getName(),cbTmp);
}
this.mConditions=mConditionsTmp;
}
return this.mConditions.get(name);
}
public void initConditionValues(ReportRequest rrequest)
{
if(this.lstConditions==null||this.lstConditions.size()==0) return;
Map<String,String> mConditionValues=new HashMap<String,String>();
for(ConditionBean cbean:lstConditions)
{
cbean.initConditionValueByInitMethod(rrequest,mConditionValues);
}
for(ConditionBean cbean:lstConditions)
{
cbean.validateConditionValue(rrequest,mConditionValues);
}
}
public boolean isExistConditionWithInputbox(ReportRequest rrequest)
{
if(this.lstConditions==null||this.lstConditions.size()==0) return false;
for(ConditionBean cbeanTmp:this.lstConditions)
{
if(!cbeanTmp.isConditionWithInputbox()) continue;
if(rrequest!=null
&&!rrequest.checkPermission(this.getReportBean().getId(),Consts.SEARCH_PART,cbeanTmp.getName(),Consts.PERMISSION_TYPE_DISPLAY))
continue;
return true;
}
return false;
}
public List<ConditionBean> getLstDisplayConditions(ReportRequest rrequest)
{
if(this.lstConditions==null||this.lstConditions.size()==0) return null;
List<ConditionBean> lstConditionsResult=new ArrayList<ConditionBean>();
for(ConditionBean cbeanTmp:this.lstConditions)
{
if(!cbeanTmp.isConditionWithInputbox()) continue;
if(rrequest!=null
&&!rrequest.checkPermission(this.getReportBean().getId(),Consts.SEARCH_PART,cbeanTmp.getName(),Consts.PERMISSION_TYPE_DISPLAY))
continue;
lstConditionsResult.add(cbeanTmp);
}
return lstConditions;
}
public void afterSqlLoad()
{
if(lstDatasetBeans==null) return;
for(ReportDataSetBean dsbeanTmp:lstDatasetBeans)
{
dsbeanTmp.afterSqlLoad();
}
}
public void doPostLoad()
{
ReportBean rbean=this.getReportBean();
if(this.lstConditions!=null)
{
List<String> lstTmp=new ArrayList<String>();
for(ConditionBean cbTmp:lstConditions)
{
if(cbTmp==null||cbTmp.getName()==null) continue;
if(lstTmp.contains(cbTmp.getName()))
{
throw new WabacusConfigLoadingException("报表 "+rbean.getPath()+"配置的查询条件name:"+cbTmp.getName()+"存在重复,必须确保唯一");
}
lstTmp.add(cbTmp.getName());
if(cbTmp.getInputbox() instanceof AbsSelectBox)
{
((AbsSelectBox)cbTmp.getInputbox()).processParentInputBox();
}
}
for(ConditionBean cbTmp:lstConditions)
{
if(cbTmp==null||cbTmp.getName()==null) continue;
cbTmp.doPostLoad();
}
}
if(lstDatasetBeans!=null)
{
List<String> lstGroupids=new ArrayList<String>();
Map<String,List<ReportDataSetBean>> mReportDatasetGroupBeans=new HashMap<String,List<ReportDataSetBean>>();
List<ReportDataSetBean> lstDatasetGroupBeansTmp;
for(ReportDataSetBean dsbeanTmp:this.lstDatasetBeans)
{
for(ReportDataSetValueBean dsvbeanTmp:dsbeanTmp.getLstValueBeans())
{
dsvbeanTmp.doPostLoad();
}
lstDatasetGroupBeansTmp=mReportDatasetGroupBeans.get(dsbeanTmp.getGroupid());
if(lstDatasetGroupBeansTmp==null)
{
lstDatasetGroupBeansTmp=new ArrayList<ReportDataSetBean>();
mReportDatasetGroupBeans.put(dsbeanTmp.getGroupid(),lstDatasetGroupBeansTmp);
lstGroupids.add(dsbeanTmp.getGroupid());
}
lstDatasetGroupBeansTmp.add(dsbeanTmp);
}
this.lstDatasetGroupBeans=new ArrayList<List<ReportDataSetBean>>();
for(String groupidTmp:lstGroupids)
{
lstDatasetGroupBeans.add(mReportDatasetGroupBeans.get(groupidTmp));
}
if(this.isHorizontalDataset())
{
parseHorizontalDatasetConfig(rbean,lstGroupids,mReportDatasetGroupBeans);
List<Integer> lstPagesize=new ArrayList<Integer>();
lstPagesize.add(-1);//横向数据信报表强制不分页显示
rbean.setLstPagesize(lstPagesize);
}
}
}
private void parseHorizontalDatasetConfig(ReportBean rbean,List<String> lstGroupids,Map<String,List<ReportDataSetBean>> mReportDatasetGroupBeans)
{
if(!Config.getInstance().getReportType(rbean.getType()).isSupportHorizontalDataset(rbean))
{
throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"不支持横向数据集");
}
this.hdsTitleLabelCbean=rbean.getDbean().getColBeanByColColumn(this.hdsTitleLabelColumn);
if(this.hdsTitleLabelCbean==null)
{
throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"配置的为横向数据集,但指定的titlelabelcolumn:"+this.hdsTitleLabelColumn+"没有对应的<col/>配置");
}
if(this.hdsTitleLabelCbean.getLstDatasetValueids()!=null&&this.hdsTitleLabelCbean.getLstDatasetValueids().size()>0)
{
throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"配置的为横向数据集,它的titlelabelcolumn:"+this.hdsTitleLabelColumn
+"对应的<col/>不能指定datasetid,因为<sql/>中所有<value/>都要查询出此列的数据");
}
if(this.hdsTitleLabelCbean.isControlCol()||this.hdsTitleLabelCbean.getProperty()==null
||this.hdsTitleLabelCbean.getProperty().trim().equals("")||this.hdsTitleLabelCbean.isNonFromDbCol()
||this.hdsTitleLabelCbean.isNonValueCol())
{
throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"配置的为横向数据集,它的titlelabelcolumn:"+this.hdsTitleLabelColumn
+"对应的<col/>不是有效的数据列,不能做为横向数据集的标题行");
}
this.hdsTitleValueCbean=rbean.getDbean().getColBeanByColColumn(this.hdsTitleValueColumn);
if(this.hdsTitleValueCbean==null)
{
throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"配置的为横向数据集,但指定的titlevaluecolumn:"+this.hdsTitleValueColumn+"没有对应的<col/>配置");
}
if(this.hdsTitleValueCbean.isControlCol()||this.hdsTitleValueCbean.getProperty()==null
||this.hdsTitleValueCbean.getProperty().trim().equals("")||this.hdsTitleValueCbean.isNonFromDbCol()
||this.hdsTitleValueCbean.isNonValueCol())
{
throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"配置的为横向数据集,它的titlevaluecolumn:"+this.hdsTitleValueColumn
+"对应的<col/>不是有效的数据列,不能做为横向数据集的标题行");
}
if(this.hdsTitleValueCbean.getLstDatasetValueids()!=null&&this.hdsTitleValueCbean.getLstDatasetValueids().size()>0)
{
throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"配置的为横向数据集,它的titlevaluecolumn:"+this.hdsTitleValueColumn
+"对应的<col/>不能指定datasetid,因为<sql/>中所有<value/>都要查询出此列的数据");
}
this.hdsOnlyTitleDatasetBean=null;
this.lstHdsDataDatasetGroupBeans=this.lstDatasetGroupBeans;
if(this.titlecolumndatasetid!=null&&!this.titlecolumndatasetid.trim().equals(""))
{//指定了取横向标题列的数据集<dataset/>的ID
ReportDataSetBean titleDsbean=this.getDatasetBeanById(this.titlecolumndatasetid);
if(titleDsbean==null)
{
throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"配置的为横向数据集,titlecolumndatasetid:"+titlecolumndatasetid
+"没有对应的<dataset/>配置");
}
boolean isOnlyTitleDataset=true;//this.titlecolumndatasetid对应的数据集是否只查询标题数据,不查询数据<col/>的数据
for(ColBean cbTmp:rbean.getDbean().getLstCols())
{
if(cbTmp.isControlCol()||cbTmp.isNonFromDbCol()||cbTmp.isNonValueCol()||cbTmp.isSequenceCol()) continue;
if(this.hdsTitleLabelColumn.equals(cbTmp.getColumn())||this.hdsTitleValueColumn.equals(cbTmp.getColumn())) continue;
if(titleDsbean.getDatasetValueBeanOfCbean(cbTmp)!=null)
{
isOnlyTitleDataset=false;
break;
}
}
if(isOnlyTitleDataset)
{//this.titlecolumndatasetid对应的数据集是否只查询标题数据,不查询数据<col/>的数据
this.hdsOnlyTitleDatasetBean=titleDsbean;
if(mReportDatasetGroupBeans.get(titleDsbean.getGroupid()).size()>1)
{
throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"配置的为横向数据集,id为:"+titleDsbean.getId()
+"的<dataset/>配置为只查询标题部分,因此不能和其它数据集通过mergetop属性进行合并,也没必要合并");
}
this.lstHdsDataDatasetGroupBeans=new ArrayList<List<ReportDataSetBean>>();
for(String groupidTmp:lstGroupids)
{
if(!groupidTmp.equals(titleDsbean.getGroupid())) lstHdsDataDatasetGroupBeans.add(mReportDatasetGroupBeans.get(groupidTmp));
}
if(this.lstHdsDataDatasetGroupBeans.size()==0||this.lstHdsDataDatasetGroupBeans.get(0).size()==0)
{
throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"配置的为横向数据集,没有配置查询数据列的数据集<dataset/>");
}
}
}
}
public AbsConfigBean clone(AbsConfigBean parent)
{
SqlBean sbeanNew=(SqlBean)super.clone(parent);
((ReportBean)parent).setSbean(sbeanNew);
sbeanNew.setLstConditions(ComponentConfigLoadAssistant.getInstance().cloneLstConditionBeans(sbeanNew,lstConditions));
if(lstConditionFromRequestNames!=null)
{
sbeanNew.setLstConditionFromRequestNames((List<String>)((ArrayList<String>)lstConditionFromRequestNames).clone());
}
if(lstDatasetBeans!=null)
{
List<ReportDataSetBean> lstDataSetBeansNew=new ArrayList<ReportDataSetBean>();
Map<String,ReportDataSetBean> mDatasetBeansNew=new HashMap<String,ReportDataSetBean>();
ReportDataSetBean rdsbeanTmp;
for(ReportDataSetBean svbeanTmp:lstDatasetBeans)
{
rdsbeanTmp=(ReportDataSetBean)svbeanTmp.clone(sbeanNew);
lstDataSetBeansNew.add(rdsbeanTmp);
mDatasetBeansNew.put(rdsbeanTmp.getId(),rdsbeanTmp);
}
sbeanNew.lstDatasetBeans=lstDataSetBeansNew;
sbeanNew.mDatasetBeans=mDatasetBeansNew;
}
cloneExtendConfig(sbeanNew);
return sbeanNew;
}
}