JAL-629 Tests for FileUtils. Tidying counter substitutions. Fixing PAE opening.
[jalview.git] / src / jalview / bin / argparser / SubVals.java
1 package jalview.bin.argparser;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import jalview.bin.Console;
9
10 /**
11  * A helper class to parse a string of the possible forms "content"
12  * "[index]content", "[keyName=keyValue]content" and return the integer index,
13  * the strings keyName and keyValue, and the content after the square brackets
14  * (if present). Values not set `will be -1 or null.
15  */
16 public class SubVals
17 {
18   public static int NOTSET = -1;
19
20   private int index = NOTSET;
21
22   private Map<String, String> subVals = null;
23
24   private static char SEPARATOR = ';';
25
26   private static char EQUALS = '=';
27
28   private String content = null;
29
30   public SubVals(SubVals sv, String c)
31   {
32     if (sv != null)
33     {
34       this.subVals = sv.getSubValsMap();
35       this.index = sv.getIndex();
36     }
37     this.content = c;
38   }
39
40   public SubVals(String item)
41   {
42     this.parseVals(item);
43   }
44
45   public void parseVals(String item)
46   {
47     if (item == null)
48       return;
49     if (item.indexOf('[') == 0 && item.indexOf(']') > 1)
50     {
51       int openBracket = 0;
52       int closeBracket = item.indexOf(']');
53       String subvalsString = item.substring(openBracket + 1, closeBracket);
54       this.content = item.substring(closeBracket + 1);
55       boolean setIndex = false;
56       for (String subvalString : subvalsString
57               .split(Character.toString(SEPARATOR)))
58       {
59         if (subVals == null)
60           subVals = new HashMap<>();
61         int equals = subvalString.indexOf(EQUALS);
62         if (equals > -1)
63         {
64           this.put(subvalString.substring(0, equals),
65                   subvalString.substring(equals + 1));
66         }
67         else
68         {
69           try
70           {
71             this.index = Integer.parseInt(subvalString);
72             setIndex = true;
73           } catch (NumberFormatException e)
74           {
75             // store this non-numeric key as a "true" value
76             subVals.put(subvalString, "true");
77           }
78         }
79       }
80       if (!setIndex)
81         this.index = NOTSET;
82       else
83         Console.debug("SubVals from '" + subvalsString + "' has index "
84                 + this.index + " set");
85     }
86     else
87     {
88       this.content = item;
89     }
90   }
91
92   protected void put(String key, String val)
93   {
94     if (subVals == null)
95       subVals = new HashMap<>();
96     subVals.put(key, val);
97   }
98
99   public boolean notSet()
100   {
101     // notSet is true if content present but nonsensical
102     return index == NOTSET && subVals == null;
103   }
104
105   public String get(String key)
106   {
107     return subVals == null ? null : subVals.get(key);
108   }
109
110   public boolean has(String key)
111   {
112     return subVals == null ? false : subVals.containsKey(key);
113   }
114
115   public int getIndex()
116   {
117     return index;
118   }
119
120   public String getContent()
121   {
122     return content;
123   }
124
125   protected Map<String, String> getSubValsMap()
126   {
127     return subVals;
128   }
129
130   public String toString()
131   {
132     if (subVals == null && getIndex() == NOTSET)
133       return "";
134
135     StringBuilder sb = new StringBuilder();
136     List<String> entries = new ArrayList<>();
137     subVals.entrySet().stream().forEachOrdered(
138             m -> entries.add(m.getValue().equals("true") ? m.getKey()
139                     : new StringBuilder().append(m.getKey()).append(EQUALS)
140                             .append(m.getValue()).toString()));
141     if (getIndex() != NOTSET)
142       entries.add(Integer.toString(getIndex()));
143     sb.append('[');
144     sb.append(String.join(Character.toString(SEPARATOR), entries));
145     sb.append(']');
146     return sb.toString();
147   }
148 }