--- /dev/null
+package jalview.gui;
+
+import jalview.bin.Cache;
+import jalview.io.packed.DataProvider.JvDataType;
+import jalview.jbgui.*;
+import jalview.ws.rest.InputType;
+import jalview.ws.rest.RestServiceDescription;
+
+import java.awt.*;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.ContainerEvent;
+import java.awt.event.ContainerListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.awt.event.WindowStateListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.*;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.GapContent;
+
+import org.apache.log4j.lf5.LogLevel;
+
+public class RestServiceEditorPane extends GRestServiceEditorPane
+{
+ /**
+ * the latest version of the service definition.
+ */
+ jalview.ws.rest.RestServiceDescription currentservice = null;
+
+ /**
+ * original service passed to editor if we are modifying an existing service
+ * definition
+ */
+ jalview.ws.rest.RestServiceDescription oldservice = null;
+
+ public RestServiceEditorPane()
+ {
+ super();
+ // begin with initial text description box enabled.
+ urldesc.addKeyListener(new KeyListener()
+ {
+ long lastWait;
+ boolean doUpdate;
+ Thread updater=null;
+ @Override
+ public void keyTyped(KeyEvent e)
+ {
+ refreshCutnPaste(true);
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ paste.addComponentListener(new ComponentListener()
+ {
+
+ @Override
+ public void componentShown(ComponentEvent e)
+ {
+ updateServiceFromGui();
+ refreshCutnPaste(false);
+
+ }
+
+ @Override
+ public void componentResized(ComponentEvent e)
+ {
+ }
+
+ @Override
+ public void componentMoved(ComponentEvent e)
+ {
+
+ }
+
+ @Override
+ public void componentHidden(ComponentEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ }
+
+ public RestServiceEditorPane(RestServiceDescription toedit)
+ {
+ this();
+ oldservice = toedit;
+ currentservice = new RestServiceDescription(toedit);
+ initGuiWith(currentservice);
+ refreshCutnPaste(false);
+ updateButtons();
+ }
+
+ /**
+ * refresh the buttons based on model state
+ */
+ public void updateButtons()
+ {
+ cancelButton.setEnabled(oldservice != null);
+ okButton.setEnabled(currentservice != null && currentservice.isValid());
+
+ }
+
+ Vector<String> _iparam = new Vector<String>();
+
+ Vector<String> _rparam = new Vector<String>();
+
+ /**
+ * generate an editable URL service string and parameter list using the
+ * service
+ *
+ * @param currentservice2
+ */
+ private void initGuiWith(RestServiceDescription currentservice)
+ {
+ name.setText(currentservice.getName());
+ descr.setText(currentservice.getDescription());
+ url.setText(currentservice.getPostUrl());
+ urlsuff.setText(currentservice.getUrlSuffix());
+ _iparam.clear();
+ _rparam.clear();
+ for (Map.Entry<String, InputType> inparam : currentservice
+ .getInputParams().entrySet())
+ {
+ _iparam.add(inparam.getKey() + " "
+ + inparam.getValue().getURLtokenPrefix() + ":"
+ + inparam.getValue().getURLEncodedParameter().toString());
+ }
+ for (JvDataType oparam : currentservice.getResultDataTypes())
+ {
+ _rparam.add((oparam.name()));
+ }
+ iprms.setListData(_iparam);
+ rdata.setListData(_rparam);
+
+ action.removeAllItems();
+ action.addItem("Alignment");
+ action.addItem("Analysis");
+ // action.addItem("Analysis");
+ action.setSelectedItem(currentservice.getAction());
+ revalidate();
+ }
+
+ private boolean updateServiceFromGui() {
+ boolean valid=true;
+ Map<String,InputType>inputTypes = new HashMap<String, InputType>();
+ StringBuffer warnings=new StringBuffer();
+ for (String its:_iparam)
+ {
+ Matcher mtch = Pattern.compile("(\\S+)\\s(\\S+):\\[(.+)]").matcher(its);
+ if (mtch.find()) {
+ if (!RestServiceDescription.parseTypeString(mtch.group(2)+":"+mtch.group(3), mtch.group(1), mtch.group(2),mtch.group(3), inputTypes, warnings))
+ {
+ System.err.println("IMPLEMENTATION PROBLEM: Cannot parse RestService input parameter string '"+its+"'"+"\n"+warnings);
+ }
+ }
+ }
+ char gc = gapChar.getSelectedItem()==null ? ' ' : ((String)gapChar.getSelectedItem()).charAt(0);
+ RestServiceDescription newService = new RestServiceDescription((String) action.getSelectedItem(),
+ descr.getText().trim(), name.getText().trim(), url.getText().trim(), urlsuff.getText().trim(), inputTypes, hSeparable.isSelected(), vSeparable.isSelected(), gc);
+
+ if (newService.isValid())
+ {
+ for (String its:_rparam)
+ {
+ JvDataType dtype;
+ try {
+ dtype = JvDataType.valueOf(its);
+ newService.addResultDatatype(dtype);
+ }
+ catch (Throwable x)
+ {
+
+ System.err.println("IMPLEMENTATION PROBLEM: Cannot parse RestService output parameter string '"+its+"'"+"\n"+warnings);
+ }
+ }
+ currentservice = newService;
+ return true;
+ } else {
+ System.err.println("IMPLEMENTATION PROBLEM: Restservice generated from GUI is invalid\n"+warnings);
+
+ }
+ return false;
+ }
+ protected void refreshCutnPaste(boolean reparse)
+ {
+ if (!reparse && currentservice.isValid())
+ {
+ urldesc.setText(currentservice.toString());
+ parseWarnings.setVisible(false);
+ }
+ else
+ {
+ if (reparse)
+ {
+ String txt = urldesc.getText().trim();
+ StringBuffer warnings;
+ if (txt.length() > 0)
+ {
+ RestServiceDescription rsd = null;
+ try
+ {
+ rsd = new RestServiceDescription(txt);
+ if (rsd.isValid())
+ {
+ parseWarnings.setVisible(false);
+ initGuiWith(currentservice=rsd);
+ }
+ else
+ {
+ parseRes.setText("Parsing failed. Syntax errors shown below\n"
+ + rsd.getInvalidMessage());
+ parseWarnings.setVisible(true);
+ }
+ } catch (Throwable e)
+ {
+ parseRes.setText("\nParsing failed. An unrecoverable exception was thrown:\n"
+ + e.toString());
+ parseWarnings.setVisible(true);
+ }
+ }
+ }
+ }
+
+ }
+
+ public static void main(String[] args)
+ {
+ if (args.length == 0)
+ {
+ new Thread(new Runnable()
+ {
+ boolean visible = true;
+
+ public void run()
+ {
+ while (visible)
+ {
+ final Thread runner = Thread.currentThread();
+ JFrame df = new JFrame();
+ df.getContentPane().setLayout(new BorderLayout());
+ df.getContentPane().add(
+ new RestServiceEditorPane(jalview.ws.rest.RestClient
+ .makeShmmrRestClient().getRestDescription()),
+ BorderLayout.CENTER);
+ df.setBounds(100, 100, 400, 600);
+ df.addComponentListener(new ComponentListener()
+ {
+
+ @Override
+ public void componentShown(ComponentEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void componentResized(ComponentEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void componentMoved(ComponentEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void componentHidden(ComponentEvent e)
+ {
+ visible = false;
+ runner.interrupt();
+
+ }
+ });
+ df.setVisible(true);
+ while (visible)
+ {
+ try
+ {
+ Thread.sleep(10000);
+ } catch (Exception x)
+ {
+ }
+ ;
+ }
+ visible = true;
+ }
+ }
+ }).start();
+
+ }
+ }
+}
--- /dev/null
+package jalview.jbgui;
+
+import jalview.gui.JvSwingUtils;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.JViewport;
+import javax.swing.UIManager;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import net.miginfocom.swing.MigLayout;
+
+public class GRestServiceEditorPane extends JPanel {
+
+ protected JTabbedPane panels;
+
+ protected JPanel details, inputs, paste;
+
+ protected JTextArea urldesc, url, urlsuff, name, descr, parseRes;
+
+ protected JComboBox action, gapChar;
+
+ JLabel acttype;
+
+ protected JButton okButton;
+
+ protected JButton cancelButton;
+
+ JPanel svcattribs;
+
+ JPanel status;
+
+ protected JList iprms;
+
+ protected JList rdata;
+
+ JScrollPane iprmVp, rdataVp, parseResVp, urlVp, descrVp, urldescVp;
+
+ JButton rdataAdd, rdataRem, rdataNdown, rdataNup;
+
+ JButton iprmsAdd, iprmsRem;
+
+ protected JCheckBox hSeparable;
+
+ protected JCheckBox vSeparable;
+
+ protected JPanel parseWarnings;
+
+ public GRestServiceEditorPane()
+ {
+ jbInit();
+ }
+
+ protected void jbInit()
+ {
+ details = new JPanel();
+ details.setName("Details");
+ details.setLayout(new MigLayout());
+ inputs = new JPanel();
+ inputs.setName("Input/Output");
+ inputs.setLayout(new MigLayout("","[grow 85,fill][]",""));
+ paste = new JPanel();
+ paste.setName("Cut'n'Paste");
+ paste.setLayout(new MigLayout());
+
+ panels = new JTabbedPane();
+ panels.addTab(details.getName(), details);
+ panels.addTab(inputs.getName(), inputs);
+ panels.addTab(paste.getName(), paste);
+
+ JPanel cpanel;
+
+ // Name and URL Panel
+ cpanel = details;
+ name = new JTextArea(1, 12);
+
+ JvSwingUtils
+ .mgAddtoLayout(cpanel, "Short descriptive name for service",
+ new JLabel("Name:"), name,"wrap");
+ action = new JComboBox();
+ JvSwingUtils
+ .mgAddtoLayout(
+ cpanel,
+ "What kind of function the service performs (e.g. alignment, analysis, search, etc).",
+ new JLabel("Service Action:"), action,"wrap");
+ descr = new JTextArea(4, 40);
+ descrVp = new JScrollPane();
+ descrVp.setViewportView(descr);
+ JvSwingUtils.mgAddtoLayout(cpanel, "Brief description of service",
+ new JLabel("Description:"), descrVp,"wrap");
+
+ url = new JTextArea(2, 20);
+ urlVp = new JScrollPane();
+ urlVp.setViewportView(url);
+ JvSwingUtils
+ .mgAddtoLayout(
+ cpanel,
+ "URL to post data to service. Include any special parameters needed here",
+ new JLabel("POST URL:"), urlVp,"wrap");
+
+ urlsuff = new JTextArea();
+ urlsuff.setColumns(20);
+
+ JvSwingUtils
+ .mgAddtoLayout(
+ cpanel,
+ "Optional suffix added to URL when retrieving results from service",
+ new JLabel("URL Suffix:"), urlsuff,"wrap");
+
+ // input options
+ // details.add(cpanel = new JPanel(), BorderLayout.CENTER);
+ // cpanel.setLayout(new FlowLayout());
+ hSeparable = new JCheckBox("per Sequence");
+ hSeparable
+ .setToolTipText("<html>"
+ + JvSwingUtils
+ .wrapTooltip("When checked, a job is created for every sequence in the current selection.")
+ + "<html>");
+ hSeparable.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0)
+ {
+ hSeparable_actionPerformed(arg0);
+
+ }
+ });
+ vSeparable = new JCheckBox("Results are vertically separable");
+ vSeparable
+ .setToolTipText("<html>"
+ + JvSwingUtils
+ .wrapTooltip("When checked, a single job is created for the visible region and results"
+ + " mapped back onto their location in the alignment. Otherwise, a job would be"
+ + " created for every contiguous region visible in the alignment or current"
+ + " selection (e.g. a multiple alignment).")
+ + "</html>");
+ vSeparable.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0)
+ {
+ vSeparable_actionPerformed(arg0);
+
+ }
+ });
+ gapChar = new JComboBox();
+ JvSwingUtils
+ .mgAddtoLayout(
+ cpanel,
+ "Which gap character does this service prefer ?",
+ new JLabel("Gap Character:"), gapChar,"wrap");
+
+
+ cpanel.add(hSeparable);
+ cpanel.add(vSeparable);
+
+ // Input and Output lists
+ // Inputparams
+ JPanel iprmsList = new JPanel();
+ iprmsList.setBorder(new TitledBorder("Data input parameters"));
+ iprmsList.setLayout(new MigLayout());
+ iprmVp = new JScrollPane();
+ iprmVp.getViewport().setView(iprms = new JList());
+ iprmsList.add(iprmVp);
+ JPanel iprmButs = new JPanel();
+ iprmButs.setLayout(new MigLayout());
+
+ iprmsAdd = JvSwingUtils.makeButton("+", "Add input parameter",
+ new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ iprmsAdd_actionPerformed(e);
+
+ }
+ });
+ iprmsRem = JvSwingUtils.makeButton("-",
+ "Remove selected input parameter", new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ iprmsRem_actionPerformed(e);
+
+ }
+ });
+
+ iprmButs.add(iprmsAdd,"wrap");
+ iprmButs.add(iprmsRem,"wrap");
+ iprmsList.add(iprmButs, "wrap");
+ inputs.add(iprmsList, "wrap");
+
+ // Return Parameters
+
+ rdataAdd = JvSwingUtils.makeButton("+", "Add return datatype",
+ new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ rdataAdd_actionPerformed(e);
+
+ }
+ });
+ rdataRem = JvSwingUtils.makeButton("-", "Remove return datatype",
+ new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ rdataRem_actionPerformed(e);
+
+ }
+ });
+ rdataNup = JvSwingUtils.makeButton("Move Up",
+ "Move return type up order", new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ rdataNup_actionPerformed(e);
+
+ }
+ });
+ rdataNdown = JvSwingUtils.makeButton("Move Down",
+ "Move return type down order", new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ rdataNdown_actionPerformed(e);
+
+ }
+ });
+
+ JPanel rparamList = new JPanel();
+ rparamList.setBorder(new TitledBorder("Data returned by service"));
+ rparamList.setLayout(new MigLayout());
+ rdata = new JList();
+ rdataVp = new JScrollPane();
+ rdataVp.getViewport().setView(rdata);
+ rparamList.add(rdataVp);
+ JPanel rparamButs = new JPanel();
+ rparamButs.setLayout(new MigLayout());
+ rparamButs.add(rdataAdd,"wrap");
+ rparamButs.add(rdataRem,"wrap");
+ rparamButs.add(rdataNup,"wrap");
+ rparamButs.add(rdataNdown,"wrap");
+ rparamList.add(rparamButs,"wrap");
+ inputs.add(rparamList,"wrap");
+
+ // Parse flat-text to a service
+
+
+ urldesc = new JTextArea(2,40);
+ urldesc.setEditable(true);
+ urldescVp = new JScrollPane();
+ urldescVp.setViewportView(urldesc);
+ JvSwingUtils.mgAddtoLayout(paste,"Flat file representation of this rest service using the Really Simple Bioinformatics Service formalism", new JLabel("RSBS Encoded Service:"), urldescVp,"wrap");
+
+ parseRes = new JTextArea(5,40);
+ parseResVp = new JScrollPane();
+ parseResVp.setViewportView(parseRes);
+ parseWarnings = new JPanel(new MigLayout());
+ parseWarnings.setBorder(new TitledBorder("Parsing errors"));
+ parseWarnings.setToolTipText("<html>"+JvSwingUtils.wrapTooltip("Results of parsing the RSBS representation")+"</html>");
+ parseWarnings.add(parseResVp, "wrap");
+ parseRes.setEditable(false);
+
+ setLayout(new BorderLayout());
+ add(panels, BorderLayout.CENTER);
+ okButton = JvSwingUtils.makeButton("OK", "", new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ ok_actionPerformed();
+ }
+ });
+ cancelButton = JvSwingUtils.makeButton("Cancel", "",
+ new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ cancel_actionPerformed();
+ }
+ });
+
+ }
+
+ protected void hSeparable_actionPerformed(ActionEvent arg0)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void vSeparable_actionPerformed(ActionEvent arg0)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void cancel_actionPerformed()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void ok_actionPerformed()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void iprmsAdd_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void iprmsRem_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void rdataAdd_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void rdataRem_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void rdataNup_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void rdataNdown_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void ok_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void cancel_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+}