package jalview.bin.argparser; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import jalview.bin.Console; /** * A helper class to parse a string of the possible forms "content" * "[index]content", "[keyName=keyValue]content" and return the integer index, * the strings keyName and keyValue, and the content after the square brackets * (if present). Values not set `will be -1 or null. */ public class SubVals { public static int NOTSET = -1; private int index = NOTSET; private Map subVals = null; private static char SEPARATOR = ';'; private static char EQUALS = '='; private String content = null; public SubVals(SubVals sv, String c) { if (sv != null) { this.subVals = sv.getSubValsMap(); this.index = sv.getIndex(); } this.content = c; } public SubVals(String item) { this.parseVals(item); } public void parseVals(String item) { if (item == null) return; if (item.indexOf('[') == 0 && item.indexOf(']') > 1) { int openBracket = 0; int closeBracket = item.indexOf(']'); String subvalsString = item.substring(openBracket + 1, closeBracket); this.content = item.substring(closeBracket + 1); boolean setIndex = false; for (String subvalString : subvalsString .split(Character.toString(SEPARATOR))) { if (subVals == null) subVals = new HashMap<>(); int equals = subvalString.indexOf(EQUALS); if (equals > -1) { this.put(subvalString.substring(0, equals), subvalString.substring(equals + 1)); } else { try { this.index = Integer.parseInt(subvalString); setIndex = true; } catch (NumberFormatException e) { // store this non-numeric key as a "true" value subVals.put(subvalString, "true"); } } } if (!setIndex) this.index = NOTSET; else Console.debug("SubVals from '" + subvalsString + "' has index " + this.index + " set"); } else { this.content = item; } } protected void put(String key, String val) { if (subVals == null) subVals = new HashMap<>(); subVals.put(key, val); } public boolean notSet() { // notSet is true if content present but nonsensical return index == NOTSET && subVals == null; } public String get(String key) { return subVals == null ? null : subVals.get(key); } public boolean has(String key) { return subVals == null ? false : subVals.containsKey(key); } public int getIndex() { return index; } public String getContent() { return content; } protected Map getSubValsMap() { return subVals; } public String toString() { if (subVals == null && getIndex() == NOTSET) return ""; StringBuilder sb = new StringBuilder(); List entries = new ArrayList<>(); subVals.entrySet().stream().forEachOrdered( m -> entries.add(m.getValue().equals("true") ? m.getKey() : new StringBuilder().append(m.getKey()).append(EQUALS) .append(m.getValue()).toString())); if (getIndex() != NOTSET) entries.add(Integer.toString(getIndex())); sb.append('['); sb.append(String.join(Character.toString(SEPARATOR), entries)); sb.append(']'); return sb.toString(); } }