Merge branch 'releases/Release_2_11_3_Branch'
[jalview.git] / src / jalview / bin / argparser / SubVals.java
index e6a7cb2..9723c9a 100644 (file)
@@ -1,6 +1,28 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ * 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;
@@ -13,18 +35,64 @@ import jalview.bin.Console;
  */
 public class SubVals
 {
-  private static int NOTSET = -1;
+  public static int NOTSET = -1;
 
   private int index = NOTSET;
 
-  private Map<String, String> subVals = null;
+  private Map<String, String> subValMap;
+
+  private static char SEPARATOR = ',';
 
-  private static char SEPARATOR = ';';
+  private static char EQUALS = '=';
 
   private String content = null;
 
-  public SubVals(String item)
+  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);
   }
 
@@ -42,11 +110,9 @@ public class SubVals
       for (String subvalString : subvalsString
               .split(Character.toString(SEPARATOR)))
       {
-        int equals = subvalString.indexOf('=');
+        int equals = subvalString.indexOf(EQUALS);
         if (equals > -1)
         {
-          if (subVals == null)
-            subVals = new HashMap<>();
           this.put(subvalString.substring(0, equals),
                   subvalString.substring(equals + 1));
         }
@@ -59,7 +125,7 @@ public class SubVals
           } catch (NumberFormatException e)
           {
             // store this non-numeric key as a "true" value
-            subVals.put(subvalsString, "true");
+            this.put(subvalString, "true");
           }
         }
       }
@@ -77,25 +143,28 @@ public class SubVals
 
   protected void put(String key, String val)
   {
-    if (subVals == null)
-      subVals = new HashMap<>();
-    subVals.put(key, val);
+    subValMap.put(key, val);
   }
 
   public boolean notSet()
   {
     // notSet is true if content present but nonsensical
-    return index == NOTSET && subVals == null;
+    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 subVals == null ? null : subVals.get(key);
+    return subValMap.get(key);
   }
 
   public boolean has(String key)
   {
-    return subVals == null ? false : subVals.containsKey(key);
+    return subValMap.containsKey(key);
   }
 
   public int getIndex()
@@ -108,15 +177,27 @@ public class SubVals
     return content;
   }
 
+  protected Map<String, String> getSubValMap()
+  {
+    return subValMap;
+  }
+
   public String toString()
   {
-    StringBuilder sb = new StringBuilder();
-    if (subVals == null)
+    if (subValMap == null && getIndex() == NOTSET)
       return "";
-    for (Map.Entry<String, String> m : subVals.entrySet())
-    {
-      sb.append(m.getKey()).append('=').append(m.getValue()).append("\n");
-    }
+
+    StringBuilder sb = new StringBuilder();
+    List<String> 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();
   }
 }
\ No newline at end of file