MenuSaveAction.java

package com.mycim.webapp.actions.setting.security.menu;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.beans.PropertyUtils;
import com.mycim.framework.utils.lang.BooleanUtils;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.Relation;
import com.mycim.valueobject.consts.LinkTypeList;
import com.mycim.valueobject.consts.SessionNames;
import com.mycim.valueobject.security.Menu;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.SystemSetupAction;
import com.mycim.webapp.forms.security.MenuInfoForm;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * 系统配置->菜单定义功能
 *
 * @author Pinyan Song
 * @version 6.0.0
 * @date 2019-8-21 14:20
 **/
public class MenuSaveAction extends SystemSetupAction {

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        MenuInfoForm theForm = (MenuInfoForm) form;
        theForm.setInstanceId(StringUtils.trim(theForm.getInstanceId()));
        Menu menu = getMenuInfo(theForm);

        PropertyUtils.copyProperties(theForm, menu);
        if (menu.getInstanceRrn() == 0) {
            theForm.setObjectType(ObjectList.MENU_SUBMENU_KEY);
            theForm.setTransId(Constants.CREATE_KEY);
        } else {
            theForm.setTransId(Constants.MODIFY_KEY);
        }
        request.setAttribute(SessionNames.MENU_KEY, menu);
        return mapping.findForward(Constants.MODIFY_KEY);
    }

    public ActionForward conversion(ActionMapping mapping, ActionForm form,
                                    HttpServletRequest request) throws Exception {
        MenuInfoForm theForm = (MenuInfoForm) form;
        moveOnTheTree(request, theForm, LocalContext.getFacilityRrn());
        return mapping.findForward(Constants.MODIFY_KEY);
    }

    public ActionForward upMembers(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
        MenuInfoForm theForm = (MenuInfoForm) form;
        Menu menu = getMenuInfo(theForm);
        List<Menu> menuList = (List<Menu>) menu.getSubMenus();

        long subMenuRrn = WebUtils.getParameterLong(Constants.ITEM_KEY, request);

        int index = getTheIndex(menuList, subMenuRrn);
        Menu indexMenu = menuList.get(index);

        menuList.set(index, menuList.get(index - 1));
        menuList.set(index - 1, indexMenu);

        saveSubMenus(menu, menuList);

        return init(mapping, theForm, request, response);
    }

    public ActionForward downMembers(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                     HttpServletResponse response) throws Exception {
        MenuInfoForm theForm = (MenuInfoForm) form;
        Menu menu = getMenuInfo(theForm);
        List<Menu> menuList = (List<Menu>) menu.getSubMenus();

        long subMenuRrn = WebUtils.getParameterLong(Constants.ITEM_KEY, request);

        int index = getTheIndex(menuList, subMenuRrn);
        Menu indexMenu = menuList.get(index);

        menuList.set(index, menuList.get(index + 1));
        menuList.set(index + 1, indexMenu);

        saveSubMenus(menu, menuList);

        return init(mapping, theForm, request, response);
    }

    public ActionForward deleteMembers(ActionMapping mapping, ActionForm form, HttpServletRequest request) {
        MenuInfoForm theForm = (MenuInfoForm) form;
        Menu menu = getMenuInfo(theForm);

        Long menuRrn = new Long(request.getParameter(Constants.ITEM_KEY));
        Relation relation = new Relation();
        relation.setTransId(Constants.DELETE_KEY);
        relation.setFromRrn(menu.getInstanceRrn());
        relation.setToRrn(menuRrn);
        relation.setLinkType(LinkTypeList.MENU_SUBMENU_KEY);

        processDetails(relation);

        theForm.setTransId(Constants.MODIFY_KEY);
        menu = getMenuInfo(theForm);
        request.setAttribute(SessionNames.MENU_KEY, menu);
        updateParent(theForm, menu);
        return mapping.findForward(Constants.MODIFY_KEY);
    }

    public ActionForward addMembers(ActionMapping mapping, ActionForm form, HttpServletRequest request) {
        MenuInfoForm theForm = (MenuInfoForm) form;
        Menu menu = getMenuInfo(theForm);

        String subMenuId = theForm.getSubMenuId().trim().toUpperCase();

        Assert.isFalse(StringUtils.equals(menu.getInstanceId(), subMenuId),
                       Errors.create().key(MessageIdList.MENU_FORBID_ADD_ITSELF).content("不能添加自己!").build());

        Menu subMenu = new Menu(subMenuId, menu.getNamedSpace(), ObjectList.MENU_KEY);
        Long subMenuRrn = baseService.getNamedObjectRrn(subMenu);

        Assert.isFalse(subMenuRrn == 0 || subMenuRrn == -1,
                       Errors.create().key(MessageIdList.SYSTEM_INSTANCE_NOT_FOUND).content("{} 没有找到对象!")
                             .args("sub menu").build());
        Relation relation = new Relation();
        relation.setTransId(Constants.CREATE_KEY);
        relation.setFromRrn(menu.getInstanceRrn());
        relation.setToRrn(subMenuRrn);
        relation.setLinkType(LinkTypeList.MENU_SUBMENU_KEY);

        processDetails(relation);

        theForm.setSubMenuId(StringUtils.EMPTY);
        menu = getMenuInfo(theForm);
        updateParent(theForm, menu);
        theForm.setTransId(Constants.MODIFY_KEY);
        request.setAttribute(SessionNames.MENU_KEY, menu);
        return mapping.findForward(Constants.MODIFY_KEY);
    }

    public ActionForward copy(ActionMapping mapping, ActionForm form, HttpServletRequest request) throws Exception {
        String id = request.getParameter(Constants.COPY_SUB_KEY);
        Menu menu = new Menu(id, getNamedSpace(ObjectList.MENU_KEY, LocalContext.getFacilityRrn()),
                             ObjectList.MENU_KEY);
        MenuInfoForm theForm = (MenuInfoForm) form;
        doCopy(theForm, menu);
        theForm.setInstanceId(StringUtils.upperCase(theForm.getInstanceId() + "_" + Constants.COPY_KEY));
        theForm.setTransId(Constants.CREATE_KEY);
        theForm.setCopyFlag(Constants.COPY_SUB_KEY);
        return (mapping.findForward(Constants.MODIFY_KEY));
    }

    public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request) {
        MenuInfoForm theFOrm = (MenuInfoForm) form;
        theFOrm.setInstanceId(StringUtils.EMPTY);
        return (mapping.findForward(Constants.SETUP_KEY));
    }

    public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request) throws Exception {
        MenuInfoForm theForm = (MenuInfoForm) form;
        Menu menu = new Menu(theForm.getInstanceId(), getNamedSpace(ObjectList.MENU_KEY, LocalContext.getFacilityRrn()),
                             ObjectList.MENU_KEY);

        verifyAndProcessMenu(Constants.CREATE_KEY, theForm.getIcon(), menu, theForm);

        menu = getMenuInfo(theForm);
        PropertyUtils.copyProperties(theForm, menu);

        theForm.setTransId(Constants.MODIFY_KEY);
        request.setAttribute(SessionNames.MENU_KEY, menu);
        return mapping.findForward(Constants.MODIFY_KEY);
    }

    public ActionForward modify(ActionMapping mapping, ActionForm form, HttpServletRequest request) throws Exception {
        MenuInfoForm theForm = (MenuInfoForm) form;
        Menu menu = getMenuInfo(theForm);
        verifyAndProcessMenu(Constants.MODIFY_KEY, theForm.getIcon(), menu, theForm);

        menu = getMenuInfo(theForm);
        PropertyUtils.copyProperties(theForm, menu);
        theForm.setTransId(Constants.MODIFY_KEY);
        request.setAttribute(SessionNames.MENU_KEY, menu);
        return mapping.findForward(Constants.MODIFY_KEY);
    }

    public ActionForward delete(ActionMapping mapping, ActionForm form) {
        MenuInfoForm theForm = (MenuInfoForm) form;
        Menu menu = getMenuInfo(theForm);
        menu.setTransId(Constants.DELETE_KEY);
        theForm.setInstanceId(StringUtils.EMPTY);
        process(menu);
        return mapping.findForward(Constants.SETUP_KEY);
    }

    public ActionForward adjust(ActionMapping mapping, ActionForm form, HttpServletRequest request) {
        MenuInfoForm theForm = (MenuInfoForm) form;
        Menu menu = getMenuInfo(theForm);
        theForm.setSubMenuSize("" + menu.getSubMenus().size());
        request.setAttribute(SessionNames.MENU_KEY, menu);
        return (mapping.findForward(Constants.ADJUST_KEY));
    }

    private void saveSubMenus(Menu menu, List<Menu> menuList) {
        List<Relation> relations = new ArrayList<Relation>();
        int index = 0;

        for (Menu submenu : menuList) {
            index++;
            Relation relation = new Relation(menu.getInstanceRrn(), submenu.getInstanceRrn(),
                                             LinkTypeList.MENU_SUBMENU_KEY);
            relation.setSequenceNumber(index);
            relations.add(relation);
        }
        baseService.saveRelations(relations, LocalContext.getUserId(), Constants.MODIFY_KEY);

    }

    private int getTheIndex(List<Menu> subMenus, long subMenuRrn) {
        int index = 0;
        for (int i = 0; i < subMenus.size(); i++) {
            Menu menu = subMenus.get(i);
            if (menu.getInstanceRrn() == subMenuRrn) {
                index = i;
                break;
            }
        }
        return index;
    }

    private Menu getMenuInfo(MenuInfoForm form) {
        Menu menu = new Menu(form.getInstanceId(), getNamedSpace(ObjectList.MENU_KEY, LocalContext.getFacilityRrn()),
                             ObjectList.MENU_KEY);
        menu = (Menu) getInstance(menu);

        if (menu.getInstanceRrn() == 0) {
            return menu;
        } else {
            menu.setSubMenus(getSubMenus(menu));
            menu.setTransPerformedby(LocalContext.getUserId());
            return menu;
        }
    }

    /**
     * 在父子菜单之间移动
     */
    private void moveOnTheTree(HttpServletRequest request, MenuInfoForm theForm, Long facilityRrn) throws Exception {
        String id = request.getParameter(Constants.ITEM_KEY);

        if (StringUtils.isEmpty(id)) {
            id = theForm.getParentMenuId();
            theForm.setParentMenuId(null);
        }

        Menu temp = (Menu) this
                .getInstance(new Menu(id, getNamedSpace(ObjectList.MENU_KEY, facilityRrn), ObjectList.MENU_KEY));
        temp.setSubMenus(this.getSubMenus(temp));

        PropertyUtils.copyProperties(theForm, temp);
        updateParent(theForm, temp);

        request.setAttribute(SessionNames.MENU_KEY, temp);
        theForm.setTransId(Constants.MODIFY_KEY);
    }

    private void updateParent(MenuInfoForm theForm, Menu menu) {
        Menu parent = securityService.getParentMenu(menu.getInstanceRrn());
        if (parent != null) {
            menu.setParentRrn(parent.getInstanceRrn());
            theForm.setParentFlag(BooleanUtils.toIntegerObject(Boolean.TRUE).toString());
            theForm.setParentMenuRrn(parent.getInstanceRrn());
            theForm.setParentMenuId(parent.getInstanceId());
        } else {
            theForm.setParentFlag(BooleanUtils.toIntegerObject(Boolean.FALSE).toString());
            theForm.setParentMenuRrn(null);
            theForm.setParentMenuId(null);
        }
    }

    private void processDetails(Relation relation) {
        String action = relation.getTransId();

        if (action.equals(Constants.CREATE_KEY)) {
            // avoid duplication
            if (baseService.getRelation(relation) != null) {
                return;
            }

            Assert.isFalse(securityService.isNodeInTree(relation.getToRrn(), relation.getFromRrn()),
                           Errors.create().key(MessageIdList.MENU_FORBID_ADD).content("无法添加此菜单!").build());

            securityService.addSubMenuToMenu(relation);
        } else if (action.equals(Constants.DELETE_KEY)) {
            baseService.deleteRelation(relation);
        }
    }

    private void verifyAndProcessMenu(String transId, String icon, Menu menu, MenuInfoForm form) throws Exception {
        PropertyUtils.copyProperties(menu, form);

        String labelId = form.getLabelId();
        long labelRrn = getInstanceRrn(labelId, getNamedSpace(ObjectList.LABEL_KEY, LocalContext.getFacilityRrn()),
                                       ObjectList.LABEL_KEY);
        Assert.isFalse(StringUtils.isEmpty(labelId) || labelRrn <= 0,
                       Errors.create().key(MessageIdList.SYSTEM_INSTANCE_NOT_FOUND).content("{} 没有找到对象!").args("Label")
                             .build());

        menu.setLabelRrn(labelRrn);
        menu.setTransId(transId);
        menu.setTransPerformedby(LocalContext.getUserId());
        menu.setIcon(icon);
        process(menu);
    }

}