# AttributeQueryManagerImpl.java

    package com.mycim.server.spec.manager.impl;

    import com.mycim.server.ctx.exec.manager.ResequenceContextValueManager;
    import com.mycim.server.prp.manager.ProcessReworkManager;
    import com.mycim.server.spec.manager.AttributeQueryManager;
    import com.mycim.server.spec.manager.ProcessSpecItemManager;
    import com.mycim.valueobject.prp.ContextValueUtils;
    import com.mycim.valueobject.prp.ProcessAttributeDto;
    import com.mycim.valueobject.prp.ProcessFlowSeqDto;
    import com.mycim.valueobject.prp.ProcessReworkDto;
    import com.mycim.valueobject.prp.ProcessSpecItem;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.lang.Override;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    /**
     * @author Qiansheng.Wang
     * @since 2020-08-18
     */
    @Service
    @Transactional
    public class AttributeQueryManagerImpl implements AttributeQueryManager {

        @Autowired
        ProcessSpecItemManager processSpecItemManager;

        @Autowired
        ProcessReworkManager processReworkManager;

        @Autowired
        ResequenceContextValueManager resequenceContextValueManager;

        @Override
        public Map<String, ProcessAttributeDto> getProcessAttributesFromTargetVersion(Long processRrn,
                                                                                      Integer processVersion,
                                                                                      Integer targetProcessVersion) {
            Map<String, ProcessAttributeDto> result = new HashMap<>();

            setReworkInfoToProcessAttribute(processRrn, processVersion, result);
            setFlowSeqToProcessAttribute(processRrn, processVersion, targetProcessVersion, result);

            ProcessAttributeDto processAttribute;

            for (ProcessSpecItem processSpecItem : processSpecItemManager
                    .getProcessSpecItemsForActive(processRrn, targetProcessVersion)) {

                String key = ContextValueUtils
                        .buildKeyByProcess(processSpecItem.getProcessRrn(), processVersion, processSpecItem.getRouteRrn(),
                                           processSpecItem.getOperationRrn());

                processAttribute = getProcessAttribute(result, key);

                processAttribute.setProcessSpecItem(processSpecItem);
            }

            return result;

        }

        @Override
        public Map<String, ProcessAttributeDto> getProcessAttributesWithSetup(Long processRrn, Integer processVersion) {
            Map<String, ProcessAttributeDto> result = new HashMap<>();

            setReworkInfoToProcessAttribute(processRrn, processVersion, result);

            ProcessAttributeDto processAttribute;

            for (ProcessSpecItem processSpecItem : processSpecItemManager.getProcessSpecItems(processRrn, processVersion)) {

                String key = ContextValueUtils
                        .buildKeyByProcess(processSpecItem.getProcessRrn(), processSpecItem.getProcessVersion(),
                                           processSpecItem.getRouteRrn(), processSpecItem.getOperationRrn());

                processAttribute = getProcessAttribute(result, key);

                processAttribute.setProcessSpecItem(processSpecItem);
            }

            return result;
        }

        private void setReworkInfoToProcessAttribute(Long processRrn, Integer processVersion,
                                                     Map<String, ProcessAttributeDto> map) {
            ProcessAttributeDto attr;

            List<ProcessReworkDto> processReworks = processReworkManager
                    .getProcessReworksForProcess(processRrn, processVersion);

            for (ProcessReworkDto processRework : processReworks) {
                String key = ContextValueUtils
                        .buildKeyByProcess(processRework.getProcessRrn(), processVersion, processRework.getRouteRrn(),
                                           processRework.getOperationRrn());

                attr = getProcessAttribute(map, key);

                attr.setProcessRework(processRework);
            }
        }

        private void setFlowSeqToProcessAttribute(Long processRrn, Integer processVersion, Integer targetProcessVersion,
                                                  Map<String, ProcessAttributeDto> map) {
            List<ProcessFlowSeqDto> processFlowSeqs = resequenceContextValueManager
                    .getProcessFlowSeqsForProcess(processRrn, targetProcessVersion);
            for (ProcessFlowSeqDto dto : processFlowSeqs) {
                String key = ContextValueUtils
                        .buildKeyByProcess(dto.getProcessRrn(), processVersion, dto.getRouteRrn(), dto.getOperationRrn());

                ProcessAttributeDto attr = getProcessAttribute(map, key);

                ProcessSpecItem processSpecItem = attr
                        .getProcessSpecItem(dto.getProcessRrn(), processVersion, dto.getRouteRrn(), dto.getOperationRrn());

                processSpecItem.setFlowSeq(dto.getFlowSeq());
            }
        }

        private ProcessAttributeDto getProcessAttribute(Map<String, ProcessAttributeDto> map, String key) {
            ProcessAttributeDto obj;
            obj = map.get(key);
            if (obj == null) {
                obj = new ProcessAttributeDto();
                map.put(key, obj);
            }
            return obj;
        }

        @Override
        public Map<String, String> getAllFlowSeqMap(Long processRrn, Integer processVersion) {
            Map<String, String> flowSeqInfo = new HashMap<>();
            for (ProcessFlowSeqDto dto : resequenceContextValueManager
                    .getProcessFlowSeqsForProcess(processRrn, processVersion)) {
                flowSeqInfo.put(ContextValueUtils.buildKeyByProcess(processRrn, processVersion, dto.getRouteRrn(),
                                                                    dto.getOperationRrn()), dto.getFlowSeq());
            }
            return flowSeqInfo;
        }

    }