ScreenSaveAction.java

/*
 *        @ Copyright 2001 FA Software;
 *        All right reserved. No part of this program may be reproduced or
 *        transmitted in any form or by any means, electronic or
 *        mechanical, including photocopying, recording, or by any
 *        information storage or retrieval system without written
 *        permission from FA Software, except for inclusion of brief
 *        quotations in a review.
 */
package com.mycim.webapp.actions.setting.system.screen;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.logging.Logger;
import com.mycim.framework.logging.LoggerFactory;
import com.mycim.framework.utils.beans.PropertyUtils;
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.sys.Field;
import com.mycim.valueobject.sys.Label;
import com.mycim.valueobject.sys.Screen;
import com.mycim.valueobject.sys.Validator;
import com.mycim.webapp.Constants;
import com.mycim.webapp.actions.SystemSetupAction;
import com.mycim.webapp.forms.system.ScreenInfoForm;
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.*;

/**
 * 页面定义
 *
 * @author yanbing.chen
 * @date 2019/8/21
 * @since 1.8
 **/
public class ScreenSaveAction extends SystemSetupAction {

    private final static int seqStep = 1;

    private static final Logger log = LoggerFactory.getLogger(ScreenSaveAction.class);

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {

        ScreenInfoForm theform = (ScreenInfoForm) form;

        // Populate the new valid format id
        String id = theform.getInstanceId().trim().toUpperCase();

        Screen screen = new Screen(id, getNamedSpace(ObjectList.SCREEN_KEY, LocalContext.getFacilityRrn()),
                                   ObjectList.SCREEN_KEY);

        screen = (Screen) getInstance(screen);

        PropertyUtils.copyProperties(theform, screen);

        theform.setPages(new Integer(1));

        // if a value object does not exist, its instanceRrn will be set to 0
        if (screen.getInstanceRrn() == 0) {
            theform.setTransId(Constants.CREATE_KEY);
        } else {
            screen.setValidators(getValidators(screen));
            theform.setTransId(Constants.MODIFY_KEY);
        }
        request.setAttribute(SessionNames.SCREEN_KEY, screen);
        return (mapping.findForward(Constants.MODIFY_KEY));
    }

    @Override
    public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
        ScreenInfoForm theform = (ScreenInfoForm) form;
        request.removeAttribute(SessionNames.SCREEN_KEY);
        theform.setInstanceId("");
        return (mapping.findForward(Constants.SETUP_KEY));
    }

    public ActionForward copy(ActionMapping mapping, ScreenInfoForm theform,
                              HttpServletRequest request) throws Exception {
        String user = LocalContext.getUserId();
        Screen screen = new Screen(theform.getInstanceId(),
                                   getNamedSpace(ObjectList.SCREEN_KEY, LocalContext.getFacilityRrn()),
                                   ObjectList.SCREEN_KEY);
        screen = (Screen) getInstance(screen);
        PropertyUtils.copyProperties(screen, theform);

        screen.setTransPerformedby(user);
        String id = request.getParameter(Constants.COPY_KEY);
        screen.setInstanceId(id);
        doCopy(theform, screen);
        theform.setTransId(Constants.CREATE_KEY);
        return (mapping.findForward(Constants.MODIFY_KEY));
    }

    public ActionForward members(ActionMapping mapping, ScreenInfoForm theform,
                                 HttpServletRequest request) throws Exception {
        Long facilityRrn = LocalContext.getFacilityRrn();
        String user = LocalContext.getUserId();

        Screen screen = new Screen(theform.getInstanceId(),
                                   getNamedSpace(ObjectList.SCREEN_KEY, LocalContext.getFacilityRrn()),
                                   ObjectList.SCREEN_KEY);

        screen = (Screen) getInstance(screen);
        PropertyUtils.copyProperties(screen, theform);

        screen.setTransPerformedby(user);

        String[] newSeq = request.getParameterValues("seq");
        String[] newFieldFlag = request.getParameterValues("hidFieldFlag");
        String[] newValidatorId = request.getParameterValues("validatorId");
        String[] newProperty = request.getParameterValues("property");
        String[] newGroupNumber = request.getParameterValues("groupNumber");

        if (request.getParameter(Constants.MEMBERS_KEY).equals("delete") &&
                (request.getParameter(Constants.ITEM_KEY) != null)) {
            // if the click the delete button.
            Long validatorRrn = new Long(request.getParameter(Constants.ITEM_KEY));
            Relation relation = new Relation();
            relation.setFromRrn(screen.getInstanceRrn());
            relation.setToRrn(validatorRrn);
            relation.setLinkType(LinkTypeList.SCREEN_FIELD_KEY);
            relation.setTransId(Constants.DELETE_KEY);
            relation.setTransPerformedby(user);
            removeTheValidator(relation);

        } else if (request.getParameter(Constants.MEMBERS_KEY).equals("done") &&
                (request.getParameter(Constants.ITEM_KEY) != null)) {
            // if clieck the done button
            String seqvalue = request.getParameter(Constants.ITEM_KEY);
            int seq = Integer.parseInt(seqvalue);
            int index = seq - 1;
            processDone(seq, index, screen, newSeq, newFieldFlag, newValidatorId, newProperty, newGroupNumber, user,
                        facilityRrn);
        }

        screen.setValidators(getValidators(screen));
        theform.setTransId(Constants.MODIFY_KEY);
        request.setAttribute(SessionNames.SCREEN_KEY, screen);
        return mapping.findForward(Constants.MODIFY_KEY);
    }

    public ActionForward save(ActionMapping mapping, ScreenInfoForm theform,
                              HttpServletRequest request) throws Exception {
        Long facilityRrn = LocalContext.getFacilityRrn();
        String user = LocalContext.getUserId();

        Screen screen = new Screen(theform.getInstanceId(),
                                   getNamedSpace(ObjectList.SCREEN_KEY, LocalContext.getFacilityRrn()),
                                   ObjectList.SCREEN_KEY);

        screen = (Screen) getInstance(screen);
        PropertyUtils.copyProperties(screen, theform);

        screen.setTransPerformedby(user);

        String[] newSeq = request.getParameterValues("seq");
        String[] newFieldFlag = request.getParameterValues("hidFieldFlag");
        String[] newValidatorId = request.getParameterValues("validatorId");
        String[] newProperty = request.getParameterValues("property");
        String[] newGroupNumber = request.getParameterValues("groupNumber");
        screen.setValidators(getValidators(screen));
        saveAllItemsInfo(screen, newSeq, newFieldFlag, newValidatorId, newProperty, newGroupNumber, user, facilityRrn);

        theform.setTransId(Constants.MODIFY_KEY);
        screen.setValidators(getValidators(screen));
        request.setAttribute(SessionNames.SCREEN_KEY, screen);
        return (mapping.findForward(Constants.MODIFY_KEY));
    }

    public ActionForward delete(ActionMapping mapping, ScreenInfoForm theform,
                                HttpServletRequest request) throws Exception {
        String user = LocalContext.getUserId();
        Screen screen = new Screen(theform.getInstanceId(),
                                   getNamedSpace(ObjectList.SCREEN_KEY, LocalContext.getFacilityRrn()),
                                   ObjectList.SCREEN_KEY);

        screen = (Screen) getInstance(screen);
        PropertyUtils.copyProperties(screen, theform);

        screen.setTransPerformedby(user);
        screen.setTransId(Constants.DELETE_KEY);
        theform.setInstanceId("");
        // no matter add or modify, they all execute the same function
        process(screen);

        theform.setTransId(Constants.MODIFY_KEY);
        screen.setValidators(getValidators(screen));
        request.setAttribute(SessionNames.SCREEN_KEY, screen);
        return (mapping.findForward(Constants.SETUP_KEY));
    }

    public ActionForward create(ActionMapping mapping, ScreenInfoForm theform,
                                HttpServletRequest request) throws Exception {
        String user = LocalContext.getUserId();
        Screen screen = new Screen(theform.getInstanceId(),
                                   getNamedSpace(ObjectList.SCREEN_KEY, LocalContext.getFacilityRrn()),
                                   ObjectList.SCREEN_KEY);
        screen = (Screen) getInstance(screen);
        PropertyUtils.copyProperties(screen, theform);

        screen.setTransPerformedby(user);

        screen.setTransId(Constants.CREATE_KEY);

        // no matter add or modify, they all execute the same function
        process(screen);

        List<Validator> validators = null;

        validators = getValidators(screen);

        screen.setValidators(validators);

        theform.setTransId(Constants.MODIFY_KEY);
        screen.setValidators(getValidators(screen));
        request.setAttribute(SessionNames.SCREEN_KEY, screen);
        return (mapping.findForward(Constants.MODIFY_KEY));
    }

    public ActionForward modify(ActionMapping mapping, ScreenInfoForm theform,
                                HttpServletRequest request) throws Exception {
        String user = LocalContext.getUserId();
        Screen screen = new Screen(theform.getInstanceId(),
                                   getNamedSpace(ObjectList.SCREEN_KEY, LocalContext.getFacilityRrn()),
                                   ObjectList.SCREEN_KEY);

        screen = (Screen) getInstance(screen);
        PropertyUtils.copyProperties(screen, theform);
        screen.setTransPerformedby(user);
        screen.setTransId(Constants.MODIFY_KEY);

        // no matter add or modify, they all execute the same function
        process(screen);

        theform.setTransId(Constants.MODIFY_KEY);
        screen.setValidators(getValidators(screen));
        request.setAttribute(SessionNames.SCREEN_KEY, screen);
        return (mapping.findForward(Constants.MODIFY_KEY));
    }

    private void saveAllItemsInfo(Screen screen, String[] newSeq, String[] newFieldFlag, String[] newValidatorId,
                                  String[] newProperty, String[] newGroupNumber, String user, Long facilityRrn) {
        Collection validators = screen.getValidators();
        int size = validators.size();
        log.debug("size =============" + size);
        // if the current page is the last page ,the last item is empty!
        if ((newValidatorId[size - 1] == null) || newValidatorId[size - 1].equals("")) {
            size = size - 1;
        }
        log.debug("size =============" + size);
        List relations = new ArrayList();
        ArrayList temps = new ArrayList();

        // save the all items.
        int index = 0;

        while (index < size) {
            Validator validator = null;
            validator = new Validator();
            validator.setFieldFlag(newFieldFlag[index]);
            validator.setValidatorRrn(this.getValidatorRrn(newValidatorId[index], newFieldFlag[index], facilityRrn));
            validator.setSeq(Integer.parseInt(newSeq[index]));
            validator.setValidatorId(newValidatorId[index]);
            validator.setProperty(newProperty[index]);
            validator.setGroupNumber(newGroupNumber[index]);
            Assert.isFalse(validator.getValidatorRrn() <= 0,
                           Errors.create().key(MessageIdList.SCREEN_MISSING_VALIDATOR_ID)
                                 .content("validator Id为空或者没有validator " + "Id,seq" + "={}!").args((index + 1))
                                 .build());

            temps.add(validator);

            index++;
        }

        // reload the info.
        Comp comp = new Comp();
        Collections.sort(temps, comp);

        Iterator it = temps.iterator();
        int i = 0;

        while (it.hasNext()) {
            Validator item = (Validator) it.next();
            item.setSequenceNumber(null);
            Relation relation = this.linkRelation(screen.getInstanceRrn(), item, user, facilityRrn);
            relations.add(relation);
        }

        saveAllRelations(relations);

        screen.setValidators(getValidators(screen));
    }

    private void saveAllRelations(Collection relations) {
        sysService.reBuilddValidatorsOfScreen(relations);
    }

    private Relation linkRelation(Long screenRrn, Validator validator, String user, Long facilityRrn) {
        Relation relation = new Relation();
        relation.setFromRrn(screenRrn);
        relation.setToRrn(validator.getValidatorRrn());
        relation.setLinkType(LinkTypeList.SCREEN_FIELD_KEY);
        relation.setSequenceNumber(validator.getSequenceNumber());
        relation.setAttributedata1(validator.getProperty());
        relation.setAttributedata2(validator.getGroupNumber());
        relation.setAttributedata3(this.getValidatorAttribute3(validator, facilityRrn));
        relation.setTransPerformedby(user);

        log.debug("relation torrn = " + relation.getFromRrn() + "sequence = " + relation.getSequenceNumber() + " " +
                          "attribute3 ->" + relation.getAttributedata3() + " validator->" + validator.getValidatorId());

        return relation;
    }

    private void removeTheValidator(Relation relation) {
        sysService.removeValidatorFromScreen(relation);
    }

    private void processDone(int seq, int index, Screen screen, String[] newSeq, String[] newFieldFlag,
                             String[] newValidatorId, String[] newProperty, String[] newGroupNumber, String user,
                             Long facilityRrn) {
        String fieldFlag;

        // get the current flag.
        if ((newFieldFlag == null) || (index >= newFieldFlag.length)) {
            fieldFlag = "off";
        } else {
            fieldFlag = newFieldFlag[index];
        }

        if (seq != screen.getValidators().size()) {
            Assert.isFalse(newValidatorId[index] == null || newValidatorId[index].equals(""),
                           Errors.create().key(MessageIdList.SCREEN_MISSING_VALIDATOR_ID)
                                 .content("validator Id为空或者没有validator Id,seq={}!").args(seq).build());
        }

        Iterator it = screen.getValidators().iterator();
        Validator validator = null;

        // select the current item
        while (it.hasNext()) {
            validator = (Validator) it.next();

            if (validator.getSequenceNumber().intValue() == (seq - 1)) {
                break;
            }
        }

        // get the relation.
        log.debug("validatorRrn = " + validator.getValidatorRrn());

        Collection relations = buildRelation(screen, validator, newSeq[index], fieldFlag, newValidatorId[index],
                                             newProperty[index], newGroupNumber[index], user, facilityRrn);

        // if the relation is null ,the id may be not existed.
        Assert.isFalse(relations == null,
                       Errors.create().key(MessageIdList.SYSTEM_INSTANCE_NOT_FOUND).content("{} 没有找到对象!")
                             .args("Validator The seq = {}", seq).build());

        log.debug("dsdsafsdf" + relations.size());

        Iterator it2 = relations.iterator();

        while (it2.hasNext()) {
            Relation relation = (Relation) it2.next();
            Validator temp = getValidatorBySequenceNumber(screen.getValidators(), relation.getSequenceNumber());
            if ((temp.getFieldFlag() != null) && (!temp.getFieldFlag().equals("N/A"))) {
                // else is update the row
                relation.setTransId(Constants.MODIFY_KEY);
                relation.setTransPerformedby(user);
                updateValidator(relation, temp);
                log.debug("update............................................");
            } else {
                // if the row is the last row.
                relation.setTransId(Constants.CREATE_KEY);
                relation.setTransPerformedby(user);
                addValidator(relation);
                log.debug("add................................................");
            }
        }
    }

    private void addValidator(Relation relation) {
        sysService.addValidatorToScreen(relation);
    }

    private void updateValidator(Relation relation, Validator validator) {
        sysService.updateValidatorOfScreen(relation, validator);
    }

    //
    private Collection buildRelation(Screen screen, Validator validator, String newSeq, String newFieldFlag,
                                     String newValidatorId, String newProperty, String newGroupNumber, String user,
                                     Long facilityRrn) {
        Collection doneRelations = new ArrayList();

        Relation relation = new Relation();
        long validatorRrn = 0;
        Field field = null;
        String attribute3 = "";
        String validatorId = newValidatorId.trim().toUpperCase();
        validatorRrn = this.getValidatorRrn(validatorId, newFieldFlag, facilityRrn);

        // if this validator is not existed reutrn null;
        if (validatorRrn <= 0) {
            return null;
        }

        if (newFieldFlag.equals("on")) {
            field = new Field(validatorId, getNamedSpace(ObjectList.FIELD_KEY, facilityRrn), ObjectList.FIELD_KEY);
            field = (Field) getInstance(field);

            if (field.getLabelRrn() != null) {
                attribute3 = field.getLabelRrn().toString();
            }
        } else {
            attribute3 = (new Long(validatorRrn)).toString();
        }

        ArrayList arrayList = (ArrayList) screen.getValidators();
        int size = arrayList.size();

        int sequence = Math.abs(Integer.valueOf(newSeq).intValue());

        if (sequence <= 0) {
            sequence = 1;
        }

        if (sequence > size - 1) {
            if ((validator.getFieldFlag() == null) || (validator.getFieldFlag().equals("N/A"))) {
                sequence = size;
            } else {
                sequence = size - 1;
            }
        }

        // calculate the sequence value
        if (size < 2) {
            doneRelations.add(this.linkRelation(screen.getInstanceRrn(), validatorRrn, new Integer(0), newProperty,
                                                newGroupNumber, attribute3, user));
        } else {
            // log.debug("flag = " + (sequence == validator.getSeq()));

            if (sequence == validator.getSeq()) {
                Integer sequenceNumber = null;

                if (validator.getSequenceNumber() == null) {
                    sequenceNumber = new Integer(
                            ((Validator) arrayList.get(size - 2)).getSequenceNumber().intValue() + seqStep);
                } else {
                    sequenceNumber = validator.getSequenceNumber();
                }

                doneRelations.add(this.linkRelation(screen.getInstanceRrn(), validatorRrn, sequenceNumber, newProperty,
                                                    newGroupNumber, attribute3, user));
                validator.setSeq(sequenceNumber.intValue() + 1);
                validator.setSequenceNumber(sequenceNumber);
            } else {
                int j = validator.getSeq();
                Validator one = validator;
                log.debug("j = " + j);

                int i = 0;

                if (sequence > j) {
                    for (i = sequence; i > j; i--) {
                        doneRelations.add(this.linkRelation(screen.getInstanceRrn(), one.getValidatorRrn(),
                                                            new Integer(i - 1), one.getProperty(), one.getGroupNumber(),
                                                            this.getValidatorAttribute3(one, facilityRrn), user));
                        one.setSeq(i);
                        one.setSequenceNumber(new Integer(i - 1));

                        Object temp = arrayList.get(i - 1);
                        arrayList.set(i - 1, one);
                        one = (Validator) temp;
                    }
                } else {
                    for (i = sequence; i < j; i++) {
                        log.debug("i = " + i);
                        doneRelations.add(this.linkRelation(screen.getInstanceRrn(), one.getValidatorRrn(),
                                                            new Integer(i - 1), one.getProperty(), one.getGroupNumber(),
                                                            this.getValidatorAttribute3(one, facilityRrn), user));
                        one.setSeq(i);
                        one.setSequenceNumber(new Integer(i - 1));
                        Object temp = arrayList.get(i - 1);
                        arrayList.set(i - 1, one);
                        one = (Validator) temp;
                    }
                }
                arrayList.set(i - 1, one);
                one.setSeq(i);
                one.setSequenceNumber(new Integer(i - 1));
                doneRelations.add(this.linkRelation(screen.getInstanceRrn(), one.getValidatorRrn(), new Integer(i - 1),
                                                    one.getProperty(), one.getGroupNumber(),
                                                    this.getValidatorAttribute3(one, facilityRrn), user));
            }
        }
        return doneRelations;
    }

    private long getValidatorRrn(String validatorId, String fieldFlag, Long facilityRrn) {
        long validatorRrn = 0;

        log.debug("validatorId->" + validatorId);

        if (fieldFlag.equals("on")) {
            Field field = new Field(validatorId, getNamedSpace(ObjectList.FIELD_KEY, facilityRrn),
                                    ObjectList.FIELD_KEY);
            field = (Field) getInstance(field);
            validatorRrn = field.getInstanceRrn();
        } else {
            Label label = new Label(validatorId, getNamedSpace(ObjectList.LABEL_KEY, facilityRrn),
                                    ObjectList.LABEL_KEY);
            validatorRrn = baseService.getNamedObjectRrn(label);
        }

        return validatorRrn;
    }

    private Relation linkRelation(Long screenRrn, Long validatorRrn, Integer sequenceNumber, String property,
                                  String groupNumber, String attribute3, String user) {
        Relation relation = new Relation();
        relation.setFromRrn(screenRrn);
        relation.setToRrn(validatorRrn);
        relation.setLinkType(LinkTypeList.SCREEN_FIELD_KEY);
        relation.setSequenceNumber(sequenceNumber);
        relation.setAttributedata1(property);
        relation.setAttributedata2(groupNumber);
        relation.setAttributedata3(attribute3);
        relation.setTransPerformedby(user);
        log.debug("relation torrn = " + validatorRrn + "sequence = " + sequenceNumber + " attribute3 ->" + attribute3);

        return relation;
    }

    private String getValidatorAttribute3(Validator validator, Long facilityRrn) {
        String attribute3 = null;
        Field field = null;

        if (validator.getFieldFlag().equals("on")) {
            field = new Field(validator.getValidatorId(), getNamedSpace(ObjectList.FIELD_KEY, facilityRrn),
                              ObjectList.FIELD_KEY);
            field = (Field) getInstance(field);

            if (field.getLabelRrn() != null) {
                attribute3 = field.getLabelRrn().toString();
            }
        } else {
            attribute3 = new Long(validator.getValidatorRrn()).toString();
        }

        return attribute3;
    }

    private Validator getValidatorBySequenceNumber(Collection validators, Integer seq) {
        Iterator it = validators.iterator();
        Validator validator = null;

        // select the current item
        log.debug("size = " + validators.size());

        while (it.hasNext()) {
            validator = (Validator) it.next();

            if (validator.getSequenceNumber().equals(seq)) {
                return validator;
            }
        }

        return null;
    }

    class Comp implements Comparator {

        public int compare(Object o1, Object o2) {
            Validator v1 = (Validator) o1;
            Validator v2 = (Validator) o2;

            if (v1.getSeq() > v2.getSeq()) {
                return 1;
            } else if (v1.getSeq() < v2.getSeq()) {
                return -1;
            } else {
                return 0;
            }
        }

        public boolean equals(Object obj) {
            return obj == this;
        }

    }

}

/*
 * Modification Log Log No : Name : Modified Date: Description :
 */