/* * 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.ConfigLoadManager; import com.wabacus.config.xml.XmlElementBean; import com.wabacus.exception.WabacusConfigLoadingException; import com.wabacus.exception.WabacusRuntimeException; import com.wabacus.system.ReportRequest; import com.wabacus.system.assistant.WabacusAssistant; import com.wabacus.system.dataset.select.report.value.AbsReportDataSetValueProvider; import com.wabacus.system.dataset.select.report.value.RelationalDBReportDataSetValueProvider; import com.wabacus.system.dataset.select.report.value.SPReportDataSetValueProvider; import com.wabacus.system.dataset.select.report.value.SQLReportDataSetValueProvider; import com.wabacus.util.Consts; import com.wabacus.util.Tools; public class ReportDataSetBean extends AbsConfigBean { private String id; private String datasource;//此报表所使用的数据源,默认为wabacus.cfg.xml中<datasources/>标签中的default属性配置的值 private String groupid;//所有通过mergetop属性合并在一起的算一个组,它们的组ID都是第一个<dataset/>的id,如果是一个独立的<dataset/>,它的组id就是它自己的id private List<XmlElementBean> lstEleValueBeans;//存放其下配置的所有<value/>子标签,只在加载时存放一次,加载完后清空 private List<ReportDataSetValueBean> lstValueBeans;//本<dataset/>中配置的所有<value/>对象 private Map<String,ReportDataSetValueBean> mValueBeans; private boolean mergetop;//当前数据集查询出的数据是否简单的合并到上一个<dataset/>中,做为上一个数据集的记录,目前只有图形报表的数据集会用到此属性 private String datasetstyleproperty;//配置在<dataset/>的styleproperty的样式,只对图形报表类型有效 private List<String> lstDynDatasetstylepropertyParts; public ReportDataSetBean(AbsConfigBean parent) { super(parent); this.datasource=((SqlBean)parent).getDatasource(); } public String getId() { return id; } public void setId(String id) { this.id=id; } public String getGroupid() { return groupid; } public void setGroupid(String groupid) { this.groupid=groupid; } public boolean isMergetop() { return mergetop; } public void setMergetop(boolean mergetop) { this.mergetop=mergetop; } public List<XmlElementBean> getLstEleValueBeans() { return lstEleValueBeans; } public void setLstEleValueBeans(List<XmlElementBean> lstEleValueBeans) { this.lstEleValueBeans=lstEleValueBeans; } public List<ReportDataSetValueBean> getLstValueBeans() { return lstValueBeans; } public String getDatasource() { if(datasource==null||datasource.trim().equals("")) { datasource=((SqlBean)this.getParent()).getDatasource(); } return datasource; } public void setDatasource(String datasource) { this.datasource=datasource; } public String getDatasetstyleproperty(ReportRequest rrequest,boolean isStaticPart) { if(isStaticPart) return this.datasetstyleproperty; return WabacusAssistant.getInstance().getStylepropertyWithDynPart(rrequest,this.datasetstyleproperty,this.lstDynDatasetstylepropertyParts,""); } public void setDatasetstyleproperty(String datasetstyleproperty,boolean isStaticPart) { if(isStaticPart) { this.datasetstyleproperty=datasetstyleproperty; }else { Object[] objArr=WabacusAssistant.getInstance().parseStylepropertyWithDynPart(datasetstyleproperty); this.datasetstyleproperty=(String)objArr[0]; this.lstDynDatasetstylepropertyParts=(List<String>)objArr[1]; } } public ReportDataSetValueBean getDatasetValueBeanById(String valueid) { if(this.mValueBeans==null) return null; if(valueid==null||valueid.trim().equals("")) valueid=Consts.DEFAULT_KEY; return this.mValueBeans.get(valueid); } public ReportDataSetValueBean getDatasetValueBeanOfCbean(ColBean cbean) { if(this.mValueBeans==null||this.mValueBeans.size()==0) return null; if(cbean.getLstDatasetValueids()==null||cbean.getLstDatasetValueids().size()==0) {//如果没有为它配置datasetvalueid,则说明所有<dataset/>下面只有一个<value/>,直接返回即可 return this.mValueBeans.entrySet().iterator().next().getValue(); } SqlBean sbean=(SqlBean)this.getParent(); if(sbean.isHorizontalDataset() &&(cbean.getColumn().equals(sbean.getHdsTitleLabelCbean().getColumn())||cbean.getColumn().equals( sbean.getHdsTitleValueCbean().getColumn()))) {//如果是横向数据集,且当前<col/>就是查询标题行的各列数据或显示label,则返回true,因为所有<value/>都会查询这两列数据 throw new WabacusRuntimeException("报表"+cbean.getReportBean().getPath()+"是横向数据集,且"+cbean.getColumn() +"为显示标题行的列,所有<value/>都会加载它的数据,因此不能调用此方法获取它的数据集<value/>对象"); } for(String valueidTmp:cbean.getLstDatasetValueids()) { if(this.mValueBeans.containsKey(valueidTmp)) return this.mValueBeans.get(valueidTmp); } return null; } boolean isDependentDatasetValue(String valueid) { if(valueid==null||valueid.trim().equals("")) valueid=Consts.DEFAULT_KEY; if(this.mValueBeans==null||this.mValueBeans.get(valueid)==null) return false; return this.mValueBeans.get(valueid).isDependentDataSet(); } public boolean loadDatasetValues() { if(lstEleValueBeans==null||lstEleValueBeans.size()==0) return false; this.lstValueBeans=new ArrayList<ReportDataSetValueBean>(); this.mValueBeans=new HashMap<String,ReportDataSetValueBean>(); ReportBean rbean=this.getReportBean(); List<String> lstExistDatasetids=new ArrayList<String>();//存放已经处理过的<value/>的id属性 boolean isExistNoIdValue=false;//是否已经存在没有配置id的<value/> String valueidTmp; for(XmlElementBean eleValueBeanTmp:lstEleValueBeans) { if(eleValueBeanTmp==null) continue; valueidTmp=eleValueBeanTmp.attributeValue("id"); valueidTmp=valueidTmp==null?"":valueidTmp.trim(); if(valueidTmp.equals("")) { if(this.lstValueBeans.size()>0) {//已经有<value/>,说明配置了多个<value/> throw new WabacusConfigLoadingException("加载报表"+rbean.getPath()+"上的<value/>失败,当使用多个<value/>时,所有<value/>标签必须配置id属性,且不能重复"); } valueidTmp=Consts.DEFAULT_KEY; isExistNoIdValue=true; }else { if(isExistNoIdValue) {//已经存在没有配置id的<value/> throw new WabacusConfigLoadingException("加载报表"+rbean.getPath()+"上的<value/>失败,当使用多个<value/>时,所有<value/>标签必须配置id属性,且不能重复"); } if(lstExistDatasetids.contains(valueidTmp)) { throw new WabacusConfigLoadingException("加载报表"+rbean.getPath()+"上的<value/>失败,id属性为"+valueidTmp+"的<value/>存在重复"); } lstExistDatasetids.add(valueidTmp); } ReportDataSetValueBean datasetValueBean=new ReportDataSetValueBean(this); datasetValueBean.setElementBean(eleValueBeanTmp); datasetValueBean.setId(valueidTmp.trim()); datasetValueBean.setDatasource(eleValueBeanTmp.attributeValue("datasource")); datasetValueBean.setDependParents(eleValueBeanTmp.attributeValue("depends")); datasetValueBean.setDependsConditionExpression(eleValueBeanTmp.attributeValue("dependscondition")); String dependstype=eleValueBeanTmp.attributeValue("dependstype"); if(dependstype!=null) datasetValueBean.setDependstype(dependstype.trim()); String seperator=eleValueBeanTmp.attributeValue("seperator"); if(seperator!=null) datasetValueBean.setSeperator(seperator); AbsReportDataSetValueProvider dsvProviderObj=null; String provider=eleValueBeanTmp.attributeValue("provider"); if(provider!=null&&Tools.isDefineKey("class",provider)) { Object datasetValueTypeObj=null; try { datasetValueTypeObj=ConfigLoadManager.currentDynClassLoader.loadClassByCurrentLoader(Tools.getRealKeyByDefine("class",provider)).newInstance(); }catch(Exception e) { throw new WabacusConfigLoadingException("配置<datasetvalue-provider/>的class:"+provider+"类无法实例化",e); } if(!AbsReportDataSetValueProvider.class.isInstance(datasetValueTypeObj)) { throw new WabacusConfigLoadingException("配置<datasetvalue-provider/>的class:"+provider+"没有继承"+AbsReportDataSetValueProvider.class.getName()+"类"); } dsvProviderObj=(AbsReportDataSetValueProvider)datasetValueTypeObj; }else { dsvProviderObj=Config.getInstance().getReportDatasetValueProvider(provider); if(dsvProviderObj==null) { if(provider==null||provider.trim().equals("")) { throw new WabacusConfigLoadingException("没有在wabacus.cfg.xml中指定全局默认报表数据集provider,必须为报表"+rbean.getPath()+"的数据集<value/>指定provider"); }else { throw new WabacusConfigLoadingException("报表"+rbean.getPath()+"的数据集<value/>指定的provider:"+provider+"不存在"); } } if(dsvProviderObj instanceof RelationalDBReportDataSetValueProvider) { String sqlValue=eleValueBeanTmp.getContent(); sqlValue=Tools.formatStringBlank(sqlValue); if(sqlValue==null||sqlValue.trim().equals("")) { throw new WabacusConfigLoadingException("加载报表"+rbean.getPath()+"的<sql/>下的<value/>配置失败,没有为<value/>标签配置查询数据的SQL语句或JAVA类"); } sqlValue=sqlValue.trim(); while(sqlValue.endsWith(";")) { sqlValue=sqlValue.substring(0,sqlValue.length()-1).trim(); } if(sqlValue.startsWith("{")&&sqlValue.endsWith("}")) sqlValue=sqlValue.substring(1,sqlValue.length()-1).trim(); if(sqlValue.toLowerCase().indexOf("call ")==0||sqlValue.toLowerCase().indexOf("{call ")==0) { dsvProviderObj=new SPReportDataSetValueProvider(); }else { dsvProviderObj=new SQLReportDataSetValueProvider(); } ((RelationalDBReportDataSetValueProvider)dsvProviderObj).setValue(sqlValue); }else { try { dsvProviderObj=dsvProviderObj.getClass().newInstance(); }catch(Exception e) { throw new WabacusConfigLoadingException("实例化"+dsvProviderObj.getClass().getName()+"失败",e); } } } dsvProviderObj.setOwnerDataSetValueBean(datasetValueBean); datasetValueBean.setProvider(dsvProviderObj); dsvProviderObj.loadConfig(eleValueBeanTmp); this.lstValueBeans.add(datasetValueBean); this.mValueBeans.put(datasetValueBean.getId(),datasetValueBean); } this.lstEleValueBeans=null; return true; } public void afterSqlLoad() { for(ReportDataSetValueBean valuebeanTmp:this.lstValueBeans) { valuebeanTmp.afterSqlLoad(); } List<ReportDataSetValueBean> lstResults=new ArrayList<ReportDataSetValueBean>();//按依赖关系依次存放各数据集对象,这里存放的顺序就是它们的执行顺序 List<String> lstProcessedValueIds=new ArrayList<String>(); ReportDataSetValueBean vbeanTmp; List<ReportDataSetValueBean> lstTmp=new ArrayList<ReportDataSetValueBean>(); while(this.lstValueBeans.size()>0) { for(int i=0;i<this.lstValueBeans.size();i++) { vbeanTmp=this.lstValueBeans.get(i); if(vbeanTmp.getMDependParents()==null||vbeanTmp.getMDependParents().size()==0 ||hasProcessedAllParentValues(vbeanTmp,lstProcessedValueIds)) { lstProcessedValueIds.add(vbeanTmp.getId()); lstResults.add(vbeanTmp); }else { lstTmp.add(vbeanTmp); } } if(lstTmp.size()==this.lstValueBeans.size()) { throw new WabacusConfigLoadingException("加载报表"+this.getReportBean().getPath()+"的<sql/>中的<value/>配置失败,存在循环依赖或者依赖的父数据集ID不存在的配置"); } this.lstValueBeans=lstTmp; lstTmp.clear(); } this.lstValueBeans=lstResults; } private boolean hasProcessedAllParentValues(ReportDataSetValueBean svbeanTmp,List<String> lstProcessedValueIds) { if(svbeanTmp.getMDependParents()==null||svbeanTmp.getMDependParents().size()==0) return true;//如果没有父数据集 if(lstProcessedValueIds==null||lstProcessedValueIds.size()==0) return false; List<String> lstParentValueids=svbeanTmp.getAllParentValueIds(); for(String parentValueidTmp:lstParentValueids) { if(!lstProcessedValueIds.contains(parentValueidTmp)) return false; } return true; } public AbsConfigBean clone(AbsConfigBean parent) { ReportDataSetBean dsbeanNew=(ReportDataSetBean)super.clone(parent); if(this.lstValueBeans!=null) { List<ReportDataSetValueBean> lstSqlValueBeansNew=new ArrayList<ReportDataSetValueBean>(); Map<String,ReportDataSetValueBean> mValueBeansNew=new HashMap<String,ReportDataSetValueBean>(); ReportDataSetValueBean dsvbeanTmp; for(ReportDataSetValueBean svbeanTmp:this.lstValueBeans) { dsvbeanTmp=svbeanTmp.clone(dsbeanNew); lstSqlValueBeansNew.add(dsvbeanTmp); mValueBeansNew.put(dsvbeanTmp.getId(),dsvbeanTmp); } dsbeanNew.lstValueBeans=lstSqlValueBeansNew; dsbeanNew.mValueBeans=mValueBeansNew; } cloneExtendConfig(dsbeanNew); return dsbeanNew; } }