Merge branch 'releases/Release_2_11_4_Branch'
[jalview.git] / 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.JOptionPane;
34 import javax.swing.JPanel;
35 import javax.swing.event.ListSelectionEvent;
36
37 import net.miginfocom.swing.MigLayout;
38
39 public class RestInputParamEditDialog extends GRestInputParamEditDialog
40         implements OptsParametersContainerI
41 {
42   Hashtable<String, Class> typeclass = new Hashtable<String, Class>();
43
44   Hashtable<String, ArrayList<JPanel>> typeopts = new Hashtable<String, ArrayList<JPanel>>();
45
46   Hashtable<String, OptsAndParamsPage> opanps = new Hashtable<String, OptsAndParamsPage>();
47
48   private InputType getTypeFor(String name)
49   {
50     try
51     {
52       return (InputType) (typeclass.get(name).getConstructor()
53               .newInstance());
54     } catch (Throwable x)
55     {
56       System.err
57               .println("Unexpected exception when instantiating rest input type.");
58       x.printStackTrace();
59     }
60     return null;
61   }
62
63   int reply;
64
65   JalviewDialog frame = new JalviewDialog()
66   {
67
68     @Override
69     protected void raiseClosed()
70     {
71
72     }
73
74     @Override
75     protected void okPressed()
76     {
77       reply = JvOptionPane.OK_OPTION;
78     }
79
80     @Override
81     protected void cancelPressed()
82     {
83       reply = JvOptionPane.CANCEL_OPTION;
84
85     }
86   };
87
88   InputType old, current;
89
90   public RestInputParamEditDialog(
91           RestServiceEditorPane restServiceEditorPane,
92           RestServiceDescription currentservice, InputType toedit)
93   {
94     initFor(restServiceEditorPane, currentservice, toedit);
95     frame.waitForInput();
96     // TODO: warn user if they are about to overwrite an existing parameter
97     // because they have used the same name when editing a different parameter.
98     // TODO: make any press of the return key cause 'OK' to be pressed
99   }
100
101   private void initFor(RestServiceEditorPane restServiceEditorPane,
102           RestServiceDescription currentservice, InputType toedit)
103   {
104     okcancel.add(frame.cancel);
105     okcancel.add(frame.ok);
106     frame.initDialogFrame(dpane, true, true, "Edit parameter for service "
107             + currentservice.getName(), 600, 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.get(
163                   newType.getURLtokenPrefix()).getCurrentSettings());
164           current = newType;
165           updated = true;
166         } catch (InvalidArgumentException ex)
167         {
168           System.err
169                   .println("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>(), prms = new ArrayList<JPanel>();
190         jtype = (InputType) (type.getConstructor().newInstance());
191         typeclass.put(jtype.getURLtokenPrefix(), type);
192         // and populate parameters from this type
193         OptsAndParamsPage opanp = new OptsAndParamsPage(this, true);
194         opanps.put(jtype.getURLtokenPrefix(), opanp);
195         for (OptionI opt : jtype.getOptions())
196         {
197
198           if (opt instanceof ParameterI)
199           {
200             prms.add(opanp.addParameter((ParameterI) opt));
201           }
202           else
203           {
204             opts.add(opanp.addOption(opt));
205           }
206         }
207         // then tag the params at the end of the options.
208         for (JPanel pnl : prms)
209         {
210           opts.add(pnl);
211         }
212         typeopts.put(jtype.getURLtokenPrefix(), opts);
213         types.add(jtype.getURLtokenPrefix());
214       } catch (Throwable x)
215       {
216         System.err
217                 .println("Unexpected exception when instantiating rest input type.");
218         x.printStackTrace();
219       }
220     }
221     typeList.setListData(types.toArray());
222
223   }
224
225   @Override
226   protected void type_SelectionChangedActionPerformed(ListSelectionEvent e)
227   {
228     options.removeAll();
229     String typen = (String) typeList.getSelectedValue();
230     if (typeopts.get(typen) != null)
231     {
232       for (JPanel opt : typeopts.get(typen))
233       {
234         opt.setOpaque(true);
235         options.add(opt, "wrap");
236       }
237       options.invalidate();
238       optionsPanel.setVisible(true);
239     }
240     else
241     {
242       optionsPanel.setVisible(false);
243     }
244     dpane.revalidate();
245     updateCurrentType();
246   }
247
248   boolean updated = false;
249
250   public boolean wasUpdated()
251   {
252     return updated;
253   }
254
255   @Override
256   public void refreshParamLayout()
257   {
258     options.invalidate();
259     dpane.revalidate();
260   }
261
262   @Override
263   protected void tokChanged_actionPerformed()
264   {
265     if (tok.getText().trim().length() > 0)
266     {
267       if (current != null)
268       {
269         current.token = tok.getText().trim();
270         updated = true;
271       }
272     }
273   }
274
275   @Override
276   public void argSetModified(Object modifiedElement, boolean b)
277   {
278     updated = updated | b;
279     if (updated)
280     {
281       updateCurrentType();
282     }
283   }
284
285 }