1 /*******************************************************************************
2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
17 *******************************************************************************/
20 import jalview.io.packed.DataProvider.JvDataType;
21 import jalview.jbgui.GRestServiceEditorPane;
22 import jalview.ws.rest.InputType;
23 import jalview.ws.rest.RestServiceDescription;
25 import java.awt.BorderLayout;
26 import java.awt.FlowLayout;
27 import java.awt.event.ActionEvent;
28 import java.awt.event.ActionListener;
29 import java.awt.event.ComponentEvent;
30 import java.awt.event.ComponentListener;
31 import java.awt.event.KeyEvent;
32 import java.awt.event.KeyListener;
33 import java.awt.event.MouseEvent;
34 import java.util.HashMap;
35 import java.util.List;
37 import java.util.Vector;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
41 import javax.swing.JFrame;
42 import javax.swing.JMenuItem;
43 import javax.swing.JPanel;
44 import javax.swing.JPopupMenu;
45 import javax.swing.event.ChangeEvent;
46 import javax.swing.event.ChangeListener;
48 public class RestServiceEditorPane extends GRestServiceEditorPane
51 * the latest version of the service definition.
53 jalview.ws.rest.RestServiceDescription currentservice = null;
56 * original service passed to editor if we are modifying an existing service
59 jalview.ws.rest.RestServiceDescription oldservice = null;
61 public RestServiceEditorPane()
64 // begin with initial text description box enabled.
65 urldesc.addKeyListener(new KeyListener()
68 public void keyTyped(KeyEvent e)
73 public void keyReleased(KeyEvent e)
75 refreshCutnPaste(true);
79 public void keyPressed(KeyEvent e)
84 panels.addChangeListener(new ChangeListener()
88 * last panel selected - used to decide whether the service or the GUI has the latest info
92 public void stateChanged(ChangeEvent e)
94 if (lastComp!=paste) {
95 updateServiceFromGui();
96 refreshCutnPaste(false);
98 refreshCutnPaste(true);
100 lastComp = panels.getSelectedComponent();
104 currentservice = new RestServiceDescription("Analysis", "service description", "service name", "http://localhost/", "", null, false, false, '-');
105 initGuiWith(currentservice);
106 refreshCutnPaste(false);
110 public RestServiceEditorPane(RestServiceDescription toedit)
114 if (oldservice!=null)
115 { currentservice = new RestServiceDescription(toedit);
117 currentservice = new RestServiceDescription("Analysis", "service description", "service name", "http://localhost/", "", null, false, false, '-');
119 initGuiWith(currentservice);
120 refreshCutnPaste(false);
125 * refresh the buttons based on model state
127 public void updateButtons()
129 cancelButton.setEnabled(true);
130 okButton.setEnabled(currentservice != null && currentservice.isValid());
134 Vector<String> _iparam = new Vector<String>();
136 Vector<String> _rparam = new Vector<String>();
139 * generate an editable URL service string and parameter list using the
142 * @param currentservice2
144 private void initGuiWith(RestServiceDescription currentservice)
148 action.removeAllItems();
149 action.addItem("Alignment");
150 action.addItem("Analysis");
151 gapChar.removeAllItems();
152 gapChar.addItem(".");
153 gapChar.addItem(" ");
154 gapChar.addItem("-");
155 if (currentservice==null)
161 action.setSelectedItem("Analysis");
162 gapChar.setSelectedItem("-");
164 name.setText(currentservice.getName());
165 descr.setText(currentservice.getDescription());
166 url.setText(currentservice.getPostUrl());
167 urlsuff.setText(currentservice.getUrlSuffix());
168 for (Map.Entry<String, InputType> inparam : currentservice
169 .getInputParams().entrySet())
171 _iparam.add(inparam.getKey() + " "
172 + inparam.getValue().getURLtokenPrefix() + ":"
173 + inparam.getValue().getURLEncodedParameter().toString());
176 for (JvDataType oparam : currentservice.getResultDataTypes())
178 _rparam.add(oparam.name());
180 iprms.setListData(_iparam);
181 rdata.setListData(_rparam);
183 action.setSelectedItem(currentservice.getAction());
185 gapChar.setSelectedItem(""+currentservice.getGapCharacter());
189 private String getSelectedInputToken()
191 if (iprms.getSelectedIndex()>-1)
193 String toktoedit = (String) iprms.getSelectedValue();
194 toktoedit=toktoedit.substring(0, toktoedit.indexOf(" "));
200 protected void iprmListSelection_doubleClicked()
202 String toktoedit = getSelectedInputToken();
205 InputType toedit = currentservice.getInputParams().get(toktoedit);
206 String oldParam=toktoedit;
207 RestInputParamEditDialog dialog=new RestInputParamEditDialog(this, currentservice, toedit);
208 if (dialog.wasUpdated()) {
209 currentservice.getInputParams().remove(oldParam);
210 currentservice.getInputParams().put(dialog.current.token, dialog.current);
211 initGuiWith(currentservice);
217 protected void iprmsAdd_actionPerformed(ActionEvent e)
219 RestInputParamEditDialog dialog=new RestInputParamEditDialog(this, currentservice, "param"+(1+currentservice.getInputParams().size()));
220 if (dialog.wasUpdated()) {
221 currentservice.getInputParams().put(dialog.current.token, dialog.current);
222 initGuiWith(currentservice);
227 protected void iprmsRem_actionPerformed(ActionEvent e)
229 String toktoedit = getSelectedInputToken();
232 currentservice.getInputParams().remove(toktoedit);
233 initGuiWith(currentservice);
238 protected void rdata_rightClicked(MouseEvent mouse)
240 final int rdatasel = rdata.getSelectedIndex();
243 JPopupMenu popup = new JPopupMenu("Select return type");
244 for (final JvDataType type:JvDataType.values()) {
245 popup.add(new JMenuItem(type.name())).addActionListener(new ActionListener()
249 public void actionPerformed(ActionEvent e)
251 currentservice.getResultDataTypes().set(rdatasel, type);
252 initGuiWith(currentservice);
253 rdata.setSelectedIndex(rdatasel);
257 popup.show(rdata, mouse.getX(), mouse.getY());
261 protected void rdataAdd_actionPerformed(ActionEvent e)
264 if ((p=rdata.getSelectedIndex())>-1)
266 currentservice.getResultDataTypes().add(p+1, JvDataType.ANNOTATION);
268 currentservice.addResultDatatype(JvDataType.ANNOTATION);
270 initGuiWith(currentservice);
271 rdata.setSelectedIndex(p==-1 ? currentservice.getResultDataTypes().size()-1 : p+1);
274 protected void rdataNdown_actionPerformed(ActionEvent e)
277 if ((p=rdata.getSelectedIndex())>-1 && p<_rparam.size()-1)
279 List<JvDataType> rtypes = currentservice.getResultDataTypes();
280 JvDataType below = rtypes.get(p+1);
281 rtypes.set(p+1, rtypes.get(p));
282 rtypes.set(p, below);
283 initGuiWith(currentservice);
284 rdata.setSelectedIndex(p+1);
288 protected void rdataNup_actionPerformed(ActionEvent e)
291 if ((p=rdata.getSelectedIndex())>0)
293 List<JvDataType> rtypes = currentservice.getResultDataTypes();
294 JvDataType above = rtypes.get(p-1);
295 rtypes.set(p-1, rtypes.get(p));
296 rtypes.set(p, above);
297 initGuiWith(currentservice);
298 rdata.setSelectedIndex(p-1);
302 protected void rdataRem_actionPerformed(ActionEvent e)
304 if (rdata.getSelectedIndex()>-1)
306 currentservice.getResultDataTypes().remove(rdata.getSelectedIndex());
307 initGuiWith(currentservice);
311 private boolean updateServiceFromGui() {
312 Map<String,InputType>inputTypes = new HashMap<String, InputType>();
313 StringBuffer warnings=new StringBuffer();
314 for (String its:_iparam)
316 Matcher mtch = Pattern.compile("(\\S+)\\s(\\S+):\\[(.+)]").matcher(its);
318 if (!RestServiceDescription.parseTypeString(mtch.group(2)+":"+mtch.group(3), mtch.group(1), mtch.group(2),mtch.group(3), inputTypes, warnings))
320 System.err.println("IMPLEMENTATION PROBLEM: Cannot parse RestService input parameter string '"+its+"'"+"\n"+warnings);
324 char gc = gapChar.getSelectedItem()==null ? ' ' : ((String)gapChar.getSelectedItem()).charAt(0);
325 RestServiceDescription newService = new RestServiceDescription((String) action.getSelectedItem(),
326 descr.getText().trim(), name.getText().trim(), url.getText().trim(), urlsuff.getText().trim(), inputTypes, hSeparable.isSelected(), vSeparable.isSelected(), gc);
328 if (newService.isValid())
330 for (String its:_rparam)
334 dtype = JvDataType.valueOf(its);
335 newService.addResultDatatype(dtype);
340 System.err.println("IMPLEMENTATION PROBLEM: Cannot parse RestService output parameter string '"+its+"'"+"\n"+warnings);
343 currentservice = newService;
346 System.err.println("IMPLEMENTATION PROBLEM: Restservice generated from GUI is invalid\n"+warnings);
351 protected void refreshCutnPaste(boolean reparse)
353 if (!reparse && currentservice.isValid())
355 urldesc.setText(currentservice.toString());
356 parseWarnings.setVisible(false);
362 String txt = urldesc.getText().trim();
363 if (txt.length() > 0)
365 RestServiceDescription rsd = null;
368 rsd = new RestServiceDescription(txt);
371 parseWarnings.setVisible(false);
372 parseRes.setText("");
373 initGuiWith(currentservice=rsd);
377 parseRes.setText("Parsing failed. Syntax errors shown below\n"
378 + rsd.getInvalidMessage());
379 parseWarnings.setVisible(true);
381 } catch (Throwable e)
384 parseRes.setText("\nParsing failed. An unrecoverable exception was thrown:\n"
386 parseWarnings.setVisible(true);
395 public static void main(String[] args)
397 if (args.length == 0)
399 new Thread(new Runnable()
401 boolean visible = true;
405 boolean nulserv=true;
408 final Thread runner = Thread.currentThread();
409 JFrame df = new JFrame();
410 df.getContentPane().setLayout(new BorderLayout());
411 df.getContentPane().add(
412 (nulserv=!nulserv) ? new RestServiceEditorPane(jalview.ws.rest.RestClient
413 .makeShmmrRestClient().getRestDescription()) : new RestServiceEditorPane(),
414 BorderLayout.CENTER);
415 df.setBounds(100, 100, 600, 400);
416 df.addComponentListener(new ComponentListener()
420 public void componentShown(ComponentEvent e)
426 public void componentResized(ComponentEvent e)
432 public void componentMoved(ComponentEvent e)
438 public void componentHidden(ComponentEvent e)
451 } catch (Exception x)
463 String finalService=null;
464 public void showDialog(String title)
466 if (oldservice!=null)
468 finalService = oldservice.toString();
470 JalviewDialog jvd = new JalviewDialog()
474 protected void raiseClosed()
476 // TODO Auto-generated method stub
481 protected void okPressed()
483 updateServiceFromGui();
484 finalService = currentservice.toString();
488 protected void cancelPressed()
493 JPanel pane = new JPanel(new BorderLayout()),okcancel=new JPanel(new FlowLayout());
494 pane.add(this,BorderLayout.CENTER);
495 okcancel.add(jvd.ok);
496 okcancel.add(jvd.cancel);
497 pane.add(okcancel, BorderLayout.SOUTH);
498 jvd.initDialogFrame(pane, true, true, title, 600,350);
502 public String getEditedRestService()