package com.kingdee.eas.custom.messageWebService;

import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
import com.kingdee.bos.metadata.IMetaDataLoader;
import com.kingdee.bos.metadata.MetaDataLoaderFactory;
import com.kingdee.bos.metadata.entity.EntityObjectInfo;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.bos.workflow.metas.AssignFactory;
import com.kingdee.bos.workflow.metas.AssignInfo;
import com.kingdee.bos.workflow.metas.IAssign;
import com.kingdee.bos.workflow.metas.WfAssignmentState;
import com.kingdee.eas.base.message.*;
import com.kingdee.eas.base.message.util.ProcessCenterUtil;
import com.kingdee.eas.base.message.webservice.MessageWebServiceDao;
import com.kingdee.eas.base.message.webservice.WSMessage;
import com.kingdee.eas.base.message.webservice.WfrAssignMessage;
import com.kingdee.eas.base.message.webservice.WfrProcMessage;
import com.kingdee.eas.base.permission.IUser;
import com.kingdee.eas.base.permission.UserFactory;
import com.kingdee.eas.base.permission.UserInfo;
import com.kingdee.eas.basedata.person.IPerson;
import com.kingdee.eas.basedata.person.PersonFactory;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

/**
 * @Description OA待办消息  ProcessWebService
 * @Date 2024/10/29 13:38
 * @Created by Heyuan
 */
public class OAMessageWebServiceDao implements MessageWebServiceDao {
    private static Logger logger = Logger.getLogger(OAMessageWebServiceDao.class);
    private Properties prop = new Properties();
    private final String MBOSURL = "https://mbos.kdeascloud.com/mbos/mbosw/getWorkflowUrl?assignId={0}&eid={1}&storeEid={2}&name=approveui.navui&billID={3}";
    //mbos流程助手首页
    private final String MBOSAPPROVECENTERURL = "https://mbos.kdeascloud.com/mbos/page/loadPage?appid=10036&eid={0}&path=lczs2&name=lczshome.navui";
    //pc转阅地址
    private final String PASSASSIGNMENTURL = "{0}/easweb/dynamicPage.do?event=initialize&method=doEvent&uipk=com.kingdee.bos.workflow.metas.approve&type=passComent&sourceIDs={1}&msgId={2}&assignmentId={3}&passid={4}&billID={5}";
    //mbos传阅
    private final String MBOSPASSASSIGNMENTURL = "https://mbos.kdeascloud.com/mbos/page/loadPage?path=lczs2&name=approveui.navui&lczstype=list&eid={0}&appid=10036&cometype=myreceivepass&billID={1}&fprocinstid={2}&fpassid={3}&msgid={4}&operateState=VIEW&storeEid={5}";

    String propPath = System.getProperty("EAS_HOME") + "/server/properties/scy/receiveOAConfig.properties";

    public OAMessageWebServiceDao() {
        try {
            prop.load(new FileInputStream(propPath));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("OA待办消息 获取配置文件失败!" + e.getMessage());
        }
    }

    /**
     * 发送消息
     *
     * @param message
     * @return
     */
    @Override
    public boolean addMessage(WSMessage message) {
        try {
            logger.error("*********OAMessageWebServiceDao addMessage 消息监听开始**********");
            boolean result = sendMessage(message, "0", "0", null);
            Context ctx = message.getContext();
            String msgID = message.getMsgID();
            IAssignRead assignReadIns = AssignReadFactory.getLocalInstance(ctx);
            AssignReadInfo assignReadInfo = assignReadIns.getAssignReadInfo(new ObjectUuidPK(msgID));
            String assignId = assignReadInfo.getAssignID().toString();
            String billId = message.getBillId();
            String workflowname = getFlowTypeNameyBillId(ctx, msgID, billId, assignId);
            addMsgId(ctx, msgID, assignId, billId, workflowname);
            return result;
        } catch (Exception e) {
            logger.error(e);
            throw new RuntimeException(e);
        }
    }


    /**
     * 删除消息
     *
     * @param s
     * @return
     */
    @Override
    public boolean removeMessage(String s) {
        logger.error("*********OAMessageWebServiceDao removeMessage111 消息监听开始**********");
        logger.error("*********OAMessageWebServiceDao s " + s);
        return false;
    }


    /**
     * 删除消息
     *
     * @param s
     * @param context
     * @return
     */
    @Override
    public boolean removeMessage(String s, Context context) {
        logger.error("*********OAMessageWebServiceDao removeMessage222 消息监听开始**********");
        logger.error("*********OAMessageWebServiceDao s " + s);
        return false;
    }

    /**
     * 更新消息
     *
     * @param s
     * @return
     */
    @Override
    public boolean updateMessage(String s) {
        logger.error("*********OAMessageWebServiceDao updateMessages444 消息监听开始**********");
        logger.error("*********OAMessageWebServiceDao s " + s);
        return false;
    }

    /**
     * 更新消息
     *
     * @param s
     * @param context
     * @return
     */
    @Override
    public boolean updateMessage(String s, Context context) {
        logger.error("*********OAMessageWebServiceDao updateMessages3333 消息监听开始**********");
        logger.error("*********OAMessageWebServiceDao s " + s);
        return false;
    }

    /**
     * @param s
     * @param msgStatus
     * @return
     */
    @Override
    public boolean updateMessages(String s, MsgStatus msgStatus) {
        logger.error("*********OAMessageWebServiceDao updateMessages111 消息监听开始**********");
        logger.error("*********OAMessageWebServiceDao s " + s);
        logger.error("*********OAMessageWebServiceDao msgStatus " + msgStatus.getAlias());
        return false;
    }

    @Override
    public boolean updateMessages(String id, MsgStatus msgStatus, Context ctx) {
        logger.error("*********OAMessageWebServiceDao updateMessages2222 消息监听开始**********");
        logger.error("*********OAMessageWebServiceDao id " + id);
        logger.error("*********OAMessageWebServiceDao msgStatus " + msgStatus.getAlias());
        BOSUuid bosId = BOSUuid.read(id);
        String bosType = bosId.getType().toString();
        logger.error("*********OAMessageWebServiceDao bosType " + bosType);
        if ("9623EB51".equals(bosType)) {
            String assignID = "";
            try {
                //任务阅读表
                IAssignRead assignReadIns = AssignReadFactory.getLocalInstance(ctx);
                AssignReadInfo assignReadInfo = assignReadIns.getAssignReadInfo(new ObjectUuidPK(id));
                assignID = assignReadInfo.getAssignID().toString();
                IAssign iAssign = AssignFactory.getLocalInstance(ctx);
                IPerson iPerson = PersonFactory.getLocalInstance(ctx);
                AssignInfo assignInfo = iAssign.getValue(new ObjectUuidPK(assignID));
                IUser iUser = UserFactory.getLocalInstance(ctx);
                WSMessage wsMessage = new WSMessage();
                wsMessage.setMsgID(id);
                wsMessage.setTitle(assignInfo.getSubject());
                wsMessage.setBillId(assignInfo.getBizObjID());
                wsMessage.setContext(ctx);
                String priorPerformerID = assignInfo.getPriorPerformerID();
                UserInfo userInfo = iUser.getUserInfo(new ObjectUuidPK(priorPerformerID));
                wsMessage.setSenderNumber(userInfo.getNumber());
                wsMessage.setSender(userInfo.getName());
                String personEmpId = assignInfo.getPersonEmpID().toString();
                PersonInfo reciever = iPerson.getPersonInfo(new ObjectUuidPK(personEmpId));
                wsMessage.setReceivers(reciever.getName());
                wsMessage.setRecieveNumber(reciever.getNumber());
                wsMessage.setRecieverID(personEmpId);
                if (MsgStatus.READED.equals(msgStatus)) {
                    //已读
                    return sendMessage(wsMessage, "0", "1", assignID);
                } else {
                    return sendMessage(wsMessage, "0", "0", assignID);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    @Override
    public boolean addInitiatorMessage(WfrProcMessage wfrProcMessage) {
        logger.error("*********OAMessageWebServiceDao addInitiatorMessage 消息监听开始**********");
        return false;
    }

    /**
     * 任务完成时触发
     * 之后会触发 com.kingdee.eas.custom.messageWebService.OAMessageWebServiceDao#removeMessage(java.lang.String, com.kingdee.bos.Context)
     * 之后会触发 com.kingdee.eas.custom.messageWebService.OAMessageWebServiceDao#addInitiatorMessage(com.kingdee.eas.base.message.webservice.WfrProcMessage)
     *
     * @param wfrAssignMessage
     * @return
     */
    @Override
    public boolean addCompletedMessage(WfrAssignMessage wfrAssignMessage) {
        String msgId = "";
        Context ctx = wfrAssignMessage.getCtx();
        //工作流实列
        String procInstId = wfrAssignMessage.getProcInstId();
        String assignId = wfrAssignMessage.getAssignId();
        try {
            logger.error("*********OAMessageWebServiceDao addCompletedMessage 消息监听开始**********");
            logger.error("*********OAMessageWebServiceDao assignId " + assignId);
            System.out.println("procInstId: " + procInstId);
            String assignSubject = wfrAssignMessage.getAssignSubject();
            String billID = wfrAssignMessage.getBillID();
            String handler = wfrAssignMessage.getHandler();
            String handlerNumber = wfrAssignMessage.getHandlerNumber();
            String state = wfrAssignMessage.getState();
            logger.error("*********OAMessageWebServiceDao state " + state);
            WfAssignmentState stateEnum = WfAssignmentState.getEnum(state);
            IAssignRead iAssignRead = AssignReadFactory.getLocalInstance(ctx);
            AssignReadCollection assignReadCollection = iAssignRead.getAssignReadCollection("where assignID='" + assignId + "'");
            if (assignReadCollection.size() > 0) {
                msgId = assignReadCollection.get(0).getId().toString();
            } else {
                //throw new RuntimeException("未找到对应的任务阅读表  assignId: " + assignId);
                msgId = getMsgId(ctx, assignId);
            }
            if (WfAssignmentState.COMPLETED.equals(stateEnum)
                    || WfAssignmentState.REJECTED.equals(stateEnum)
                    || WfAssignmentState.CANCELED.equals(stateEnum)) {
                //任务完成或已拒绝、任务取消，更新OA消息为已办
                WSMessage wsMessage = new WSMessage();
                wsMessage.setMsgID(msgId);
                wsMessage.setTitle(assignSubject);
                wsMessage.setBillId(billID);
                wsMessage.setContext(ctx);
                wsMessage.setSenderNumber(wfrAssignMessage.getInitiatorNumber());
                wsMessage.setSender(wfrAssignMessage.getInitiator());
                wsMessage.setReceivers(handler);
                wsMessage.setRecieveNumber(handlerNumber);
                wsMessage.setRecieverID(wfrAssignMessage.getHandlerId());
                return sendMessage(wsMessage, "2", "1", assignId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * @param message
     * @param isremark 流程处理状态
     * @param viewtype 流程查看状态
     * @return
     */
    private boolean sendMessage(WSMessage message, String isremark, String viewtype, String assignId) {
        Context ctx = message.getContext();
        String msgID = message.getMsgID();
        String billId = null;
        String receiveOAPath = prop.getProperty("receiveOAPath");
        JSONObject params = null;
        try {
            String serverName = prop.getProperty("serverName");
            if (StringUtils.isEmpty(receiveOAPath)) {
                throw new BOSException("发送OA待办消息,推送异步消息地址不能为空! 请检查配置文件: " + propPath);
            }
            params = new JSONObject();
            String syscode = prop.getProperty("syscode", "SHR");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();
            String now = sdf.format(date);
            params.put("syscode", syscode);//异构系统标识
            params.put("flowid", msgID);//流程实例id
            //业务类型
            MsgBizType bizType = message.getBizType();
            if (MsgBizType.URGENT.equals(bizType)) {
                //催办
                params.put("requestname", message.getBody());//标题
            } else {
                params.put("requestname", message.getTitle());//标题
            }
            billId = message.getBillId();
            logger.error("billId: " + billId);
            //MsgType type = message.getType();
            params.put("nodename", "sHR");//步骤名称（节点名称）
            params.put("isremark", isremark);//流程处理状态
            params.put("viewtype", viewtype);//流程查看状态
            params.put("creator", message.getSenderNumber());//创建人（原值）
            params.put("createdatetime", now);//创建日期时间
            params.put("receiver", message.getRecieveNumber());//接收人（原值）
            params.put("receivedatetime", now);//接收日期时间
            //时间戳字段，客户端使用线程调用接口的时候，根据此字段判断是否需要更新数据，防止后发的请求数据被之前的覆盖
            params.put("receivets", String.valueOf(date.getTime()));
            if (StringUtils.isBlank(msgID)) {
                throw new BOSException("msgID为空!");
            }
            params.put("pcurl", getPcUrl(ctx, serverName, message, bizType, assignId));//PC地址（相对路径/开头）
            params.put("appurl", getAppUrl(ctx, serverName, message, bizType, assignId));//APP地址（相对路径/开头）
            String workflowname = getFlowTypeNameyBillId(ctx, msgID, billId, assignId);
            params.put("workflowname", workflowname);//流程类型名称
            logger.error("addMessage -> params: " + params);
            OkHttpClient client = new OkHttpClient();
            MediaType mediaType = MediaType.parse("application/json");
            RequestBody body = RequestBody.create(mediaType, params.toString());
            Request request = new Request.Builder()
                    .url(receiveOAPath)
                    .post(body)
                    .addHeader("content-type", "application/json")
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                String result = response.body().string();
                logger.error("addMessage -> result:" + result);
                JSONObject jsonObject = JSONObject.parseObject(result);
                String operResult = jsonObject.getString("operResult");
                if ("1".equals(operResult)) {
                    addOAMsgCallLog(ctx, msgID, assignId, billId, receiveOAPath, params.toJSONString(), result, 1, "成功");
                    return true;
                } else {
                    logger.error(jsonObject.getString("message"));
                    throw new BOSException(jsonObject.getString("message"));
                }
            } else {
                logger.error("发送OA待办消息 超时");
                throw new BOSException("发送OA待办消息 超时");
            }
        } catch (Exception e) {
            e.printStackTrace();
            String paramsStr = null;
            if (params != null) {
                paramsStr = params.toString();
            }
            addOAMsgCallLog(ctx, msgID, assignId, billId, receiveOAPath, paramsStr, "", 0, e.getMessage());
        }
        return false;
    }

    /**
     * 获取pc待办地址
     *
     * @param ctx
     * @param serverName
     * @param message
     * @return
     * @throws UnsupportedEncodingException
     * @throws BOSException
     * @throws EASBizException
     */
    private String getPcUrl(Context ctx, String serverName, WSMessage message, MsgBizType bizType, String assignId)
            throws BOSException {
        try {
            String msgId = message.getMsgID();
            String billId = message.getBillId();
            StringBuilder pcurl = new StringBuilder();
            pcurl.append(serverName).append("/shr/api/oAToSHR?redirect=");
            String bosType = BOSUuid.read(msgId).getType().toString();
            if ("9623EB51".equals(bosType)) {
                //任务阅读表
                StringBuilder redirectUrl = new StringBuilder();
                if (StringUtils.isBlank(assignId)) {
                    IAssignRead assignReadIns = AssignReadFactory.getLocalInstance(ctx);
                    AssignReadInfo assignReadInfo = assignReadIns.getAssignReadInfo(new ObjectUuidPK(msgId));
                    assignId = assignReadInfo.getAssignID().toString();
                }
                if (StringUtils.isNotBlank(assignId)) {
                    if (StringUtils.isBlank(billId)) {
                        URLInfo info = ProcessCenterUtil.getUrlInfos(assignId, ctx);
                        billId = info.getBillID();
                    }
                    redirectUrl.append(serverName).append("/easweb/webviews/workflow/transferApprove.jsp?AssignmentId=")
                            .append(URLEncoder.encode(assignId, "UTF-8")).append("&billID=").append(URLEncoder.encode(billId, "UTF-8"));
                } else {
                    redirectUrl.append(serverName).append("/shr/dynamic.do?uipk=shr.perself.homepage");
                }
                pcurl.append(URLEncoder.encode(redirectUrl.toString(), "UTF-8"));
                logger.error("pcurl: " + pcurl);
                return pcurl.toString();
            } else {
                throw new RuntimeException("bosType类型未找到: " + bosType);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BOSException(e.getMessage());
        }
    }

    /**
     * 获取app待办地址
     *
     * @param serverName
     * @param message
     * @return
     * @throws BOSException
     * @throws EASBizException
     * @throws UnsupportedEncodingException
     */
    private String getAppUrl(Context ctx, String serverName, WSMessage message, MsgBizType bizType, String assignId)
            throws BOSException {
        try {
            String msgId = message.getMsgID();
            String billId = message.getBillId();
            StringBuilder appUrl = new StringBuilder();
            appUrl.append(serverName).append("/shr/api/oAToMBos?redirect=");
            String bosType = BOSUuid.read(msgId).getType().toString();
            String eid = prop.getProperty("eid");
            if (StringUtils.isEmpty(eid)) {
                throw new RuntimeException("发送OA待办消息,eid不能为空! 请检查配置文件: " + propPath);
            }
            if ("9623EB51".equals(bosType)) {
                //任务阅读表
                String redirectUrl = null;
                if (StringUtils.isBlank(assignId)) {
                    IAssignRead assignReadIns = AssignReadFactory.getLocalInstance(ctx);
                    AssignReadInfo assignReadInfo = assignReadIns.getAssignReadInfo(new ObjectUuidPK(msgId));
                    assignId = assignReadInfo.getAssignID().toString();
                }
                if (StringUtils.isNotBlank(assignId)) {
                    if (StringUtils.isBlank(billId)) {
                        URLInfo info = ProcessCenterUtil.getUrlInfos(assignId, ctx);
                        billId = info.getBillID();
                    }
                    redirectUrl = MessageFormat.format(MBOSURL,
                            URLEncoder.encode(assignId, "UTF-8"),
                            eid,
                            "21231",
                            URLEncoder.encode(billId, "UTF-8"));
                } else {
                    redirectUrl = MessageFormat.format(MBOSAPPROVECENTERURL, eid);
                }
                appUrl.append(URLEncoder.encode(redirectUrl, "UTF-8"));
            }
            logger.error("appUrl: " + appUrl);
            return appUrl.toString();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BOSException(e.getMessage());
        }
    }


    /**
     * 删除待办
     *
     * @param flowId
     * @param userId
     * @return
     */
    private boolean deleteMessage(String flowId, String userId) {
        try {
            OkHttpClient client = new OkHttpClient();
            JSONObject params = new JSONObject();
            String deleteMsgPath = prop.getProperty("deleteMsgPath");
            if (StringUtils.isEmpty(deleteMsgPath)) {
                throw new RuntimeException("删除OA消息地址不能为空! 请检查配置文件: " + propPath);
            }
            String syscode = prop.getProperty("syscode", "SHR");
            params.put("syscode", syscode);
            params.put("flowid", flowId);
            params.put("userid", userId);
            String paramsStr = params.toString();
            logger.error("OAMessageWebServiceDao  deleteMessage-> params:" + paramsStr);
            MediaType mediaType = MediaType.parse("application/json");
            RequestBody body = RequestBody.create(mediaType, paramsStr);
            Request request = new Request.Builder()
                    .url(deleteMsgPath)
                    .post(body)
                    .addHeader("content-type", "application/json")
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                String result = response.body().string();
                logger.error("deleteMessage -> result:" + result);
                JSONObject jsonObject = JSONObject.parseObject(result);
                String operResult = jsonObject.getString("operResult");
                if ("1".equals(operResult)) {
                    return true;
                } else {
                    logger.error(jsonObject.getString("message"));
                }
            } else {
                logger.error("删除OA待办消息 超时");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 根据单据id获取流程单据类型名称
     *
     * @param ctx
     * @param msgId
     * @param billId
     * @param assignId
     * @return
     * @throws BOSException
     * @throws EASBizException
     */
    public String getFlowTypeNameyBillId(Context ctx,
                                         String msgId,
                                         String billId,
                                         String assignId)
            throws BOSException, EASBizException {
        String flowTypeName = "流程";
        try {
            if (StringUtils.isBlank(billId)) {
                if (StringUtils.isBlank(assignId)) {
                    IAssignRead assignReadIns = AssignReadFactory.getLocalInstance(ctx);
                    AssignReadInfo assignReadInfo = assignReadIns.getAssignReadInfo(new ObjectUuidPK(msgId));
                    assignId = assignReadInfo.getAssignID().toString();
                }
                if (StringUtils.isNotBlank(assignId)) {
                    URLInfo info = ProcessCenterUtil.getUrlInfos(assignId, ctx);
                    billId = info.getBillID();
                } else {
                    return flowTypeName;
                }
            }
            IMetaDataLoader loader = MetaDataLoaderFactory.getRemoteMetaDataLoader();
            EntityObjectInfo vo = loader.getEntity(BOSUuid.read(billId).getType());
            flowTypeName = vo.getDisplayName();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flowTypeName;
    }

    /**
     * 获取消息阅读表id
     * 流程撤销时,阅读表数据会先删除,然后再进addCompletedMessage方法,由于msgId作为OA待办消息的唯一标识
     *
     * @param ctx
     * @param assignID
     * @return
     */
    private String getMsgId(
            Context ctx,
            String assignID) {
        String msgId = "";
        try {
            String sql = "select MsgId from assignReadRecord where assignID = ?";
            IRowSet iRowSet = DbUtil.executeQuery(ctx, sql, new Object[]{assignID});
            while (iRowSet.next()) {
                msgId = iRowSet.getString("MsgId");
            }
        } catch (Exception e) {
            logger.error(e);
        }
        return msgId;
    }

    /**
     * 写入消息阅读表Id
     *
     * @param ctx
     * @param assignID
     * @return
     */
    private void addMsgId(
            Context ctx,
            String msgId,
            String assignID,
            String billId,
            String workflowname) {
        try {
            String insertSql = "insert into assignReadRecord(MsgId,assignID,billId,workflowname) values(?,?,?,?)";
            DbUtil.execute(ctx, insertSql, new Object[]{
                    getStringOrDefault(msgId),
                    getStringOrDefault(assignID),
                    getStringOrDefault(billId),
                    getStringOrDefault(workflowname)});
        } catch (Exception e) {
            logger.error(e);
        }
    }

    /**
     * 写入待办消息记录表
     *
     * @param ctx
     * @param assignID
     * @return
     */
    private void addOAMsgCallLog(
            Context ctx,
            String msgId,
            String assignID,
            String billId,
            String requestUrl,
            String requestParams,
            String responseResult,
            int statusCode,
            String message) {
        try {
            String insertSql = "insert into OAMsgCallLog(MsgId,assignID,billId,RequestUrl,RequestParams,ResponseResult,StatusCode,Message) values(?,?,?,?,?,?,?,?)";
            DbUtil.execute(ctx, insertSql, new Object[]{
                    getStringOrDefault(msgId),
                    getStringOrDefault(assignID),
                    getStringOrDefault(billId),
                    getStringOrDefault(requestUrl),
                    getStringOrDefault(requestParams),
                    getStringOrDefault(responseResult),
                    statusCode,
                    getStringOrDefault(message)});
        } catch (Exception e) {
            logger.error(e);
        }
    }

    private String getStringOrDefault(String value) {
        if (StringUtils.isBlank(value)) {
            return "";
        } else {
            return value;
        }
    }
}
