com.wabacus.system.assistant.EditableReportAssistant.java Source code

Java tutorial

Introduction

Here is the source code for com.wabacus.system.assistant.EditableReportAssistant.java

Source

/* 
 * 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());//guidguid???
                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);
    }
}