/* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ 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 subValMap; private static char SEPARATOR = ','; private static char EQUALS = '='; private String content = null; protected SubVals(SubVals sv, String c) { this(sv, c, true); } protected SubVals(SubVals sv, String c, boolean merge) { SubVals subvals; if (merge) { SubVals vsv = new SubVals(c); if (sv != null && sv.getSubValMap() != null) { for (String key : sv.getSubValMap().keySet()) { vsv.put(key, sv.get(key)); } } if (sv != null && sv.getIndex() > 0) { vsv.index = sv.getIndex(); } subvals = vsv; } else { // replace subvals = sv; } if (subvals == null) { this.subValMap = new HashMap<>(); } else { this.subValMap = subvals == null ? new HashMap<>() : subvals.getSubValMap(); this.index = subvals.getIndex(); } this.content = c; } protected SubVals(String item) { if (subValMap == null) subValMap = new HashMap<>(); 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))) { 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 this.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) { subValMap.put(key, val); } public boolean notSet() { // notSet is true if content present but nonsensical return index == NOTSET && (subValMap == null || subValMap.size() == 0); } public String getWithSubstitutions(ArgParser ap, String id, String key) { return ap.makeSubstitutions(subValMap.get(key), id); } public String get(String key) { return subValMap.get(key); } public boolean has(String key) { return subValMap.containsKey(key); } public int getIndex() { return index; } public String getContent() { return content; } protected Map getSubValMap() { return subValMap; } public String toString() { if (subValMap == null && getIndex() == NOTSET) return ""; StringBuilder sb = new StringBuilder(); List entries = new ArrayList<>(); subValMap.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(); } }