/* * 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.system.dataset.update.precondition; import java.util.ArrayList; import java.util.List; import com.wabacus.config.ConfigLoadManager; import com.wabacus.exception.WabacusConfigLoadingException; import com.wabacus.system.component.application.report.configbean.editablereport.AbsEditableReportEditDataBean; import com.wabacus.util.Tools; public class CompositeExpressionBeanForLoad { private final static List<String> lstSupportCompareTypes=new ArrayList<String>(); static { lstSupportCompareTypes.add("eq"); lstSupportCompareTypes.add("neq"); lstSupportCompareTypes.add("gt"); lstSupportCompareTypes.add("lt"); lstSupportCompareTypes.add("gte"); lstSupportCompareTypes.add("lte"); lstSupportCompareTypes.add("class"); lstSupportCompareTypes.add("ref"); } private List lstChildExpressions; private List<String> lstChildRelations; public void parsePreConditionExpressionsStart(String reportTypeKey,AbsEditableReportEditDataBean editBean,String expressions,String datasource) { if(expressions==null||expressions.trim().equals("")) return; expressions=expressions.trim(); lstChildExpressions=new ArrayList(); lstChildRelations=new ArrayList<String>(); while(true) { if(expressions.equals("")) break; if(expressions.charAt(0)=='[') { int idx=expressions.indexOf(']'); if(idx<0) { throw new WabacusConfigLoadingException("报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition属性:" +expressions+"不合法,[]没有成对"); } lstChildExpressions.add(createConcreteExpressionBean(reportTypeKey,editBean,expressions.substring(1,idx).trim(),datasource)); expressions=parseExpressionRelation(editBean,expressions.substring(idx+1).trim()); if(Tools.isEmpty(expressions)) break; }else if(expressions.charAt(0)=='(') {//是组合表达式 int leftBracket=1, i=0; for(;i<expressions.length();i++) { if(expressions.charAt(i)==')') { leftBracket--; if(leftBracket==0) break; }else if(expressions.charAt(i)=='(') { leftBracket++; } } if(i==expressions.length()) { throw new WabacusConfigLoadingException("报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition属性:" +expressions+"不合法,()没有成对"); } CompositeExpressionBeanForLoad childCompositeBean=new CompositeExpressionBeanForLoad(); childCompositeBean.parsePreConditionExpressionsStart(reportTypeKey,editBean,expressions.substring(1,i),datasource); lstChildExpressions.add(childCompositeBean); expressions=parseExpressionRelation(editBean,expressions.substring(i+1).trim()); if(Tools.isEmpty(expressions)) break; }else { throw new WabacusConfigLoadingException("报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition属性:"+expressions +"不合法"); } } } private String parseExpressionRelation(AbsEditableReportEditDataBean editBean,String expressions) { if(expressions==null||expressions.trim().length()<3) return null; expressions=expressions.trim(); if(expressions.toLowerCase().startsWith("and")) { lstChildRelations.add("and"); expressions=expressions.substring(3).trim(); }else if(expressions.toLowerCase().startsWith("or")) { lstChildRelations.add("or"); expressions=expressions.substring(2).trim(); }else { throw new WabacusConfigLoadingException("报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition属性:"+expressions +"不合法,相临表达式之间的关系只能是and或or"); } return expressions.trim(); } public AbsExpressionBean parsePreConditionExpressionsEnd() { if(lstChildExpressions==null||lstChildExpressions.size()==0) return null; if(lstChildExpressions.size()==1) {//只有一个子节点,则本层就删掉,直接用子节点 return getExpressionBeanByExpessionObject(lstChildExpressions.get(0)); }else { List<AbsExpressionBean> lstChildExpressionBeans=new ArrayList<AbsExpressionBean>(); String logic=null; if(lstChildRelations.contains("and")&&lstChildRelations.contains("or")) { logic="or"; List<AbsExpressionBean> lstAndChildBeans=new ArrayList<AbsExpressionBean>(); addExpressionBeanToCurrentAndRelation(lstAndChildBeans,0); for(int i=0;i<this.lstChildRelations.size()-1;i++) { if(lstChildRelations.get(i).equals("or")) { addPrevAndChildExpression(lstChildExpressionBeans,lstAndChildBeans); lstAndChildBeans=new ArrayList<AbsExpressionBean>();//重新处理下一个and连接的子表达式 } addExpressionBeanToCurrentAndRelation(lstAndChildBeans,i+1); } addPrevAndChildExpression(lstChildExpressionBeans,lstAndChildBeans); }else { logic=lstChildRelations.get(0); AbsExpressionBean expressBeanTmp; for(Object objTmp:this.lstChildExpressions) { expressBeanTmp=getExpressionBeanByExpessionObject(objTmp); if(expressBeanTmp!=null) lstChildExpressionBeans.add(expressBeanTmp); } } if(lstChildExpressionBeans.size()==0) return null; if(lstChildExpressionBeans.size()==1) return lstChildExpressionBeans.get(0); CompositeExpressionBean cebean=new CompositeExpressionBean(); cebean.setLstChildExpressionBeans(lstChildExpressionBeans); cebean.setLogic(logic); return cebean; } } private AbsExpressionBean getExpressionBeanByExpessionObject(Object expressObj) { if(expressObj==null) return null; if(expressObj instanceof AbsConcreteExpressionBean) return (AbsConcreteExpressionBean)expressObj; return ((CompositeExpressionBeanForLoad)expressObj).parsePreConditionExpressionsEnd(); } private void addExpressionBeanToCurrentAndRelation(List<AbsExpressionBean> lstAndChildBeans,int index) { AbsExpressionBean expressBeanTmp=getExpressionBeanByExpessionObject(lstChildExpressions.get(index)); if(expressBeanTmp!=null) lstAndChildBeans.add(expressBeanTmp); } private void addPrevAndChildExpression(List<AbsExpressionBean> lstChildExpressionBeans,List<AbsExpressionBean> lstAndChildBeans) { if(lstAndChildBeans.size()==1) { lstChildExpressionBeans.add(lstAndChildBeans.get(0)); }else if(lstAndChildBeans.size()>1) { CompositeExpressionBean cebean=new CompositeExpressionBean(); cebean.setLstChildExpressionBeans(lstAndChildBeans); cebean.setLogic("and"); lstChildExpressionBeans.add(cebean); } } private AbsConcreteExpressionBean createConcreteExpressionBean(String reportTypeKey,AbsEditableReportEditDataBean editBean,String expressions,String datasource) { if(Tools.isEmpty(expressions)) return null; expressions=expressions.trim(); List<String> lstExpressParms=Tools.parseStringToList(expressions,",",true); if(lstExpressParms.size()==0) return null; String type=lstExpressParms.get(0).toLowerCase().trim();//比较类型 if(!lstSupportCompareTypes.contains(type)) { throw new WabacusConfigLoadingException("解析报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition中的"+expressions +"表达式失败,不支持比较类型"+type); } AbsConcreteExpressionBean resultExpressionBean; if(type.equals("ref")) {//引用<preconditions/>中定义的<precondition/> if(lstExpressParms.size()<2) { throw new WabacusConfigLoadingException("解析报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition中的" +expressions+"表达式失败,当使用ref引用条件表达式时,必须指定被引用的条件表达式名"); } String refedname=lstExpressParms.get(1); if(Tools.isEmpty(refedname)) { throw new WabacusConfigLoadingException("解析报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition中的" +expressions+"表达式失败,,当使用ref引用条件表达式时,必须指定被引用的条件表达式名"); } if(editBean.getPreconditionExpressionBean(refedname)==null) { throw new WabacusConfigLoadingException("解析报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition中的" +expressions+"表达式失败,,当使用ref引用条件表达式时,必须指定被引用的条件表达式名"+refedname+"不存在,或者被定义在本<precondition/>的后面"); } boolean bolValue=false; if(lstExpressParms.size()>2) { String expressionvalue=lstExpressParms.get(2); expressionvalue=expressionvalue==null?"false":expressionvalue.toLowerCase().trim(); if(!expressionvalue.trim().equals("")&&!expressionvalue.equals("true")&&!expressionvalue.equals("false")) { throw new WabacusConfigLoadingException("解析报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition中的"+expressions +"表达式失败,,当使用ref引用条件表达式时,与被引用的表达式的比较值只能是true或false,不能是其它值"); } bolValue=expressionvalue.equals("true"); } resultExpressionBean=new RefConcreteExpressionBean(); ((RefConcreteExpressionBean)resultExpressionBean).setComparedValue(bolValue); ((RefConcreteExpressionBean)resultExpressionBean).setRefedExpressionBean(editBean.getPreconditionExpressionBean(refedname)); }else if(type.equals("class")) { if(lstExpressParms.size()<2) { throw new WabacusConfigLoadingException("解析报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition中的" +expressions+"表达式失败,当采用自定义JAVA类做为条件表达式时,必须指定JAVA类全限定类名"); } String javaclass=lstExpressParms.get(1); if(Tools.isEmpty(javaclass)) { throw new WabacusConfigLoadingException("解析报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition中的" +expressions+"表达式失败,当采用自定义JAVA类做为条件表达式时,指定JAVA类全限定类名不能为空"); } Object obj=null; try { obj=ConfigLoadManager.currentDynClassLoader.loadClassByCurrentLoader(javaclass.trim()).newInstance(); }catch(Exception e) { throw new WabacusConfigLoadingException("解析报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition中的" +expressions+"表达式失败,当采用自定义JAVA类做为条件表达式时,指定JAVA类全限定类"+javaclass+"无法实例化",e); } if(!(obj instanceof AbsConcreteExpressionBean)) { throw new WabacusConfigLoadingException("解析报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition中的" +expressions+"表达式失败,当采用自定义JAVA类做为条件表达式时,指定JAVA类全限定类"+javaclass+"没有继承框架的父类:"+AbsConcreteExpressionBean.class.getName()); } resultExpressionBean=(AbsConcreteExpressionBean)obj; if(lstExpressParms.size()>2) { List<String> lstParams=new ArrayList<String>(); for(int i=2;i<lstExpressParms.size();i++) { lstParams.add(antiReplaceSpecialWords(lstExpressParms.get(i))); } resultExpressionBean.setLstParams(lstParams); } }else { if(lstExpressParms.size()<3) { throw new WabacusConfigLoadingException("解析报表"+editBean.getOwner().getReportBean().getPath()+"配置的precondition中的" +expressions+"表达式失败,采用内置的比较条件时,必须指定比较参数和被比较参数"); } resultExpressionBean=new DefaultConcreteExpressionBean(); List<String> lstParams=new ArrayList<String>(); for(int i=0;i<lstExpressParms.size();i++) { lstParams.add(antiReplaceSpecialWords(lstExpressParms.get(i))); } resultExpressionBean.setLstParams(lstParams); } resultExpressionBean.setOwnerEditbean(editBean); resultExpressionBean.setReportTypeKey(reportTypeKey); resultExpressionBean.setDatasource(datasource); resultExpressionBean.parseParams(); return resultExpressionBean; } private String antiReplaceSpecialWords(String str) { if(str==null) return null; str=Tools.replaceAll(str,"$_LEFTBRACKET_$","("); str=Tools.replaceAll(str,"$_RIGHTBRACKET_$",")"); str=Tools.replaceAll(str,"$_LEFTBRACKET2_$","["); str=Tools.replaceAll(str,"$_RIGHTBRACKET2_$","]"); str=Tools.replaceAll(str,"$_LEFTBRACKET3_$","{"); str=Tools.replaceAll(str,"$_RIGHTBRACKET3_$","}"); str=Tools.replaceAll(str,"$_COMMA_$",","); return str; } }