JAL-4131 Replace usages of requireNonNullElse
[jalview.git] / src / jalview / ws2 / client / slivka / SlivkaParamStoreFactory.java
1 package jalview.ws2.client.slivka;
2
3 import java.io.File;
4 import java.net.MalformedURLException;
5 import java.net.URL;
6 import java.util.ArrayList;
7 import java.util.Collections;
8 import java.util.List;
9 import java.util.Map;
10
11 import com.stevesoft.pat.NotImplementedError;
12
13 import jalview.bin.Cache;
14 import jalview.bin.Console;
15 import jalview.ws.params.ArgumentI;
16 import jalview.ws.params.ParamDatastoreI;
17 import jalview.ws.params.ParamManager;
18 import jalview.ws.params.WsParamSetI;
19 import jalview.ws.params.simple.BooleanOption;
20 import jalview.ws.params.simple.DoubleParameter;
21 import jalview.ws.params.simple.IntegerParameter;
22 import jalview.ws.params.simple.Option;
23 import jalview.ws.params.simple.StringParameter;
24 import jalview.ws2.params.SimpleParamDatastore;
25 import jalview.ws2.params.SimpleParamSet;
26 import uk.ac.dundee.compbio.slivkaclient.Parameter;
27 import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
28
29 class SlivkaParamStoreFactory
30 {
31   private final SlivkaService service;
32
33   private final ParamManager manager;
34
35   SlivkaParamStoreFactory(SlivkaService service, ParamManager manager)
36   {
37     this.service = service;
38     this.manager = manager;
39   }
40
41   ParamDatastoreI createParamDatastore()
42   {
43     URL url = null;
44     try
45     {
46       url = service.getUrl().toURL();
47     } catch (MalformedURLException e)
48     {
49       Console.warn("Invalid service url " + service.getUrl(), e);
50     }
51     List<WsParamSetI> presets = new ArrayList<>(service.getPresets().size());
52     for (var preset : service.getPresets())
53     {
54       presets.add(createPreset(preset));
55     }
56     List<ArgumentI> arguments = createPresetArguments(Collections.emptyMap());
57     return new SimpleParamDatastore(url, arguments, presets, manager);
58   }
59
60   WsParamSetI createPreset(SlivkaService.Preset preset)
61   {
62     var builder = SimpleParamSet.newBuilder();
63     builder.name(preset.name);
64     builder.description(preset.description);
65     builder.url(service.getUrl().toString());
66     builder.modifiable(false);
67     builder.arguments(createPresetArguments(preset.values));
68     return builder.build();
69   }
70
71   List<ArgumentI> createPresetArguments(Map<String, Object> values)
72   {
73     var args = new ArrayList<ArgumentI>();
74     for (Parameter param : service.getParameters())
75     {
76       if (param instanceof Parameter.IntegerParameter)
77       {
78         args.add(createOption((Parameter.IntegerParameter) param,
79             (Integer) values.get(param.getId())));
80       }
81       else if (param instanceof Parameter.DecimalParameter)
82       {
83         args.add(createOption((Parameter.DecimalParameter) param,
84             (Double) values.get(param.getId())));
85       }
86       else if (param instanceof Parameter.TextParameter)
87       {
88         args.add(createOption((Parameter.TextParameter) param,
89             (String) values.get(param.getId())));
90       }
91       else if (param instanceof Parameter.FlagParameter)
92       {
93         args.add(createOption((Parameter.FlagParameter) param,
94             (Boolean) values.get(param.getId())));
95       }
96       else if (param instanceof Parameter.ChoiceParameter)
97       {
98         Object ovalue = values.get(param.getId());
99         List<String> lvalue = null;
100         if (param.isArray())
101           lvalue = (List<String>) ovalue;
102         else if (ovalue != null)
103           lvalue = List.of((String) ovalue);
104         args.addAll(createChoiceOptions((Parameter.ChoiceParameter) param, lvalue));
105       }
106       else if (param instanceof Parameter.FileParameter)
107       {
108         // args.add(createOption((Parameter.FileParameter) param, null));
109       }
110       else
111       {
112         args.add(createOption(param, values.get(param.getId())));
113       }
114     }
115     return args;
116   }
117
118   private Option createOption(Parameter.IntegerParameter param, Integer value)
119   {
120     var builder = IntegerParameter.newBuilder();
121     setCommonProperties(param, builder);
122     builder.setDefaultValue((Integer) param.getDefault());
123     builder.setValue(value);
124     builder.setBounds(param.getMin(), param.getMax());
125     return builder.build();
126   }
127
128   private Option createOption(Parameter.DecimalParameter param, Double value)
129   {
130     var builder = DoubleParameter.newBuilder();
131     setCommonProperties(param, builder);
132     builder.setDefaultValue((Double) param.getDefault());
133     builder.setValue(value);
134     builder.setBounds(param.getMin(), param.getMax());
135     return builder.build();
136   }
137
138   private Option createOption(Parameter.TextParameter param, String value)
139   {
140     var builder = StringParameter.newBuilder();
141     setCommonProperties(param, builder);
142     builder.setDefaultValue((String) param.getDefault());
143     builder.setValue(value);
144     return builder.build();
145   }
146
147   private Option createOption(Parameter.FlagParameter param, Boolean value)
148   {
149     var builder = BooleanOption.newBuilder();
150     setCommonProperties(param, builder);
151     builder.setDefaultValue((Boolean) param.getDefault());
152     builder.setValue(value);
153     return builder.build();
154   }
155
156   private List<Option> createChoiceOptions(Parameter.ChoiceParameter param, List<String> value)
157   {
158     value = value != null ? value : Collections.emptyList();
159     if (param.isArray())
160     {
161       /*
162        * Array parameter means that multiple values can be provided.
163        * Use multiple boolean checkboxes to represent the value.
164        */
165       List<Option> options = new ArrayList<>();
166       List<?> selected = param.getDefault() != null
167               ? (List<?>) param.getDefault()
168               : Collections.emptyList();
169       int i = 0;
170       var builder = BooleanOption.newBuilder();
171       setCommonProperties(param, builder);
172       for (String choice : param.getChoices())
173       {
174         builder.setName(String.format("%s$%d", param.getId(), i++));
175         builder.setLabel(choice);
176         builder.setDefaultValue(selected.contains(choice));
177         builder.setValue(value.contains(choice));
178         builder.setReprValue(choice);
179         options.add(builder.build());
180       }
181       return options;
182     }
183     else
184     {
185       /*
186        * Single value parameter means a single string with limited possible
187        * values can be used.
188        */
189       var builder = StringParameter.newBuilder();
190       setCommonProperties(param, builder);
191       builder.setDefaultValue((String) param.getDefault());
192       if (value.size() > 0)
193         builder.setValue(value.get(0));
194       builder.setPossibleValues(param.getChoices());
195       return List.of(builder.build());
196     }
197   }
198
199   private Option createOption(Parameter.FileParameter param, File value)
200   {
201     throw new NotImplementedError("file paramters are not implemented for slivka");
202   }
203
204   private Option createOption(Parameter param, Object value)
205   {
206     var builder = StringParameter.newBuilder();
207     setCommonProperties(param, builder);
208     if (param.getDefault() != null)
209       builder.setDefaultValue(param.getDefault().toString());
210     if (value != null)
211       builder.setValue(value.toString());
212     return builder.build();
213   }
214
215   private void setCommonProperties(Parameter param, Option.Builder builder)
216   {
217     builder.setName(param.getId());
218     builder.setLabel(param.getName());
219     builder.setDescription(param.getDescription());
220     builder.setRequired(param.isRequired());
221     try
222     {
223       builder.setDetailsUrl(service.getUrl().toURL());
224     } catch (MalformedURLException e)
225     {
226       Console.warn("invalid service url " + service.getUrl(), e);
227     }
228   }
229 }