package edu.isi.karma.controller.command.selection; import java.util.Map.Entry; import edu.isi.karma.rep.Row; import edu.isi.karma.rep.Workspace; public class LargeSelection extends Selection { public enum Operation { Union, Intersect, Subtract, Invert } private Selection sourceA; private Selection sourceB; private Operation operation; public LargeSelection(Workspace workspace, String worksheetId, String hTableId, String name, String superSelectionName, Selection sourceA, Selection sourceB, Operation operation) { super(workspace, worksheetId, hTableId, name, superSelectionName); this.sourceA = sourceA; this.sourceB = sourceB; this.operation = operation; if (sourceA != null && sourceA.hasSelectedRowsMethod) hasSelectedRowsMethod = true; if (sourceB != null && sourceB.hasSelectedRowsMethod) hasSelectedRowsMethod = true; populateSelection(); } private void union() { if (sourceA.getStatus() == SelectionStatus.OUT_OF_DATE) sourceA.updateSelection(); if (sourceB.getStatus() == SelectionStatus.OUT_OF_DATE) sourceB.updateSelection(); for (Entry<Row, Boolean> entry : sourceA.getCache().entrySet()) { Boolean valueB = sourceB.getCache().get(entry.getKey()); Boolean valueA = entry.getValue(); if (valueB == null) valueB = false; selectedRowsCache.put(entry.getKey(), valueB | valueA); } evalColumns.addAll(sourceA.evalColumns); evalColumns.addAll(sourceB.evalColumns); selectedRowsColumns.addAll(sourceA.evalColumns); selectedRowsColumns.addAll(sourceB.evalColumns); } private void intersect(){ if (sourceA.getStatus() == SelectionStatus.OUT_OF_DATE) sourceA.updateSelection(); if (sourceB.getStatus() == SelectionStatus.OUT_OF_DATE) sourceB.updateSelection(); for (Entry<Row, Boolean> entry : sourceA.getCache().entrySet()) { Boolean valueB = sourceB.getCache().get(entry.getKey()); Boolean valueA = entry.getValue(); if (valueB == null) selectedRowsCache.put(entry.getKey(), false); else selectedRowsCache.put(entry.getKey(), valueB & valueA); } evalColumns.addAll(sourceA.evalColumns); evalColumns.addAll(sourceB.evalColumns); selectedRowsColumns.addAll(sourceA.evalColumns); selectedRowsColumns.addAll(sourceB.evalColumns); } private void subtract(){ if (sourceA.getStatus() == SelectionStatus.OUT_OF_DATE) sourceA.updateSelection(); if (sourceB.getStatus() == SelectionStatus.OUT_OF_DATE) sourceB.updateSelection(); for (Entry<Row, Boolean> entry : sourceA.getCache().entrySet()) { Boolean valueB = sourceB.getCache().get(entry.getKey()); Boolean valueA = entry.getValue(); if (valueB == null) valueB = false; if (valueB == true && valueA == true) selectedRowsCache.put(entry.getKey(), false); else selectedRowsCache.put(entry.getKey(), valueA); } evalColumns.addAll(sourceA.evalColumns); evalColumns.addAll(sourceB.evalColumns); selectedRowsColumns.addAll(sourceA.evalColumns); selectedRowsColumns.addAll(sourceB.evalColumns); } private void invert(){ if (sourceA.getStatus() == SelectionStatus.OUT_OF_DATE) sourceA.updateSelection(); for (Entry<Row, Boolean> entry : sourceA.getCache().entrySet()) { Boolean valueA = entry.getValue(); selectedRowsCache.put(entry.getKey(), !valueA); } evalColumns.addAll(sourceA.evalColumns); selectedRowsColumns.addAll(sourceA.evalColumns); } private void populateSelection(){ switch(operation) { case Intersect: intersect(); break; case Invert: invert(); break; case Subtract: subtract(); break; case Union: union(); break; } } @Override public void updateSelection(){ if (this.status == SelectionStatus.UP_TO_DATE) return; evalColumns.clear(); selectedRowsColumns.clear(); populateSelection(); this.status = SelectionStatus.UP_TO_DATE; } }