/*
* 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.assistant;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.wabacus.config.Config;
import com.wabacus.config.component.application.report.ColBean;
import com.wabacus.config.component.application.report.ReportBean;
import com.wabacus.exception.WabacusConfigLoadingException;
import com.wabacus.exception.WabacusRuntimeException;
import com.wabacus.exception.WabacusRuntimeTerminateException;
import com.wabacus.system.CacheDataBean;
import com.wabacus.system.ReportRequest;
import com.wabacus.system.buttons.EditableReportSQLButtonDataBean;
import com.wabacus.system.component.application.report.abstractreport.AbsReportType;
import com.wabacus.system.component.application.report.abstractreport.IEditableReportType;
import com.wabacus.system.component.application.report.abstractreport.SaveInfoDataBean;
import com.wabacus.system.component.application.report.configbean.editablereport.AbsEditableReportEditDataBean;
import com.wabacus.system.component.application.report.configbean.editablereport.EditableReportBean;
import com.wabacus.system.component.application.report.configbean.editablereport.EditableReportColBean;
import com.wabacus.system.component.application.report.configbean.editablereport.EditableReportDeleteDataBean;
import com.wabacus.system.component.application.report.configbean.editablereport.EditableReportExternalValueBean;
import com.wabacus.system.component.application.report.configbean.editablereport.EditableReportParamBean;
import com.wabacus.system.component.application.report.configbean.editablereport.EditableReportSecretColValueBean;
import com.wabacus.system.component.application.report.configbean.editablereport.EditableReportSqlBean;
import com.wabacus.system.dataset.update.action.AbsUpdateAction;
import com.wabacus.system.dataset.update.transaction.DefaultTransactionType;
import com.wabacus.system.intercept.AbsPageInterceptor;
import com.wabacus.system.intercept.IInterceptor;
import com.wabacus.util.Consts;
import com.wabacus.util.Consts_Private;
import com.wabacus.util.Tools;
public class EditableReportAssistant
{
private static Log log=LogFactory.getLog(EditableReportAssistant.class);
private final static EditableReportAssistant instance=new EditableReportAssistant();
protected EditableReportAssistant()
{}
public static EditableReportAssistant getInstance()
{
return instance;
}
public String getInputBoxId(ColBean cbean)
{
if(cbean.getProperty()==null||cbean.getProperty().trim().equals("")) return "";
return cbean.getReportBean().getGuid()+"_wxcol_"+cbean.getProperty();
}
public String getInputBoxId(ReportBean rbean,String property)
{
if(property==null||property.trim().equals("")) return "";
return rbean.getGuid()+"_"+property;
}
public String getColParamName(ColBean cbean)
{
return cbean.getProperty();
}
public String getColParamValue(ReportRequest rrequest,Map<String,String> mColParamsValue,ColBean cbean)
{
return getColParamValue(rrequest,cbean.getReportBean(),mColParamsValue,getColParamName(cbean));
}
public String getColParamValue(ReportRequest rrequest,ReportBean rbean,Map<String,String> mColParamsValue,String paramname)
{
if(mColParamsValue==null) return null;
String paramvalue=null;
if(mColParamsValue.containsKey(Consts_Private.COL_NONDISPLAY_PERMISSION_PREX+paramname))
{
EditableReportSecretColValueBean secretColvalueBean=EditableReportSecretColValueBean.loadFromSession(rrequest,rbean);
if(secretColvalueBean==null)
{
rrequest.getWResponse().setStatecode(Consts.STATECODE_FAILED);
rrequest.getWResponse().getMessageCollector().warn("session过期,没有取到保存数据,请刷新后重试",null,true);
}
String colkey=mColParamsValue.get(Consts_Private.COL_NONDISPLAY_PERMISSION_PREX+paramname);
if(colkey==null||colkey.trim().equals("")) return null;
if(!secretColvalueBean.containsColkey(colkey))
{
paramvalue=colkey;
}else
{
paramvalue=secretColvalueBean.getParamValue(colkey);
}
}else
{//直接从客户端
paramvalue=mColParamsValue.get(paramname);
}
return paramvalue;
}
public String getColParamRealValue(ReportRequest rrequest,ReportBean rbean,String paramname,String paramvalue)
{
if(paramname==null||!paramname.startsWith(Consts_Private.COL_NONDISPLAY_PERMISSION_PREX)) return paramvalue;
EditableReportSecretColValueBean secretColvalueBean=EditableReportSecretColValueBean.loadFromSession(rrequest,rbean);
if(secretColvalueBean==null)
{
throw new WabacusRuntimeException("session过期,无法获取到"+paramname+"参数的真正参数值");
}
if(secretColvalueBean.containsColkey(paramvalue))
{
paramvalue=secretColvalueBean.getParamValue(paramvalue);
}
return paramvalue;
}
public boolean isReadonlyAccessMode(IEditableReportType reportTypeObj)
{
ReportBean rbean=((AbsReportType)reportTypeObj).getReportBean();
ReportRequest rrequest=((AbsReportType)reportTypeObj).getReportRequest();
String isReadonlyAccessmode=rrequest.getStringAttribute(rbean.getId()+"_isReadonlyAccessmode","");
if(isReadonlyAccessmode.equals(""))
{
String accessmode=rrequest.getStringAttribute(rbean.getId()+"_ACCESSMODE",reportTypeObj.getDefaultAccessMode()).toLowerCase();
if(accessmode.equals(Consts.READONLY_MODE)||rrequest.checkPermission(rbean.getId(),null,null,"readonly")||rbean.getSbean()==null)
{
isReadonlyAccessmode="true";//当前是以只读模式访问此编辑报表
}else
{
EditableReportSqlBean ersqlbean=(EditableReportSqlBean)rbean.getSbean().getExtendConfigDataForReportType(EditableReportSqlBean.class);
if(ersqlbean==null||(ersqlbean.getDeletebean()==null&&ersqlbean.getInsertbean()==null&&ersqlbean.getUpdatebean()==null))
{
isReadonlyAccessmode="true";
}else
{
isReadonlyAccessmode="false";
}
}
rrequest.setAttribute(rbean.getId()+"_isReadonlyAccessmode",isReadonlyAccessmode);
}
return Boolean.valueOf(isReadonlyAccessmode);
}
public int comareEditableReportSaveOrder(IEditableReportType editableReportObj1,IEditableReportType editableReportObj2)
{
if(editableReportObj1==null&&editableReportObj2==null) return 0;
if(editableReportObj1==null) return -1;
if(editableReportObj2==null) return 1;
int saveorder1=editableReportObj1.getReportRequest().getIntAttribute(editableReportObj1.getReportBean().getId()+"_SAVE_ORDER",0);
int saveorder2=editableReportObj2.getReportRequest().getIntAttribute(editableReportObj2.getReportBean().getId()+"_SAVE_ORDER",0);
if(saveorder1==saveorder2) return 0;
return saveorder1>saveorder2?1:-1;
}
public void doAllReportsSaveAction(ReportRequest rrequest)
{
String flag=rrequest.getStringAttribute("WX_HAS_SAVING_DATA_"+rrequest.getPagebean().getId(),"");
if(flag.equals("true")) return;
rrequest.setAttribute("WX_HAS_SAVING_DATA_"+rrequest.getPagebean().getId(),"true");
Map<Object,Object> mAtts=new HashMap<Object,Object>();
mAtts.putAll(rrequest.getAttributes());
Object objKeyTmp,objValueTmp;
String keyTmp,valueTmp;
List<IEditableReportType> lstSavingReportObjs=new ArrayList<IEditableReportType>();
String reportidTmp;
List<String> lstReportidsTmp=new ArrayList<String>();//存放已经处理过的报表ID,以免重复初始化
for(Entry<Object,Object> entryTmp:mAtts.entrySet())
{
objKeyTmp=entryTmp.getKey();
objValueTmp=entryTmp.getValue();
if(!(objKeyTmp instanceof String)||!(objValueTmp instanceof String)) continue;
keyTmp=(String)objKeyTmp;
if(keyTmp.endsWith("_INSERTDATAS"))
{
reportidTmp=keyTmp.substring(0,keyTmp.length()-"_INSERTDATAS".length());
}else if(keyTmp.endsWith("_UPDATEDATAS"))
{
reportidTmp=keyTmp.substring(0,keyTmp.length()-"_UPDATEDATAS".length());
}else if(keyTmp.endsWith("_DELETEDATAS"))
{
reportidTmp=keyTmp.substring(0,keyTmp.length()-"_DELETEDATAS".length());
}else if(keyTmp.endsWith("_CUSTOMIZEDATAS"))
{
reportidTmp=keyTmp.substring(0,keyTmp.length()-"_CUSTOMIZEDATAS".length());
}else
{
continue;
}
if(reportidTmp.trim().equals("")||lstReportidsTmp.contains(reportidTmp.trim())) continue;
lstReportidsTmp.add(reportidTmp.trim());
ReportBean rbeanTmp=rrequest.getPagebean().getReportChild(reportidTmp,true);
if(rbeanTmp==null) continue;
valueTmp=(String)objValueTmp;
if(valueTmp.trim().equals("")) continue;
Object objTmp=rrequest.getComponentTypeObj(rbeanTmp,null,true);
if(!(objTmp instanceof IEditableReportType)) continue;
if(isReadonlyAccessMode((IEditableReportType)objTmp)) continue;
lstSavingReportObjs.add((IEditableReportType)objTmp);
initEditedParams(rrequest,rbeanTmp);
}
if(lstSavingReportObjs.size()>0)
{
if(lstSavingReportObjs.size()>1) Collections.sort(lstSavingReportObjs);
EditableReportSqlBean ersqlbeanTmp;
ReportBean rbeanTmp;
CacheDataBean cdbTmp;
for(IEditableReportType reportTypeObjTmp:lstSavingReportObjs)
{
rbeanTmp=reportTypeObjTmp.getReportBean();
cdbTmp=rrequest.getCdb(rbeanTmp.getId());
ersqlbeanTmp=(EditableReportSqlBean)rbeanTmp.getSbean().getExtendConfigDataForReportType(EditableReportSqlBean.class);
initEditExternalValues(rrequest,ersqlbeanTmp.getInsertbean(),cdbTmp,ersqlbeanTmp);
initEditExternalValues(rrequest,ersqlbeanTmp.getUpdatebean(),cdbTmp,ersqlbeanTmp);
initEditExternalValues(rrequest,ersqlbeanTmp.getDeletebean(),cdbTmp,ersqlbeanTmp);
}
rrequest.removeAttribute(rrequest.getPagebean().getId()+"_ALL_EDITPARAM_VALUES");//清除掉缓存中所有变量的值
doSaveAction(rrequest,lstSavingReportObjs);
}
}
private void initEditExternalValues(ReportRequest rrequest,AbsEditableReportEditDataBean editbean,CacheDataBean cdb,
EditableReportSqlBean ersqlbean)
{
if(editbean==null) return;
List<Map<String,String>> lstEditColDataTmp=cdb.getLstEditedData(editbean);
if(lstEditColDataTmp==null||lstEditColDataTmp.size()==0) return;
cdb.setLstEditedParamValues(editbean,getExternalValues(editbean,lstEditColDataTmp,rrequest));
}
private void initEditedParams(ReportRequest rrequest,ReportBean reportbean)
{
EditableReportSqlBean ersqlbean=(EditableReportSqlBean)reportbean.getSbean().getExtendConfigDataForReportType(EditableReportSqlBean.class);
CacheDataBean cdb=rrequest.getCdb(reportbean.getId());
boolean[] shouldDoSave=new boolean[4];
SaveInfoDataBean sidbean=new SaveInfoDataBean();
sidbean.setShouldDoSave(shouldDoSave);
List<Map<String,String>> lstParamsValue=parseSaveDataStringToList(rrequest.getStringAttribute(reportbean.getId()+"_CUSTOMIZEDATAS",""));
if(lstParamsValue!=null&&lstParamsValue.size()>0)
{
Map<String,String> mCustomizeData=lstParamsValue.get(0);
cdb.getAttributes().put("WX_UPDATE_CUSTOMIZEDATAS",mCustomizeData);
shouldDoSave[3]=true;
if(mCustomizeData!=null&&mCustomizeData.containsKey("WX_UPDATETYPE"))
{
sidbean.setUpdatetype(mCustomizeData.get("WX_UPDATETYPE"));
}else
{
sidbean.setUpdatetype("");
}
}else
{
shouldDoSave[3]=false;
}
shouldDoSave[0]=initEditedParams(rrequest.getStringAttribute(reportbean.getId()+"_INSERTDATAS",""),rrequest,reportbean,ersqlbean
.getInsertbean());//初始化传过来的添加数据列表
shouldDoSave[1]=initEditedParams(rrequest.getStringAttribute(reportbean.getId()+"_UPDATEDATAS",""),rrequest,reportbean,ersqlbean
.getUpdatebean());
shouldDoSave[2]=initEditedParams(rrequest.getStringAttribute(reportbean.getId()+"_DELETEDATAS",""),rrequest,reportbean,ersqlbean
.getDeletebean());
rrequest.setAttribute(reportbean.getId(),"SAVEINFO_DATABEAN",sidbean);
}
private boolean initEditedParams(String strParams,ReportRequest rrequest,ReportBean reportbean,AbsEditableReportEditDataBean editbean)
{
if(strParams.equals("")||editbean==null) return false;
log.debug(strParams);
List<Map<String,String>> lstParamsValue=parseSaveDataStringToList(strParams);
if(lstParamsValue==null||lstParamsValue.size()==0) return false;
CacheDataBean cdb=rrequest.getCdb(reportbean.getId());
cdb.setLstEditedData(editbean,lstParamsValue);
if(!(editbean instanceof EditableReportDeleteDataBean))
{
List<ColBean> lstCBeans=reportbean.getDbean().getLstCols();
EditableReportColBean ecbeanTmp;
for(Map<String,String> mParamValuesTmp:lstParamsValue)
{
for(ColBean cbTmp:lstCBeans)
{
ecbeanTmp=(EditableReportColBean)cbTmp.getExtendConfigDataForReportType(EditableReportColBean.class);
if(ecbeanTmp!=null&&ecbeanTmp.getServerValidateBean()!=null)
{//依次对每个配置了服务器端校验的列进行服务器端校验
ColBean cbDest=cbTmp.getUpdateColBeanDest(false);
if(cbDest==null) cbDest=cbTmp;
if(!ecbeanTmp.getServerValidateBean().validate(rrequest,mParamValuesTmp.get(cbDest.getProperty()),mParamValuesTmp,
new ArrayList<String>(),null)) return false;
}
}
}
}
return true;
}
public List<Map<String,String>> parseSaveDataStringToList(String strSavedata)
{
if(strSavedata==null||strSavedata.trim().equals("")) return null;
List<String> lstRowDatas=Tools.parseStringToList(strSavedata.trim(),Consts_Private.SAVE_ROWDATA_SEPERATOR,false);
List<Map<String,String>> lstResults=new ArrayList<Map<String,String>>();
for(String rowdataTmp:lstRowDatas)
{
if(rowdataTmp==null||rowdataTmp.trim().equals("")) continue;
Map<String,String> mRowData=new HashMap<String,String>();
List<String> lstColsData=Tools.parseStringToList(rowdataTmp,Consts_Private.SAVE_COLDATA_SEPERATOR,false);
String colnameTmp;
String colvalueTmp;
for(String coldataTmp:lstColsData)
{
if(coldataTmp==null||coldataTmp.trim().equals("")) continue;
int idx=coldataTmp.indexOf(Consts_Private.SAVE_NAMEVALUE_SEPERATOR);
if(idx<=0) continue;
colnameTmp=coldataTmp.substring(0,idx).trim();
colvalueTmp=coldataTmp.substring(idx+Consts_Private.SAVE_NAMEVALUE_SEPERATOR.length());
if(colnameTmp.equals("")) continue;
if("[W-X-N-U-L-L]".equals(colvalueTmp)) colvalueTmp=null;
mRowData.put(colnameTmp,colvalueTmp);
}
if(mRowData.size()>0) lstResults.add(mRowData);
}
return lstResults;
}
private void doSaveAction(ReportRequest rrequest,List<IEditableReportType> lstSavingReportObjs)
{
if(lstSavingReportObjs==null||lstSavingReportObjs.size()==0) return;
rrequest.setTransactionObj(new DefaultTransactionType());
List<ReportBean> lstSaveReportBeans=new ArrayList<ReportBean>();
for(IEditableReportType reportTypeObjTmp:lstSavingReportObjs)
{
lstSaveReportBeans.add(reportTypeObjTmp.getReportBean());
}
List<AbsPageInterceptor> lstPageInterceptors=rrequest.getLstPageInterceptors();
if(lstPageInterceptors!=null&&lstPageInterceptors.size()>0)
{//页面拦截器
for(AbsPageInterceptor pageInterceptorObjTmp:lstPageInterceptors)
{
pageInterceptorObjTmp.doStartSave(rrequest,lstSaveReportBeans);
}
}
List<AbsUpdateAction> lstAllUpdateActions=new ArrayList<AbsUpdateAction>();
for(IEditableReportType reportTypeObjTmp:lstSavingReportObjs)
{
reportTypeObjTmp.collectEditActionGroupBeans(lstAllUpdateActions);
}
if(rrequest.getTransactionWrapper()!=null) rrequest.getTransactionWrapper().beginTransaction(rrequest,lstAllUpdateActions);
boolean hasInsertData=false,hasUpdateData=false,hasDeleteData=false;
boolean isFailed=false,hasSaveReport=false;
boolean shouldStopRefreshDisplay=false;
int[] resultTmp=null;
try
{
ReportBean rbeanTmp;
for(IEditableReportType reportTypeObjTmp:lstSavingReportObjs)
{//依次保存所有报表数据
rbeanTmp=((AbsReportType)reportTypeObjTmp).getReportBean();
resultTmp=reportTypeObjTmp.doSaveAction();
if(resultTmp==null||resultTmp.length!=2||resultTmp[0]==IInterceptor.WX_RETURNVAL_SKIP) continue;
if(resultTmp[0]==IInterceptor.WX_RETURNVAL_TERMINATE)
{
rrequest.getTransactionWrapper().rollbackTransaction(rrequest,lstAllUpdateActions);
rrequest.getWResponse().terminateResponse(Consts.STATECODE_FAILED);
return;
}
rrequest.getWResponse().addUpdateReportGuid(rbeanTmp.getGuid());//将此报表的guid加到本次更新的报表guid列表中(因为加的过程中会判断重复,所以这里不用判断)
if(resultTmp[0]==IInterceptor.WX_RETURNVAL_SUCCESS_NOTREFRESH) shouldStopRefreshDisplay=true;
if(resultTmp[1]==IEditableReportType.IS_ADD_DATA)
{
hasInsertData=true;
}else if(resultTmp[1]==IEditableReportType.IS_UPDATE_DATA)
{
hasUpdateData=true;
}else if(resultTmp[1]==IEditableReportType.IS_ADD_UPDATE_DATA)
{
hasInsertData=true;
hasUpdateData=true;
}else if(resultTmp[1]==IEditableReportType.IS_DELETE_DATA)
{
hasDeleteData=true;
}
hasSaveReport=true;
}
if(lstPageInterceptors!=null&&lstPageInterceptors.size()>0)
{
AbsPageInterceptor pageInterceptorObjTmp;
for(int i=lstPageInterceptors.size()-1;i>=0;i--)
{
pageInterceptorObjTmp=lstPageInterceptors.get(i);
pageInterceptorObjTmp.doEndSave(rrequest,lstSaveReportBeans);
}
}
if(rrequest.getTransactionWrapper()!=null) rrequest.getTransactionWrapper().commitTransaction(rrequest,lstAllUpdateActions);
}catch(WabacusRuntimeTerminateException wrwe)
{
if(rrequest.getTransactionWrapper()!=null)
{
if(rrequest.getWResponse().getStatecode()!=Consts.STATECODE_FAILED)
{
rrequest.getTransactionWrapper().commitTransaction(rrequest,lstAllUpdateActions);
}else
{
rrequest.getTransactionWrapper().rollbackTransaction(rrequest,lstAllUpdateActions);
}
}
throw new WabacusRuntimeTerminateException();
}catch(Exception e)
{
isFailed=true;
if(rrequest.getTransactionWrapper()!=null) rrequest.getTransactionWrapper().rollbackTransaction(rrequest,lstAllUpdateActions);
log.error("保存页面"+rrequest.getPagebean().getId()+"上的报表数据失败",e);
if(resultTmp!=null&&resultTmp.length==2)
{//保存时抛出异常时,没有执行上面的为hasInsertData,hasUpdateData,hasDeleteData的赋值操作,所以在这里赋值
if(resultTmp[1]==1)
{
hasInsertData=true;
}else if(resultTmp[1]==2)
{
hasUpdateData=true;
}else if(resultTmp[1]==3)
{
hasInsertData=true;
hasUpdateData=true;
}else if(resultTmp[1]==4)
{
hasDeleteData=true;
}
}
if(!rrequest.isDisableAutoFailedPrompt()) promptFailedMessage(rrequest,hasInsertData,hasUpdateData,hasDeleteData);
}finally
{
rrequest.setTransactionObj(null);
}
if(hasSaveReport&&!isFailed)
{
if(!rrequest.isDisableAutoSuccessPrompt())
{
promptSuccessMessage(rrequest,hasInsertData,hasUpdateData,hasDeleteData);
}
if(shouldStopRefreshDisplay)
{
rrequest.getWResponse().terminateResponse(Consts.STATECODE_NONREFRESHPAGE);
}
}else if(!hasSaveReport)
{
rrequest.getWResponse().getMessageCollector().warn(
rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${save.nodata.prompt}",
false)));
}
}
private void promptFailedMessage(ReportRequest rrequest,boolean hasInsertData,boolean hasUpdateData,boolean hasDeleteData)
{
String errorprompt=null;
if((hasInsertData&&hasDeleteData)||(hasUpdateData&&hasDeleteData))
{
errorprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${operate.failed.prompt}",false));
}else if(hasInsertData&&hasUpdateData)
{//同时有增、改操作,即保存操作
errorprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${save.failed.prompt}",false));
}else if(hasInsertData)
{
errorprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${insert.failed.prompt}",false));
}else if(hasUpdateData)
{
errorprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${update.failed.prompt}",false));
}else if(hasDeleteData)
{
errorprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${delete.failed.prompt}",false));
}else
{
errorprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${operate.failed.prompt}",false));
}
rrequest.getWResponse().getMessageCollector().error(errorprompt,null,true);
}
private void promptSuccessMessage(ReportRequest rrequest,boolean hasInsertData,boolean hasUpdateData,boolean hasDeleteData)
{
String successprompt=null;
if((hasInsertData&&hasDeleteData)||(hasUpdateData&&hasDeleteData))
{
successprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${operate.success.prompt}",false));
}else if(hasInsertData&&hasUpdateData)
{//同时有增、改操作,即保存操作
successprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${save.success.prompt}",false));
}else if(hasInsertData)
{
successprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${insert.success.prompt}",false));
}else if(hasUpdateData)
{
successprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${update.success.prompt}",false));
}else if(hasDeleteData)
{
successprompt=rrequest.getI18NStringValue(Config.getInstance().getResourceString(rrequest,rrequest.getPagebean(),"${delete.success.prompt}",false));
}else
{
return;
}
rrequest.getWResponse().getMessageCollector().success(successprompt);
}
public int processAfterSaveAction(ReportRequest rrequest,ReportBean rbean,String updatetype,int originalRtnVal)
{
EditableReportSqlBean ersqlbean=(EditableReportSqlBean)rbean.getSbean().getExtendConfigDataForReportType(EditableReportSqlBean.class);
if(ersqlbean.getAfterSaveAction()!=null&&ersqlbean.getAfterSaveAction().length>0)
{
String afterSaveActionMethod=ersqlbean.getAfterSaveActionMethod();
if(!afterSaveActionMethod.equals(""))
{
StringBuffer paramsBuf=new StringBuffer();
paramsBuf.append("{pageid:\""+rbean.getPageBean().getId()+"\"");
paramsBuf.append(",reportid:\""+rbean.getId()+"\"");
paramsBuf.append(",updatetype:\""+updatetype+"\"}");
rrequest.getWResponse().addOnloadMethod(afterSaveActionMethod,paramsBuf.toString(),true);
}
if(ersqlbean.getAfterSaveAction().length==2&&"true".equals(ersqlbean.getAfterSaveAction()[1]))
{
return IInterceptor.WX_RETURNVAL_SUCCESS_NOTREFRESH;//中断报表数据的加载,则中断报表的后续显示
}
}
return originalRtnVal;
}
public String getEditableMetaData(IEditableReportType editableReportTypeObj)
{
ReportBean rbean=((AbsReportType)editableReportTypeObj).getReportBean();
StringBuilder resultBuf=new StringBuilder();
if(EditableReportAssistant.getInstance().isReadonlyAccessMode(editableReportTypeObj))
{
resultBuf.append(" current_accessmode=\"").append(Consts.READONLY_MODE).append("\"");
}else
{
resultBuf.append(" current_accessmode=\"").append(editableReportTypeObj.getRealAccessMode()).append("\"");
EditableReportSqlBean ersqlbean=(EditableReportSqlBean)rbean.getSbean().getExtendConfigDataForReportType(EditableReportSqlBean.class);
if(ersqlbean.getBeforeSaveAction()!=null&&!ersqlbean.getBeforeSaveAction().trim().equals(""))
{
resultBuf.append(" beforeSaveAction=\"{method:").append(ersqlbean.getBeforeSaveAction()).append("}\"");
}
if(ersqlbean.getDeletebean()!=null)
{
ReportRequest rrequest=((AbsReportType)editableReportTypeObj).getReportRequest();
String deleteconfirmmess=ersqlbean.getDeletebean().getDeleteConfirmMessage(rrequest);
if(deleteconfirmmess==null||deleteconfirmmess.trim().equals(""))
{
deleteconfirmmess=Config.getInstance().getResourceString(null,null,"${delete.confirm.prompt}",true);
}
if(deleteconfirmmess!=null&&!deleteconfirmmess.trim().equals(""))
{
resultBuf.append(" deleteconfirmmessage=\"").append(rrequest.getI18NStringValue(deleteconfirmmess)).append("\"");
}
}
if(rbean.getDependParentId()!=null&&!rbean.getDependParentId().trim().equals(""))
{
if(ersqlbean.getInsertbean()!=null) addRefreshParentProperty(resultBuf,rbean,ersqlbean.getInsertbean(),"OnInsert");
if(ersqlbean.getUpdatebean()!=null) addRefreshParentProperty(resultBuf,rbean,ersqlbean.getUpdatebean(),"OnUpdate");//修改时需要刷新主报表
if(ersqlbean.getDeletebean()!=null) addRefreshParentProperty(resultBuf,rbean,ersqlbean.getDeletebean(),"OnDelete");
}
EditableReportBean erbean=(EditableReportBean)rbean.getExtendConfigDataForReportType(EditableReportBean.class);
resultBuf.append(" checkdirtydata=\"").append(erbean==null||erbean.isCheckdirtydata()).append("\"");
resultBuf.append(" savedatatype=\"").append(
(erbean==null||erbean.getSavedatatype()==null||erbean.getSavedatatype().trim().equals(""))?"":erbean.getSavedatatype()
.toLowerCase().trim()).append("\"");
}
EditableReportColBean ercbeanTmp;
for(ColBean cbeanTmp:rbean.getDbean().getLstCols())
{
if(cbeanTmp.isControlCol()) continue;
ercbeanTmp=(EditableReportColBean)cbeanTmp.getExtendConfigDataForReportType(EditableReportColBean.class);
if(ercbeanTmp==null) continue;
if(!Tools.isEmpty(ercbeanTmp.getOngetvalueMethod()))
{
resultBuf.append(" "+cbeanTmp.getProperty()+"_ongetvaluemethods=\"{methods:"+ercbeanTmp.getOngetvalueMethod()+"}\"");
}
if(!Tools.isEmpty(ercbeanTmp.getOnsetvalueMethod()))
{
resultBuf.append(" "+cbeanTmp.getProperty()+"_onsetvaluemethods=\"{methods:"+ercbeanTmp.getOnsetvalueMethod()+"}\"");
}
}
return resultBuf.toString();
}
private void addRefreshParentProperty(StringBuilder resultBuf,ReportBean rbean,AbsEditableReportEditDataBean editBean,String propertySuffix)
{
String refreshedParentid=editBean.getRefreshParentidOnSave();
if(refreshedParentid==null||refreshedParentid.trim().equals("")) return;
ReportBean rbeanMaster=rbean.getPageBean().getReportChild(refreshedParentid,true);
if(rbeanMaster==null)
{
throw new WabacusRuntimeException("ID为"+refreshedParentid+"的报表不存在");
}
if(!rbean.isMasterReportOfMe(rbeanMaster,true))
{
throw new WabacusRuntimeException("显示报表"+rbean.getPath()+"失败,ID为"+refreshedParentid+"的报表不是ID为"+rbean.getId()+"报表的主报表");
}
resultBuf.append(" refreshParentReportid"+propertySuffix+"=\"").append(refreshedParentid).append("\"");
resultBuf.append(" refreshParentReportType"+propertySuffix+"=\"").append(editBean.isResetNavigateInfoOnRefreshParent()).append("\"");
}
public int doSaveReport(ReportRequest rrequest,ReportBean rbean,AbsEditableReportEditDataBean editbean)
{
CacheDataBean cdb=rrequest.getCdb(rbean.getId());
List<Map<String,String>> lstRowData=cdb.getLstEditedData(editbean);
List<Map<String,String>> lstParamValues=cdb.getLstEditedParamValues(editbean);
Map<String,String> mRowData, mParamValues;//分别存放要操作的各列数据以及<params/>中定义的变量的数据
boolean hasSaveData=false, hasNonRefreshReport=false;
if(lstRowData==null||lstRowData.size()==0)
{
if(editbean instanceof EditableReportSQLButtonDataBean)
{//如果是直接配置更新脚本的<button/>
EditableReportSQLButtonDataBean buttonEditBean=(EditableReportSQLButtonDataBean)editbean;
if(!buttonEditBean.isAutoReportdata()&&!buttonEditBean.isHasReportDataParams())
{//如果这个<button/>不是自动取报表数据,且所有更新脚本不需要取@{param}的数据进行操作,则即使没有记录也要执行,所以如果有参数的话也要初始化参数
mParamValues=lstParamValues!=null&&lstParamValues.size()>0?lstParamValues.get(0):null;
int rtnVal;
if(rbean.getInterceptor()!=null)
{
rtnVal=rbean.getInterceptor().doSavePerRow(rrequest,rbean,null,mParamValues,editbean);
}else
{
rtnVal=doSaveRow(rrequest,rbean,null,mParamValues,editbean);
}
if(rtnVal==IInterceptor.WX_RETURNVAL_TERMINATE||rtnVal==IInterceptor.WX_RETURNVAL_SKIP) return rtnVal;
hasSaveData=true;
if(rtnVal==IInterceptor.WX_RETURNVAL_SUCCESS_NOTREFRESH) hasNonRefreshReport=true;
}
}
}else
{
for(int i=0;i<lstRowData.size();i++)
{
mRowData=lstRowData.get(i);
mParamValues=lstParamValues!=null&&lstParamValues.size()>i?lstParamValues.get(i):null;
rrequest.setAttribute(rbean.getId(),"update_datarow_index",String.valueOf(i));
int rtnVal;
if(rbean.getInterceptor()!=null)
{
rtnVal=rbean.getInterceptor().doSavePerRow(rrequest,rbean,mRowData,mParamValues,editbean);
}else
{
rtnVal=doSaveRow(rrequest,rbean,mRowData,mParamValues,editbean);
}
if(rtnVal==IInterceptor.WX_RETURNVAL_TERMINATE) return rtnVal;
if(rtnVal==IInterceptor.WX_RETURNVAL_SKIP) continue;
hasSaveData=true;
if(rtnVal==IInterceptor.WX_RETURNVAL_SUCCESS_NOTREFRESH) hasNonRefreshReport=true;
}
}
if(!hasSaveData) return IInterceptor.WX_RETURNVAL_SKIP;
if(hasNonRefreshReport) return IInterceptor.WX_RETURNVAL_SUCCESS_NOTREFRESH;
return IInterceptor.WX_RETURNVAL_SUCCESS;
}
public int doSaveRow(ReportRequest rrequest,ReportBean rbean,Map<String,String> mRowData,Map<String,String> mParamValues,
AbsEditableReportEditDataBean editbean)
{
List<AbsUpdateAction> lstAllExecuteEditActions=editbean.getLstAllExecuteEditActions(rrequest,mRowData,mParamValues);
if(lstAllExecuteEditActions==null||lstAllExecuteEditActions.size()==0) return IInterceptor.WX_RETURNVAL_SKIP;//没有要执行的保存动作
boolean hasSaveData=false, hasNonRefreshReport=false;
for(AbsUpdateAction actionTmp:lstAllExecuteEditActions)
{
int rtnVal;
if(rbean.getInterceptor()!=null)
{
rtnVal=rbean.getInterceptor().doSavePerAction(rrequest,rbean,mRowData,mParamValues,actionTmp,editbean);
}else
{
rtnVal=doSavePerAction(rrequest,rbean,mRowData,mParamValues,actionTmp,editbean);
}
if(rtnVal==IInterceptor.WX_RETURNVAL_TERMINATE) return rtnVal;
if(rtnVal==IInterceptor.WX_RETURNVAL_SKIP) continue;
hasSaveData=true;
if(rtnVal==IInterceptor.WX_RETURNVAL_SUCCESS_NOTREFRESH) hasNonRefreshReport=true;
}
if(!hasSaveData) return IInterceptor.WX_RETURNVAL_SKIP;
if(hasNonRefreshReport) return IInterceptor.WX_RETURNVAL_SUCCESS_NOTREFRESH;
return IInterceptor.WX_RETURNVAL_SUCCESS;
}
public int doSavePerAction(ReportRequest rrequest,ReportBean rbean,Map<String,String> mRowData,Map<String,String> mParamValues,
AbsUpdateAction action,AbsEditableReportEditDataBean editbean)
{
try
{
action.updateData(rrequest,mRowData,mParamValues);
}catch(SQLException e)
{
throw new WabacusRuntimeException("保存报表"+rbean.getPath()+"数据失败",e);
}
return IInterceptor.WX_RETURNVAL_SUCCESS;
}
public List<Map<String,String>> getExternalValues(AbsEditableReportEditDataBean editbean,List<Map<String,String>> lstColParamsValue,ReportRequest rrequest)
{
if(editbean.getLstExternalValues()==null||editbean.getLstExternalValues().size()==0) return null;
List<Map<String,String>> lstExternalValues=new ArrayList<Map<String,String>>();
if(lstColParamsValue==null||lstColParamsValue.size()==0)
{
if(editbean instanceof EditableReportSQLButtonDataBean)
{//如果是直接配置更新脚本的<button/>
EditableReportSQLButtonDataBean buttonEditBean=(EditableReportSQLButtonDataBean)editbean;
if(!buttonEditBean.isAutoReportdata()&&!buttonEditBean.isHasReportDataParams())
{//如果这个<button/>不是自动取报表数据,且所有脚本不需要取@{param}的数据进行操作,则即使没有记录也要执行,所以如果有参数的话也要初始化参数
lstExternalValues.add(initParamValuesForOneRowData(editbean,rrequest,null,0));
}
}
}else
{
int i=0;
for(Map<String,String> mRowDataTmp:lstColParamsValue)
{//保存的每一条记录都要计算一次与它相应的所有在<params/>中定义的参数值
lstExternalValues.add(initParamValuesForOneRowData(editbean,rrequest,mRowDataTmp,i++));
}
}
return lstExternalValues.size()==0?null:lstExternalValues;
}
private Map<String,String> initParamValuesForOneRowData(AbsEditableReportEditDataBean editbean,ReportRequest rrequest,Map<String,String> mRowData,int rowidx)
{
Map<String,String> mExternalValue=new HashMap<String,String>();
Map<String,String> mCustomizedValues=rrequest.getMCustomizeEditData(editbean.getOwner().getReportBean());//用户传过来的自定义保存数据
Map<String,String> mAllParamValues=(Map<String,String>)rrequest.getAttribute(rrequest.getPagebean().getId()+"_ALL_EDITPARAM_VALUES");
if(mAllParamValues==null)
{
mAllParamValues=new HashMap<String,String>();
rrequest.setAttribute(rrequest.getPagebean().getId()+"_ALL_EDITPARAM_VALUES",mAllParamValues);
}
String valueTmp;
for(EditableReportExternalValueBean paramBeanTmp:editbean.getLstExternalValues())
{
valueTmp=mAllParamValues.get(paramBeanTmp.getObjectId()+"_"+rowidx);
if(valueTmp==null||valueTmp.equals(""))
{
valueTmp=paramBeanTmp.getParamValue(rrequest,mRowData,mCustomizedValues,mExternalValue);
mAllParamValues.put(paramBeanTmp.getObjectId()+"_"+rowidx,valueTmp);
}
mExternalValue.put(paramBeanTmp.getName(),valueTmp);
}
return mExternalValue;
}
public String getParamValueOfOneRowData(AbsEditableReportEditDataBean editbean,EditableReportExternalValueBean paramBean,ReportRequest rrequest,
int rowidx)
{
Map<String,String> mAllParamValues=(Map<String,String>)rrequest.getAttribute(rrequest.getPagebean().getId()+"_ALL_EDITPARAM_VALUES");
if(mAllParamValues==null)
{
mAllParamValues=new HashMap<String,String>();
rrequest.setAttribute(rrequest.getPagebean().getId()+"_ALL_EDITPARAM_VALUES",mAllParamValues);
}
String valueTmp=mAllParamValues.get(paramBean.getObjectId()+"_"+rowidx);
if(valueTmp==null||valueTmp.equals(""))
{
List<Map<String,String>> lstAllRowsData=rrequest.getCdb(editbean.getOwner().getReportBean().getId()).getLstEditedData(editbean);
valueTmp=paramBean.getParamValue(rrequest,lstAllRowsData!=null&&lstAllRowsData.size()>0?lstAllRowsData.get(0):null,rrequest
.getMCustomizeEditData(editbean.getOwner().getReportBean()),null);
mAllParamValues.put(paramBean.getObjectId()+"_"+rowidx,valueTmp);
}
return valueTmp;
}
public String parseStandardEditSql(ReportBean rbean,String sql,List<EditableReportParamBean> lstDynParams,boolean isPreparedstatement,
boolean includeQuote)
{
if(sql==null||sql.trim().equals("")) return "";
sql=sql.trim();
if(!includeQuote)
{
sql=Tools.replaceCharacterInQuote(sql,'{',"$_LEFTBRACKET_$",true);
sql=Tools.replaceCharacterInQuote(sql,'}',"$_RIGHTBRACKET_$",true);
}
Map<String,EditableReportParamBean> mDynParamsAndPlaceHolder=new HashMap<String,EditableReportParamBean>();//存放每个动态参数对象及其对应的占位符,其中占位符为键
sql=parseCertainTypeDynParamsInStandardSql(rbean,sql,mDynParamsAndPlaceHolder,"url",isPreparedstatement);
sql=parseCertainTypeDynParamsInStandardSql(rbean,sql,mDynParamsAndPlaceHolder,"request",isPreparedstatement);
sql=parseCertainTypeDynParamsInStandardSql(rbean,sql,mDynParamsAndPlaceHolder,"session",isPreparedstatement);
sql=parseCertainTypeDynParamsInStandardSql(rbean,sql,mDynParamsAndPlaceHolder,"@",isPreparedstatement);
sql=parseCertainTypeDynParamsInStandardSql(rbean,sql,mDynParamsAndPlaceHolder,"!",isPreparedstatement);//解析条件子句中的!{...}动态参数
sql=parseCertainTypeDynParamsInStandardSql(rbean,sql,mDynParamsAndPlaceHolder,"#",isPreparedstatement);
if(isPreparedstatement)
{
sql=convertPlaceHolderToRealParams(sql,mDynParamsAndPlaceHolder,lstDynParams);
}else
{
for(Entry<String,EditableReportParamBean> entryTmp:mDynParamsAndPlaceHolder.entrySet())
{
entryTmp.getValue().setPlaceholder(entryTmp.getKey());//设置此参数对应的占位符
lstDynParams.add(entryTmp.getValue());
}
}
if(!includeQuote)
{
sql=Tools.replaceAll(sql,"$_LEFTBRACKET_$","{");
sql=Tools.replaceAll(sql,"$_RIGHTBRACKET_$","}");
}
return sql;
}
private String parseCertainTypeDynParamsInStandardSql(ReportBean rbean,String sql,Map<String,EditableReportParamBean> mDynParamsAndPlaceHolder,
String paramtype,boolean isPreparedstatement)
{
String strStart,strDynValue,strEnd,placeHolderTmp;
EditableReportParamBean paramBeanTmp;
int placeholderIdxTmp=10000;
int idx=sql.indexOf(paramtype+"{");
while(idx>=0)
{
strStart=sql.substring(0,idx).trim();
strEnd=sql.substring(idx);
idx=strEnd.indexOf("}");
if(idx<0)
{
throw new WabacusConfigLoadingException("加载组件"+rbean.getPath()+"下的SQL语句"+sql+"失败,其中动态参数没有闭合的}");
}
strDynValue=strEnd.substring(0,idx+1);
strEnd=strEnd.substring(idx+1).trim();//存放type{...}后面的部分
paramBeanTmp=new EditableReportParamBean();
paramBeanTmp.setParamname(strDynValue);
if("url".equals(paramtype)) rbean.addParamNameFromURL(Tools.getRealKeyByDefine("url",strDynValue));
if(isPreparedstatement)
{
if((strStart.endsWith("%")&&strStart.substring(0,strStart.length()-1).trim().toLowerCase().endsWith(" like"))
||strStart.toLowerCase().endsWith(" like"))
{
if(strStart.endsWith("%"))
{
strStart=strStart.substring(0,strStart.length()-1);
paramBeanTmp.setHasLeftPercent(true);
}
if(strEnd.startsWith("%"))
{
strEnd=strEnd.substring(1);
paramBeanTmp.setHasRightPercent(true);
}
}
}
placeHolderTmp="[PLACE_HOLDER_"+paramtype+"_"+placeholderIdxTmp+"]";
mDynParamsAndPlaceHolder.put(placeHolderTmp,paramBeanTmp);
sql=strStart+placeHolderTmp+strEnd;
idx=sql.indexOf(paramtype+"{");
placeholderIdxTmp++;
}
return sql;
}
private String convertPlaceHolderToRealParams(String sql,Map<String,EditableReportParamBean> mDynParamsAndPlaceHolder,
List<EditableReportParamBean> lstDynParams)
{
if(mDynParamsAndPlaceHolder==null||mDynParamsAndPlaceHolder.size()==0) return sql;
int idxPlaceHolderStart=sql.indexOf("[PLACE_HOLDER_");
String strStart=null;
String strEnd=null;
String placeHolderTmp;
while(idxPlaceHolderStart>=0)
{
strStart=sql.substring(0,idxPlaceHolderStart);//占位符前面部分
strEnd=sql.substring(idxPlaceHolderStart);
int idxPlaceHolderEnd=strEnd.indexOf("]");
placeHolderTmp=strEnd.substring(0,idxPlaceHolderEnd+1);
strEnd=strEnd.substring(idxPlaceHolderEnd+1);
lstDynParams.add(mDynParamsAndPlaceHolder.get(placeHolderTmp));
sql=strStart+" ? "+strEnd;
idxPlaceHolderStart=sql.indexOf("[PLACE_HOLDER_");
}
return sql;
}
private Map<String,Long> mAllAutoIncrementIdValues=new HashMap<String,Long>();
public synchronized String getAutoIncrementIdValue(ReportRequest rrequest,ReportBean rbean,String datasource,String paramname)
{
if(paramname==null||paramname.trim().equals("")) return "-1";
if(datasource==null) datasource="";
String key=datasource+"__"+paramname;
Long lid=mAllAutoIncrementIdValues.get(key);
if(lid==null||lid.longValue()<0)
{
String realparamname=Tools.getRealKeyByDefine("increment",paramname);
int idx=realparamname.indexOf(".");
if(idx<0)
{
throw new WabacusRuntimeException("为报表"+rbean.getPath()+"配置的自动增长字段"+paramname+"不合法,没有指定表名和自动增长字段名,并用.分隔");
}
String tablename=realparamname.substring(0,idx).trim();
String columnname=realparamname.substring(idx+1).trim();
if(tablename.trim().equals("")||columnname.trim().equals(""))
{
throw new WabacusRuntimeException("为报表"+rbean.getPath()+"配置的自动增长字段"+paramname+"不合法,没有指定表名或自动增长字段名");
}
String sid="-1";
Connection conn=rrequest.getConnection(datasource);
Statement stmt=null;
ResultSet rs=null;
String sql="select max("+columnname+") from "+tablename;
try
{
stmt=conn.createStatement();
rs=stmt.executeQuery(sql);
if(rs.next())
{
sid=rs.getString(1);
}
}catch(SQLException e)
{
throw new WabacusRuntimeException("获取报表"+rbean.getPath()+"配置的自动增长字段"+realparamname+"失败",e);
}finally
{
try
{
if(rs!=null) rs.close();
}catch(SQLException e)
{
e.printStackTrace();
}
WabacusAssistant.getInstance().release(null,stmt);
}
lid=Long.valueOf(sid);
}
mAllAutoIncrementIdValues.put(key,++lid);
return String.valueOf(lid);
}
}