8e4fe2cefead47bb4775841514923b4e0e43da80
[jalview.git] / src / jalview / bin / argparser / ArgValues.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.bin.argparser;
22
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.stream.Collectors;
28
29 import jalview.bin.Console;
30 import jalview.bin.argparser.Arg.Opt;
31 import jalview.bin.argparser.Arg.Type;
32
33 public class ArgValues
34 {
35   public static final String ID = "id";
36
37   private Arg arg;
38
39   private int argCount = 0;
40
41   private boolean boolValue = false;
42
43   private boolean negated = false;
44
45   private boolean setByWildcard = false;
46
47   private int boolIndex = -1;
48
49   private List<Integer> argsIndexes;
50
51   private List<ArgValue> argValueList;
52
53   private Map<String, ArgValue> idMap = new HashMap<>();
54
55   /*
56    * Type type is only really used by --help-type
57    */
58   private Type type = null;
59
60   protected ArgValues(Arg a)
61   {
62     this.arg = a;
63     this.argValueList = new ArrayList<ArgValue>();
64     this.boolValue = arg.getDefaultBoolValue();
65   }
66
67   protected boolean setByWildcard()
68   {
69     return setByWildcard;
70   }
71
72   protected void setSetByWildcard(boolean b)
73   {
74     setByWildcard = b;
75   }
76
77   public Arg arg()
78   {
79     return arg;
80   }
81
82   protected void setType(Type t)
83   {
84     if (this.arg().hasOption(Opt.HASTYPE))
85       this.type = t;
86   }
87
88   public Type getType()
89   {
90     return type;
91   }
92
93   protected int getCount()
94   {
95     return argCount;
96   }
97
98   protected void incrementCount()
99   {
100     argCount++;
101   }
102
103   protected void setNegated(boolean b, boolean beingSetByWildcard)
104   {
105     // don't overwrite a wildcard set boolean with a non-wildcard set boolean
106     if (boolIndex >= 0 && !this.setByWildcard && beingSetByWildcard)
107       return;
108     this.negated = b;
109   }
110
111   protected boolean isNegated()
112   {
113     return this.negated;
114   }
115
116   protected void setBoolean(Type t, boolean b, int i,
117           boolean beingSetByWildcard)
118   {
119     this.setType(t);
120     // don't overwrite a wildcard set boolean with a non-wildcard set boolean
121     if (boolIndex >= 0 && !this.setByWildcard && beingSetByWildcard)
122       return;
123     this.boolValue = b;
124     this.boolIndex = i;
125     this.setSetByWildcard(beingSetByWildcard);
126   }
127
128   protected boolean getBoolean()
129   {
130     return this.boolValue;
131   }
132
133   @Override
134   public String toString()
135   {
136     if (argValueList == null)
137       return null;
138     StringBuilder sb = new StringBuilder();
139     sb.append(arg.toLongString());
140     if (arg.hasOption(Opt.BOOLEAN) || arg.hasOption(Opt.UNARY))
141       sb.append("Boolean: ").append(boolValue).append("; Default: ")
142               .append(arg.getDefaultBoolValue()).append("; Negated: ")
143               .append(negated).append("\n");
144     if (arg.hasOption(Opt.STRING))
145     {
146       sb.append("Values:");
147       sb.append("'")
148               .append(String
149                       .join("',\n  '",
150                               argValueList.stream().map(av -> av.getValue())
151                                       .collect(Collectors.toList())))
152               .append("'");
153       sb.append("\n");
154     }
155     sb.append("Count: ").append(argCount).append("\n");
156     return sb.toString();
157   }
158
159   protected void addValue(Type type, String val, int argIndex,
160           boolean wildcard)
161   {
162     addArgValue(new ArgValue(arg(), type, val, argIndex), wildcard);
163   }
164
165   protected void addValue(SubVals sv, Type type, String content,
166           int argIndex, boolean wildcard)
167   {
168     addArgValue(new ArgValue(arg(), sv, type, content, argIndex), wildcard);
169   }
170
171   protected void addArgValue(ArgValue av, boolean beingSetByWildcard)
172   {
173     // allow a non-wildcard value to overwrite a wildcard set single value
174     boolean overwrite = !arg.hasOption(Opt.MULTIVALUE) && setByWildcard
175             && !beingSetByWildcard;
176     if ((!arg.hasOption(Opt.MULTIVALUE) && argValueList.size() > 0)
177             && !overwrite)
178       return;
179     if (arg.hasOption(Opt.NODUPLICATEVALUES)
180             && this.containsValue(av.getValue()))
181       return;
182     // new or overwrite if single valued
183     if (argValueList == null || overwrite)
184     {
185       argValueList = new ArrayList<ArgValue>();
186     }
187     SubVals sv = new SubVals(av.getValue());
188     if (sv.has(ID))
189     {
190       String id = sv.get(ID);
191       av.setId(id);
192       idMap.put(id, av);
193     }
194     argValueList.add(av);
195     this.setSetByWildcard(beingSetByWildcard);
196   }
197
198   protected boolean hasValue(String val)
199   {
200     return argValueList.contains(val);
201   }
202
203   protected ArgValue getArgValue()
204   {
205     if (arg.hasOption(Opt.MULTIVALUE))
206       Console.warn("Requesting single value for multi value argument");
207     return argValueList.size() > 0 ? argValueList.get(0) : null;
208   }
209
210   protected List<ArgValue> getArgValueList()
211   {
212     return argValueList;
213   }
214
215   protected boolean hasId(String id)
216   {
217     return idMap.containsKey(id);
218   }
219
220   protected ArgValue getId(String id)
221   {
222     return idMap.get(id);
223   }
224
225   private boolean containsValue(String v)
226   {
227     if (argValueList == null)
228       return false;
229     for (ArgValue av : argValueList)
230     {
231       String val = av.getValue();
232       if (v == null && val == null)
233         return true;
234       if (v == null)
235         continue;
236       if (v.equals(val))
237         return true;
238     }
239     return false;
240   }
241 }