# QueryMapCache.java

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

    import com.mycim.framework.context.spring.SpringContext;
    import com.mycim.framework.logging.Logger;
    import com.mycim.framework.logging.LoggerFactory;
    import com.mycim.framework.utils.lang.StringUtils;
    import com.mycim.framework.utils.lang.collections.CollectionUtils;
    import com.mycim.framework.utils.lang.collections.MapUtils;
    import com.mycim.framework.utils.lang.math.NumberUtils;
    import com.mycim.server.base.manager.NamedObjectManager;
    import com.mycim.server.spec.manager.ProcessSpecItemManager;
    import com.mycim.server.system.manager.ReferenceFileManager;
    import com.mycim.server.wip.dao.LotQueryDAO;
    import com.mycim.valueobject.ObjectList;
    import com.mycim.valueobject.prp.ProcessSpecItem;
    import com.mycim.valueobject.prp.ProcessSpecItemDto;
    import com.mycim.valueobject.sys.ReferenceFileDetail;

    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;

    public class QueryMapCache {

        private final long faciltiyRrn;

        private final long stepDescContext;

        private final long recipeContextRrn;

        private final long reticleContextRrn;

        private final LotQueryDAO lotQueryDAO = SpringContext.getBean(LotQueryDAO.class);

        private final NamedObjectManager namedObjectManager = SpringContext.getBean(NamedObjectManager.class);

        private final ReferenceFileManager referenceFileManager = SpringContext.getBean(ReferenceFileManager.class);

        private final ProcessSpecItemManager processSpecItemManager = SpringContext.getBean(ProcessSpecItemManager.class);

        private final static Logger logger = LoggerFactory.getLogger(QueryMapCache.class);

        public QueryMapCache(long facilityRrn, long stepDescContext, long recipeContextRrn, long reticleContextRrn) {
            this.faciltiyRrn = facilityRrn;
            this.stepDescContext = stepDescContext;
            this.recipeContextRrn = recipeContextRrn;
            this.reticleContextRrn = reticleContextRrn;
        }

        private final MapCache<String, Map<String, Object>> proContextCache = new MapCache<String, Map<String, Object>>() {

            @Override
            public Map<String, Object> load(String key) {
                String[] keys = StringUtils.splitPreserveAllTokens(key, ',');
                Map<String, Object> result = lotQueryDAO
                        .getProContextActiveDtl(Long.valueOf(keys[0]).longValue(), Long.valueOf(keys[1]).longValue(),
                                                Long.valueOf(keys[2]).longValue(), Integer.valueOf(keys[3]).intValue(),
                                                Long.valueOf(keys[4]).longValue(), Long.valueOf(keys[5]).longValue());
                if (MapUtils.isEmpty(result)) {
                    result = new HashMap<String, Object>();
                    String desc = lotQueryDAO.getStepDesc(stepDescContext, keys[0], keys[1], keys[2], keys[3], keys[4]);
                    result.put("operation_description", StringUtils.isEmpty(desc) ? StringUtils.EMPTY : desc);

                    Long rrn = lotQueryDAO.getRecipeByLot(recipeContextRrn, keys[0], keys[1], keys[2], keys[3], keys[4]);
                    result.put("recipe_rrn", rrn != null ? rrn : 0L);
                }
                return result;
            }

        };

        private final MapCache<String, String> reticleCache = new MapCache<String, String>() {

            @Override
            public String load(String key) {
                String[] keys = StringUtils.splitPreserveAllTokens(key, ',');
                Long familyRrn = lotQueryDAO
                        .getReticleByLot(reticleContextRrn, keys[0], keys[1], keys[2], keys[3], keys[4]);
                if (familyRrn == null || familyRrn == 0) {
                    return StringUtils.EMPTY;
                }
                List<Long> reticles = lotQueryDAO.getReticleByFamily(familyRrn);

                String reticleId = StringUtils.EMPTY;

                if (CollectionUtils.isNotEmpty(reticles)) {
                    for (Long reticleRrn : reticles) {
                        reticleId += namedObjectManager.getInstanceId(reticleRrn);
                    }
                }
                return reticleId;
            }

        };

        private final MapCache<Long, Map<String, String>> carrierCache = new MapCache<Long, Map<String, String>>() {

            @Override
            public Map<String, String> load(Long key) {
                Map<String, String> result = new HashMap<String, String>();
                Map<String, Object> carrierInfo = lotQueryDAO.queryCarrierInfo(key);
                if (MapUtils.isNotEmpty(carrierInfo)) {
                    result.put("podID", namedObjectManager.getInstanceId(MapUtils.getLongValue(carrierInfo, "POD_RRN")));
                }
                return result;
            }

        };

        private final MapCache<Long, String> instanceIdCache = new MapCache<Long, String>() {

            @Override
            public String load(Long key) {
                return namedObjectManager.getInstanceId(key);
            }

        };

        private final MapCache<ProcessSpecItem, String> workAreaCache = new MapCache<ProcessSpecItem, String>() {

            @Override
            public String load(ProcessSpecItem key) {
                ProcessSpecItemDto processSpecItemDto = new ProcessSpecItemDto(key.getProcessRrn(), key.getProcessVersion(),
                                                                               key.getRouteRrn(), key.getOperationRrn());
                ProcessSpecItem processSpecItem = processSpecItemManager.getProcessSpecItemForActive(processSpecItemDto);
                if (processSpecItem != null) {
                    return processSpecItem.getWorkArea();
                }
                // TODO Auto-generated method stub
                return "";
            }

        };

        private final MapCache<String, String> stepEqpGroupCache = new MapCache<String, String>() {

            @Override
            public String load(String key) {
                String[] keys = StringUtils.splitPreserveAllTokens(key, ',');
                return processSpecItemManager.getEqptGroupRrns(NumberUtils.toLong(keys[0]), NumberUtils.toInt(keys[1]),
                                                               NumberUtils.toLong(keys[2]), NumberUtils.toLong(keys[3]));
            }

        };

        private final MapCache<Long, String> eqpGroupEqpIds = new MapCache<Long, String>() {

            @Override
            public String load(Long key) {
                return lotQueryDAO.getEqpIds(key);
            }

        };

        private final MapCache<Long, String> locationCache = new MapCache<Long, String>() {

            @Override
            public String load(Long key) {
                String location = "";
                if (key != null && key > 0) {
                    location = namedObjectManager.getInstanceId(key);
                    if (StringUtils.isEmpty(location)) {
                        location = lotQueryDAO.getLocationId(key);
                    }
                }
                return location;
            }

        };

        private final MapCache<String, String> namedSpaceCache = new MapCache<String, String>() {

            @Override
            public String load(String key) {
                return namedObjectManager.getNamedSpace(faciltiyRrn, key);
            }

        };

        //	private final MapCache<String, String> lotCategoryCache = new MapCache<String, String>() {
        //
        //		public String get(String key) {
        //			if (values.get(key) == null) {
        //				values.putAll(lotQueryDAO.getReferenceCategory());
        //			}
        //			return key;
        //		};
        //
        //		@Override
        //		public String load(String key) {
        //			// TODO Auto-generated method stub
        //			return null;
        //		}
        //
        //	};

        private final MapCache<String, String> mfgEqpGroupCache = new MapCache<String, String>() {

            @Override
            public String load(String key) {
                ReferenceFileDetail referenceFileDetail = new ReferenceFileDetail("$$MFGEQP_GROUP_ID", getNamedSpaceCache()
                        .get(ObjectList.REFERENCE_FILE_KEY), ObjectList.REFERENCE_FILE_KEY);
                if (!StringUtils.equals(key, "empty")) {
                    referenceFileDetail.setKey1Value(key);
                }

                List<ReferenceFileDetail> referenceFileDetailList = referenceFileManager
                        .getReferenceFileDetails(referenceFileDetail.getInstanceRrn());
                if (CollectionUtils.isNotEmpty(referenceFileDetailList)) {
                    return referenceFileDetailList.get(0).getData1Value();
                }

                return StringUtils.EMPTY;
            }

        };

        abstract class MapCache<K, V> {
            protected ConcurrentHashMap<K, V> values = new ConcurrentHashMap<K, V>(50);

            public V get(K key) {
                if (values.get(key) == null) {
                    V value = load(key);
                    if (value != null) {
                        values.put(key, value);
                    }
                }
                return values.get(key);
            }

            public abstract V load(K key);

        }

        private final MapCache<ProcessSpecItem, String> stageIdCache = new MapCache<ProcessSpecItem, String>() {

            @Override
            public String load(ProcessSpecItem key) {
                ProcessSpecItemDto processSpecItemDto = new ProcessSpecItemDto(key.getProcessRrn(), key.getProcessVersion(),
                                                                               key.getRouteRrn(), key.getOperationRrn());
                ProcessSpecItem processSpecItem = processSpecItemManager.getProcessSpecItemForActive(processSpecItemDto);

                if (processSpecItem != null) {
                    return processSpecItem.getStageId();
                }
                // TODO Auto-generated method stub
                return "";
            }

        };

        public MapCache<String, String> getMfgEqpGroupCache() {
            return mfgEqpGroupCache;
        }

        public MapCache<String, String> getNamedSpaceCache() {
            return namedSpaceCache;
        }

        public MapCache<Long, String> getLocationCache() {
            return locationCache;
        }

        public MapCache<Long, String> getInstanceIdCache() {
            return instanceIdCache;
        }

        public MapCache<String, Map<String, Object>> getProContextCache() {
            return proContextCache;
        }

        public MapCache<Long, Map<String, String>> getCarrierCache() {
            return carrierCache;
        }

        public MapCache<Long, String> getEqpGroupEqpIds() {
            return eqpGroupEqpIds;
        }

        public MapCache<String, String> getReticleCache() {
            return reticleCache;
        }

        public MapCache<String, String> getStepEqpGroupCache() {
            return stepEqpGroupCache;
        }

        public MapCache<ProcessSpecItem, String> getWorkAreaCache() {
            return workAreaCache;
        }

        public MapCache<ProcessSpecItem, String> getStageIdCache() {
            return stageIdCache;
        }

        //	public MapCache<String, String> getLotCategoryCache() {
        //		return lotCategoryCache;
        //	}

    }