JAL-629 Ensure precedence of named linked ID values over wildcard linked ID set value...
[jalview.git] / src / jalview / bin / argparser / ArgValuesMap.java
1 package jalview.bin.argparser;
2
3 import java.io.File;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
9
10 import jalview.bin.argparser.Arg.Opt;
11 import jalview.util.FileUtils;
12
13 /**
14  * Helper class to allow easy extraction of information about specific argument
15  * values (without having to check for null etc all the time)
16  */
17 public class ArgValuesMap
18 {
19   protected Map<Arg, ArgValues> m;
20
21   private String linkedId;
22
23   protected ArgValuesMap(String linkedId)
24   {
25     this.linkedId = linkedId;
26     this.newMap();
27   }
28
29   protected ArgValuesMap(String linkedId, Map<Arg, ArgValues> map)
30   {
31     this.linkedId = linkedId;
32     this.m = map;
33   }
34
35   public String getLinkedId()
36   {
37     return linkedId;
38   }
39
40   private Map<Arg, ArgValues> getMap()
41   {
42     return m;
43   }
44
45   private void newMap()
46   {
47     m = new HashMap<Arg, ArgValues>();
48   }
49
50   private void newArg(Arg a)
51   {
52     if (m == null)
53       newMap();
54     if (!containsArg(a))
55       m.put(a, new ArgValues(a));
56   }
57
58   public ArgValues getArgValues(Arg a)
59   {
60     return m == null ? null : m.get(a);
61   }
62
63   public ArgValues getOrCreateArgValues(Arg a)
64   {
65     ArgValues avs = m.get(a);
66     if (avs == null)
67       newArg(a);
68     return getArgValues(a);
69   }
70
71   public List<ArgValue> getArgValueList(Arg a)
72   {
73     ArgValues avs = getArgValues(a);
74     return avs == null ? new ArrayList<>() : avs.getArgValueList();
75   }
76
77   public ArgValue getArgValue(Arg a)
78   {
79     List<ArgValue> vals = getArgValueList(a);
80     return (vals == null || vals.size() == 0) ? null : vals.get(0);
81   }
82
83   public String getValue(Arg a)
84   {
85     ArgValue av = getArgValue(a);
86     return av == null ? null : av.getValue();
87   }
88
89   public boolean containsArg(Arg a)
90   {
91     if (m == null || !m.containsKey(a))
92       return false;
93     return a.hasOption(Opt.STRING) ? getArgValue(a) != null : true;
94   }
95
96   public boolean hasValue(Arg a, String val)
97   {
98     if (m == null || !m.containsKey(a))
99       return false;
100     for (ArgValue av : getArgValueList(a))
101     {
102       String avVal = av.getValue();
103       if ((val == null && avVal == null)
104               || (val != null && val.equals(avVal)))
105       {
106         return true;
107       }
108     }
109     return false;
110   }
111
112   public boolean getBoolean(Arg a)
113   {
114     ArgValues av = getArgValues(a);
115     return av == null ? false : av.getBoolean();
116   }
117
118   public Set<Arg> getArgKeys()
119   {
120     return m.keySet();
121   }
122
123   public ArgValue getClosestPreviousArgValueOfArg(ArgValue thisAv, Arg a)
124   {
125     ArgValue closestAv = null;
126     int thisArgIndex = thisAv.getArgIndex();
127     ArgValues compareAvs = this.getArgValues(a);
128     int closestPreviousIndex = -1;
129     for (ArgValue av : compareAvs.getArgValueList())
130     {
131       int argIndex = av.getArgIndex();
132       if (argIndex < thisArgIndex && argIndex > closestPreviousIndex)
133       {
134         closestPreviousIndex = argIndex;
135         closestAv = av;
136       }
137     }
138     return closestAv;
139   }
140
141   public ArgValue getClosestNextArgValueOfArg(ArgValue thisAv, Arg a)
142   {
143     // this looks for the *next* arg that *might* be referring back to
144     // a thisAv. Such an arg would have no subValues (if it does it should
145     // specify an id in the subValues so wouldn't need to be guessed).
146     ArgValue closestAv = null;
147     int thisArgIndex = thisAv.getArgIndex();
148     if (!containsArg(a))
149       return null;
150     ArgValues compareAvs = this.getArgValues(a);
151     int closestNextIndex = Integer.MAX_VALUE;
152     for (ArgValue av : compareAvs.getArgValueList())
153     {
154       int argIndex = av.getArgIndex();
155       if (argIndex > thisArgIndex && argIndex < closestNextIndex)
156       {
157         closestNextIndex = argIndex;
158         closestAv = av;
159       }
160     }
161     return closestAv;
162   }
163
164   public ArgValue[] getArgValuesReferringTo(String key, String value, Arg a)
165   {
166     // this looks for the *next* arg that *might* be referring back to
167     // a thisAv. Such an arg would have no subValues (if it does it should
168     // specify an id in the subValues so wouldn't need to be guessed).
169     List<ArgValue> avList = new ArrayList<>();
170     Arg[] args = a == null ? (Arg[]) this.getMap().keySet().toArray()
171             : new Arg[]
172             { a };
173     for (Arg keyArg : args)
174     {
175       for (ArgValue av : this.getArgValueList(keyArg))
176       {
177
178       }
179     }
180     return (ArgValue[]) avList.toArray();
181   }
182
183   public boolean hasId(Arg a, String id)
184   {
185     ArgValues avs = this.getArgValues(a);
186     return avs == null ? false : avs.hasId(id);
187   }
188
189   public ArgValue getId(Arg a, String id)
190   {
191     ArgValues avs = this.getArgValues(a);
192     return avs == null ? null : avs.getId(id);
193   }
194
195   /*
196    * This method returns the basename of the first --append or --open value. 
197    * Used primarily for substitutions in output filenames.
198    */
199   public String getBasename()
200   {
201     return getDirBasenameOrExtension(false, false);
202   }
203
204   /*
205    * This method returns the basename of the first --append or --open value. 
206    * Used primarily for substitutions in output filenames.
207    */
208   public String getExtension()
209   {
210     return getDirBasenameOrExtension(false, true);
211   }
212
213   /*
214    * This method returns the dirname of the first --append or --open value. 
215    * Used primarily for substitutions in output filenames.
216    */
217   public String getDirname()
218   {
219     return getDirBasenameOrExtension(true, false);
220   }
221
222   public String getDirBasenameOrExtension(boolean dirname,
223           boolean extension)
224   {
225     String filename = null;
226     String appendVal = getValue(Arg.APPEND);
227     String openVal = getValue(Arg.OPEN);
228     if (appendVal != null)
229       filename = appendVal;
230     if (filename == null && openVal != null)
231       filename = openVal;
232     if (filename == null)
233       return null;
234
235     File file = new File(filename);
236     if (dirname)
237     {
238       return FileUtils.getDirname(file);
239     }
240     return extension ? FileUtils.getExtension(file)
241             : FileUtils.getBasename(file);
242   }
243
244   /*
245    * Checks if there is an Arg with Opt
246    */
247   public boolean hasArgWithOption(Opt o)
248   {
249     for (Arg a : getArgKeys())
250     {
251       if (a.hasOption(o))
252         return true;
253     }
254     return false;
255   }
256 }