package ru.gazprom.gtnn.minos.models; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import ru.gazprom.gtnn.minos.entity.DivisionNode; import ru.gazprom.gtnn.minos.entity.PositionNode; import ru.gazprom.gtnn.minos.util.DatabaseConnectionKeeper; import ru.gedr.util.tuple.Pair; import com.google.common.cache.LoadingCache; public class PositionInDivisionModel extends BasicModel { public PositionInDivisionModel(DatabaseConnectionKeeper kdb, LoadingCache<Integer, PositionNode> cachePosition, TreeModel division, String sqlLoadPositionIDsForDivision, String patternParentID, boolean flagPositionBeforeSubDivision ) { super(kdb); this.cachePosition = cachePosition; this.division = division; this.sqlLoadPositionIDsForDivision = sqlLoadPositionIDsForDivision; this.patternParentID = patternParentID; this.flagPositionBeforeSubDivision = flagPositionBeforeSubDivision; positionsInDivision = new HashMap<>(); } @Override public Object getRoot() { return division.getRoot(); } @Override public boolean isLeaf(Object arg) { if(arg == null) return true; assert((arg instanceof DivisionNode) || (arg instanceof Pair<?, ?>)) : "PositionInDivisionModel.isLeaf() : arg have incorrect type"; if(arg instanceof Pair<?, ?>) return true; if(arg instanceof DivisionNode) { List<Integer> lst = checkAndLoadPosition( (DivisionNode)arg ); return (division.isLeaf(arg) && (lst.size() == 0)); } return true; } @Override public int getChildCount(Object parent) { if(parent == null) return 0; assert((parent instanceof DivisionNode) || (parent instanceof Pair<?, ?>)) : "PositionInDivisionModel.getChildCount() : parent have incorrect type"; if(parent instanceof Pair<?, ?>) return 0; if(parent instanceof DivisionNode) { List<Integer> lst = checkAndLoadPosition( (DivisionNode)parent ); return division.getChildCount(parent) + lst.size() ; } return 0; } @Override public Object getChild(Object parent, int index) { if(parent == null) return null; assert(parent instanceof DivisionNode) : "PositionInDivisionModel.getChild() : parent have incorrect type"; if(parent instanceof DivisionNode) { DivisionNode node = (DivisionNode)parent; List<Integer> lst = checkAndLoadPosition(node); Object obj = null; try { if(flagPositionBeforeSubDivision) { obj = ( ((0 <= index) && (index < lst.size())) ? new Pair<Integer, PositionNode>(node.divisionID, cachePosition.get(lst.get(index))) : division.getChild(parent, index - lst.size()) ); } else { obj = (((0 <= index) && (index < division.getChildCount(parent))) ? division.getChild(parent, index) : new Pair<Integer, PositionNode>( node.divisionID, cachePosition.get(lst.get(index - division.getChildCount(parent))) ) ); } } catch(Exception e) { e.printStackTrace(); obj = null; } return obj; } return null; } @Override public int getIndexOfChild(Object parent, Object child) { if(parent == null || child == null) return -1; assert((parent instanceof DivisionNode) && ((child instanceof Pair<?, ?>) || (child instanceof DivisionNode)) ) : "PositionInDivisionModel.getIndexOfChild() : parent have incorrect type"; if(parent instanceof Pair<?, ?>) return -1; if(parent instanceof DivisionNode) { DivisionNode node = (DivisionNode)parent; List<Integer> lst = checkAndLoadPosition(node); if(child instanceof DivisionNode) { int ind = division.getIndexOfChild(parent, child); return (flagPositionBeforeSubDivision ? lst.size() + ind : ind); } if(child instanceof Pair<?, ?>) { @SuppressWarnings("unchecked") Pair<Integer, PositionNode> p = (Pair<Integer, PositionNode>)child; int ind = -1; for(int i = 0; i < lst.size(); i++) { if(lst.get(i) == p.getSecond().positionID) { ind = i; break; } } if(ind == -1) return ind; return (flagPositionBeforeSubDivision ? ind : ind + division.getChildCount(parent)); } } return -1; } @Override public void valueForPathChanged(TreePath arg0, Object arg1) { // TODO Auto-generated method stub } private List<Integer> checkAndLoadPosition(DivisionNode dn) { List<Integer> lst = positionsInDivision.get(dn.divisionID); if(lst == null) { lst = loadChildIDs(sqlLoadPositionIDsForDivision, patternParentID, dn.divisionID); positionsInDivision.put(dn.divisionID, lst); } return lst; } private LoadingCache<Integer, PositionNode> cachePosition; private TreeModel division; private String sqlLoadPositionIDsForDivision; private String patternParentID; private boolean flagPositionBeforeSubDivision; private Map<Integer, List<Integer>> positionsInDivision; }