package com.plectix.simulator.util; import java.io.FileNotFoundException; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import com.plectix.simulator.parser.EasyReader; import com.plectix.simulator.parser.GeneralReader; public class CorrectionsDataParser extends GeneralReader<Map<String, SortedSet<Long>>> { private static class ParseOptions { private boolean myNot = false; private boolean myAdd = true; private boolean myAnd = false; private ConnectionType myConnectionType = ConnectionType.EMPTY; public ConnectionType getConnectionType() { return myConnectionType; } public void setConnectionType(ConnectionType type) { myConnectionType = type; } public void resetFlags() { myNot = false; myAnd = false; myConnectionType = ConnectionType.EMPTY; } public boolean isAnd() { return myAnd; } public void setAnd(boolean myAnd) { this.myAnd = myAnd; } public boolean isNot() { return myNot; } public void setNot(boolean myNot) { this.myNot = myNot; } public boolean isAdd() { return myAdd; } public void setAdd(boolean myAdd) { this.myAdd = myAdd; } } private enum ConnectionType { FIND_A, FIND_B, LINK_AA, EMPTY; } private EasyReader reader = getReader(); public CorrectionsDataParser(String path) throws FileNotFoundException { super(path); } private void fill(Set<Long> set1, Set<Long> set2) { set1.clear(); set1.addAll(set2); } private void connect(Set<Long> set, ConnectionType type) { switch (type) { case FIND_A: { fill(set, GreatFileUtility.findAndAddAPart(set)); break; } case FIND_B: { fill(set, GreatFileUtility.findAndAddBPart(set)); break; } case LINK_AA: { fill(set, GreatFileUtility.findAndAddAALink(set)); break; } default: } } private void addOrRemoveAll(Set<Long> set1, Set<Long> set2, ParseOptions options) { boolean not = options.isNot(); boolean add = options.isAdd(); boolean and = options.isAnd(); ConnectionType connectionType = options.getConnectionType(); Set<Long> set = new TreeSet<Long>(); if (and) { if (!not) { set.addAll(set2); } else { set.addAll(GreatFileUtility.not(set2)); } connect(set, connectionType); fill(set1, SetUtilities.and(set1, set)); } else { if (!not) { set.addAll(set2); } else { set.addAll(GreatFileUtility.not(set2)); } connect(set, connectionType); if (add) { set1.addAll(set); } else { set1.removeAll(set); } } } private void processData(Set<Long> set, String command, String currentName, ParseOptions options) { switch (CorrectionsDataCommand.getByName(command)) { case GET_ALL_A: addOrRemoveAll(set, GreatFileUtility.allA(), options); break; case GET_ALL_B: addOrRemoveAll(set, GreatFileUtility.allB(), options); break; case GET_ALL_AA: addOrRemoveAll(set, GreatFileUtility.allAA(), options); break; case GET_ALL_X_INTERNAL: addOrRemoveAll(set, GreatFileUtility.allXInternal(), options); break; case GET_ALL_Y_INTERNAL: addOrRemoveAll(set, GreatFileUtility.allYInternal(), options); break; case GET_ALL_X_LINKED: addOrRemoveAll(set, GreatFileUtility.allXLinked(), options); break; case GET_ALL_Y_LINKED: addOrRemoveAll(set, GreatFileUtility.allYLinked(), options); break; case GET_ALL_K_INTERNAL: addOrRemoveAll(set, GreatFileUtility.allKInternal(), options); break; case GET_ALL_L_INTERNAL: addOrRemoveAll(set, GreatFileUtility.allLInternal(), options); break; case GET_ALL_Y: addOrRemoveAll(set, GreatFileUtility.allY(), options); break; case GET_ALL_L: addOrRemoveAll(set, GreatFileUtility.allL(), options); break; case GET_ALL_K_LINKED: addOrRemoveAll(set, GreatFileUtility.allKLinked(), options); break; case GET_ALL_L_LINKED: addOrRemoveAll(set, GreatFileUtility.allLLinked(), options); break; case GET_ALL_A_DOUBLE_LINKED: addOrRemoveAll(set, GreatFileUtility.allAADoubleLinked(), options); break; default: } } @Override protected Map<String, SortedSet<Long>> unsafeRead() { Map<String, SortedSet<Long>> map = new LinkedHashMap<String, SortedSet<Long>>(); String line = ""; String currentName = ""; SortedSet<Long> set = new TreeSet<Long>(); boolean flag = false; ParseOptions options = new ParseOptions(); while (line != null) { if (line.startsWith("#name ")) { // flush if (!flag) { flag = true; } else { map.put(currentName, set); set = new TreeSet<Long>(); } currentName = line.substring(6); options.setAdd(true); } else if (line.startsWith("#use ")) { String name = line.substring(5); SortedSet<Long> temp = map.get(name); if (temp != null) { addOrRemoveAll(set, temp, options); } } else if (line.startsWith("NO y")) { addOrRemoveAll(set, GreatFileUtility.allWithNoY(), options); } else if (line.startsWith("INCL B")) { connect(set, ConnectionType.FIND_B); } else if (line.startsWith("INCL A")) { connect(set, ConnectionType.FIND_A); } else if (line.startsWith("ALL")) { String command = line.substring(0, 6); processData(set, command, currentName, options); } else if (line.startsWith("MINUS")) { options.setAdd(false); } else if (line.startsWith("COMPL A")) { options.setConnectionType(ConnectionType.FIND_A); line = line.substring(8); continue; } else if (line.startsWith("LINK ALL A")) { connect(set, ConnectionType.LINK_AA); } else if (line.startsWith("LINK A")) { options.setConnectionType(ConnectionType.LINK_AA); line = line.substring(7); continue; } else if (line.startsWith("COMPL B")) { options.setConnectionType(ConnectionType.FIND_B); line = line.substring(8); continue; } else if (line.startsWith("AND")) { options.setAnd(true); line = line.substring(4); continue; } else if (line.startsWith("NOT")) { options.setNot(true); line = line.substring(4); continue; } else { addOrRemoveAll(set, GreatFileUtility.fillByLine(line), options); } options.resetFlags(); line = reader.getLine(); } return map; } }