Merge branch 'develop' into alpha/JAL-3362_Jalview_212_alpha
[jalview.git] / src / jalview / gui / RestInputParamEditDialog.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.gui;
22
23 import jalview.jbgui.GRestInputParamEditDialog;
24 import jalview.ws.params.InvalidArgumentException;
25 import jalview.ws.params.OptionI;
26 import jalview.ws.params.ParameterI;
27 import jalview.ws.rest.InputType;
28 import jalview.ws.rest.RestServiceDescription;
29
30 import java.util.ArrayList;
31 import java.util.Hashtable;
32
33 import javax.swing.JPanel;
34 import javax.swing.event.ListSelectionEvent;
35
36 import net.miginfocom.swing.MigLayout;
37
38 public class RestInputParamEditDialog extends GRestInputParamEditDialog
39         implements OptsParametersContainerI
40 {
41   Hashtable<String, Class> typeclass = new Hashtable<String, Class>();
42
43   Hashtable<String, ArrayList<JPanel>> typeopts = new Hashtable<String, ArrayList<JPanel>>();
44
45   Hashtable<String, OptsAndParamsPage> opanps = new Hashtable<String, OptsAndParamsPage>();
46
47   private InputType getTypeFor(String name)
48   {
49     try
50     {
51       return (InputType) (typeclass.get(name).getConstructor()
52               .newInstance());
53     } catch (Throwable x)
54     {
55       System.err.println(
56               "Unexpected exception when instantiating rest input type.");
57       x.printStackTrace();
58     }
59     return null;
60   }
61
62   int reply;
63
64   JalviewDialog frame = new JalviewDialog()
65   {
66
67     @Override
68     protected void raiseClosed()
69     {
70
71     }
72
73     @Override
74     protected void okPressed()
75     {
76       reply = JvOptionPane.OK_OPTION;
77     }
78
79     @Override
80     protected void cancelPressed()
81     {
82       reply = JvOptionPane.CANCEL_OPTION;
83
84     }
85   };
86
87   InputType old, current;
88
89   public RestInputParamEditDialog(
90           RestServiceEditorPane restServiceEditorPane,
91           RestServiceDescription currentservice, InputType toedit)
92   {
93     initFor(restServiceEditorPane, currentservice, toedit);
94     frame.waitForInput();
95     // TODO: warn user if they are about to overwrite an existing parameter
96     // because they have used the same name when editing a different parameter.
97     // TODO: make any press of the return key cause 'OK' to be pressed
98   }
99
100   private void initFor(RestServiceEditorPane restServiceEditorPane,
101           RestServiceDescription currentservice, InputType toedit)
102   {
103     okcancel.add(frame.cancel);
104     okcancel.add(frame.ok);
105     frame.initDialogFrame(dpane, true, true,
106             "Edit parameter for service " + currentservice.getName(), 600,
107             800);
108
109     initTypeLists();
110     reply = JvOptionPane.CANCEL_OPTION;
111     old = toedit;
112     current = null;
113     if (old != null)
114     {
115       setStateFor(old);
116     }
117     updated = updated && reply == JvOptionPane.OK_OPTION;
118     frame.validate();
119   }
120
121   public RestInputParamEditDialog(
122           RestServiceEditorPane restServiceEditorPane,
123           RestServiceDescription currentservice, String string)
124   {
125     initFor(restServiceEditorPane, currentservice, null);
126     tok.setText(string);
127     frame.waitForInput();
128   }
129
130   private void setStateFor(InputType current)
131   {
132     tok.setText(current.token);
133     OptsAndParamsPage opanp = opanps.get(current.getURLtokenPrefix());
134     for (OptionI ops : current.getOptions())
135     {
136       if (ops instanceof ParameterI)
137       {
138         opanp.setParameter((ParameterI) ops);
139       }
140       else
141       {
142         if (ops.getValue() != null && ops.getValue().length() > 0)
143         {
144           opanp.selectOption(ops, ops.getValue());
145         }
146       }
147     }
148     typeList.setSelectedValue(current.getURLtokenPrefix(), true);
149     type_SelectionChangedActionPerformed(null);
150   }
151
152   private void updateCurrentType()
153   {
154     if (typeList.getSelectedValue() != null)
155     {
156       InputType newType = getTypeFor((String) typeList.getSelectedValue());
157       if (newType != null)
158       {
159         newType.token = tok.getText().trim();
160         try
161         {
162           newType.configureFromArgumentI(opanps
163                   .get(newType.getURLtokenPrefix()).getCurrentSettings());
164           current = newType;
165           updated = true;
166         } catch (InvalidArgumentException ex)
167         {
168           System.err.println(
169                   "IMPLEMENTATION ERROR: Invalid argument for type : "
170                           + typeList.getSelectedValue() + "\n");
171           ex.printStackTrace();
172         }
173       }
174     }
175
176   }
177
178   private void initTypeLists()
179   {
180     ArrayList<String> types = new ArrayList<String>();
181     // populate type list
182     for (Class type : RestServiceDescription.getInputTypes())
183     {
184
185       InputType jtype = null;
186       try
187       {
188         JPanel inopts = new JPanel(new MigLayout());
189         ArrayList<JPanel> opts = new ArrayList<JPanel>(),
190                 prms = new ArrayList<JPanel>();
191         jtype = (InputType) (type.getConstructor().newInstance());
192         typeclass.put(jtype.getURLtokenPrefix(), type);
193         // and populate parameters from this type
194         OptsAndParamsPage opanp = new OptsAndParamsPage(this, true);
195         opanps.put(jtype.getURLtokenPrefix(), opanp);
196         for (OptionI opt : jtype.getOptions())
197         {
198
199           if (opt instanceof ParameterI)
200           {
201             prms.add(opanp.addParameter((ParameterI) opt));
202           }
203           else
204           {
205             opts.add(opanp.addOption(opt));
206           }
207         }
208         // then tag the params at the end of the options.
209         for (JPanel pnl : prms)
210         {
211           opts.add(pnl);
212         }
213         typeopts.put(jtype.getURLtokenPrefix(), opts);
214         types.add(jtype.getURLtokenPrefix());
215       } catch (Throwable x)
216       {
217         System.err.println(
218                 "Unexpected exception when instantiating rest input type.");
219         x.printStackTrace();
220       }
221     }
222     typeList.setListData(types.toArray());
223
224   }
225
226   @Override
227   protected void type_SelectionChangedActionPerformed(ListSelectionEvent e)
228   {
229     options.removeAll();
230     String typen = (String) typeList.getSelectedValue();
231     if (typeopts.get(typen) != null)
232     {
233       for (JPanel opt : typeopts.get(typen))
234       {
235         opt.setOpaque(true);
236         options.add(opt, "wrap");
237       }
238       options.invalidate();
239       optionsPanel.setVisible(true);
240     }
241     else
242     {
243       optionsPanel.setVisible(false);
244     }
245     dpane.revalidate();
246     updateCurrentType();
247   }
248
249   boolean updated = false;
250
251   public boolean wasUpdated()
252   {
253     return updated;
254   }
255
256   @Override
257   public void refreshParamLayout()
258   {
259     options.invalidate();
260     dpane.revalidate();
261   }
262
263   @Override
264   protected void tokChanged_actionPerformed()
265   {
266     if (tok.getText().trim().length() > 0)
267     {
268       if (current != null)
269       {
270         current.token = tok.getText().trim();
271         updated = true;
272       }
273     }
274   }
275
276   @Override
277   public void argSetModified(Object modifiedElement, boolean b)
278   {
279     updated = updated | b;
280     if (updated)
281     {
282       updateCurrentType();
283     }
284   }
285
286 }