From: jprocter Date: Mon, 29 Aug 2011 14:44:06 +0000 (+0100) Subject: JAL-919, JAL-715 - prototype service editing dialog using jalview parameter model... X-Git-Tag: Release_2_7~75 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=a789f790fbb3ab13f1967b42781b837b58bf9bbc;hp=5dfd1bdf67e6e0c916d22e67d498c0e956917c21;p=jalview.git JAL-919, JAL-715 - prototype service editing dialog using jalview parameter model to configure service definition and associated bug fixes to jalview.ws.rest package --- diff --git a/src/jalview/gui/RestInputParamEditDialog.java b/src/jalview/gui/RestInputParamEditDialog.java new file mode 100644 index 0000000..71fdb5d --- /dev/null +++ b/src/jalview/gui/RestInputParamEditDialog.java @@ -0,0 +1,249 @@ +package jalview.gui; + +import java.util.ArrayList; +import java.util.Hashtable; + +import javax.swing.JDialog; +import javax.swing.JInternalFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.event.ListSelectionEvent; + +import com.sun.tools.corba.se.idl.InvalidArgument; + +import net.miginfocom.swing.MigLayout; + +import jalview.jbgui.GRestInputParamEditDialog; +import jalview.ws.params.ArgumentI; +import jalview.ws.params.InvalidArgumentException; +import jalview.ws.params.OptionI; +import jalview.ws.params.ParameterI; +import jalview.ws.rest.InputType; +import jalview.ws.rest.RestServiceDescription; + +public class RestInputParamEditDialog extends GRestInputParamEditDialog + implements OptsParametersContainerI +{ + Hashtable typeclass = new Hashtable(); + + Hashtable> typeopts = new Hashtable>(); + + Hashtable opanps = new Hashtable(); + + private InputType getTypeFor(String name) + { + try + { + return (InputType) (typeclass.get(name).getConstructor() + .newInstance(null)); + } catch (Throwable x) + { + System.err + .println("Unexpected exception when instantiating rest input type."); + x.printStackTrace(); + } + return null; + } + + int reply; + JalviewDialog frame = new JalviewDialog() + { + + @Override + protected void raiseClosed() + { + + } + + @Override + protected void okPressed() + { + reply=JOptionPane.OK_OPTION; + } + + @Override + protected void cancelPressed() + { + reply=JOptionPane.CANCEL_OPTION; + + } + }; + InputType old,current; + public RestInputParamEditDialog( + RestServiceEditorPane restServiceEditorPane, + RestServiceDescription currentservice, InputType toedit) + { + initFor(restServiceEditorPane, currentservice, toedit); + frame.waitForInput(); + // TODO: warn user if they are about to overwrite an existing parameter because they have used the same name when editing a different parameter. + // TODO: make any press of the return key cause 'OK' to be pressed + } + private void initFor(RestServiceEditorPane restServiceEditorPane, + RestServiceDescription currentservice, InputType toedit) + { + okcancel.add(frame.cancel); + okcancel.add(frame.ok); + frame.initDialogFrame(dpane, true, true, "Edit parameter for service "+currentservice.getName(), 600,800); + + initTypeLists(); + reply=JOptionPane.CANCEL_OPTION; + old = toedit; + current = null; + if (old!=null) { + setStateFor(old); + } + updated = updated && reply==JOptionPane.OK_OPTION; + frame.validate(); + } + + public RestInputParamEditDialog( + RestServiceEditorPane restServiceEditorPane, + RestServiceDescription currentservice, String string) + { + initFor(restServiceEditorPane, currentservice,null); + tok.setText(string); + frame.waitForInput(); + } + + private void setStateFor(InputType current) + { + tok.setText(current.token); + OptsAndParamsPage opanp=opanps.get(current.getURLtokenPrefix()); + for (OptionI ops:current.getOptions()) + { + if (ops instanceof ParameterI) + { + opanp.setParameter((ParameterI) ops); + } else { + if (ops.getValue()!=null && ops.getValue().length()>0) { + opanp.selectOption(ops, ops.getValue()); + } + } + } + typeList.setSelectedValue(current.getURLtokenPrefix(), true); + type_SelectionChangedActionPerformed(null); + } + private void updateCurrentType() + { + if (typeList.getSelectedValue()!=null) { + InputType newType = getTypeFor((String)typeList.getSelectedValue()); + if (newType!=null) { + newType.token = tok.getText().trim(); + try { + newType.configureFromArgumentI(opanps.get(newType.getURLtokenPrefix()).getCurrentSettings()); + current=newType; + updated=true; + } catch (InvalidArgumentException ex) { + System.err.println("IMPLEMENTATION ERROR: Invalid argument for type : "+typeList.getSelectedValue()+"\n"); + ex.printStackTrace(); + } + } + } + + } + private void initTypeLists() + { + ArrayList types=new ArrayList(); + // populate type list + for (Class type : RestServiceDescription.getInputTypes()) + { + + InputType jtype = null; + try + { + JPanel inopts = new JPanel(new MigLayout()); + ArrayList opts = new ArrayList(), prms = new ArrayList(); + jtype = (InputType) (type.getConstructor().newInstance(null)); + typeclass.put(jtype.getURLtokenPrefix(), type); + // and populate parameters from this type + OptsAndParamsPage opanp = new OptsAndParamsPage(this,true); + opanps.put(jtype.getURLtokenPrefix(),opanp); + for (OptionI opt : jtype.getOptions()) + { + + if (opt instanceof ParameterI) + { + prms.add(opanp.addParameter((ParameterI) opt)); + } + else + { + opts.add(opanp.addOption(opt)); + } + } + // then tag the params at the end of the options. + for (JPanel pnl : prms) + { + opts.add(pnl); + } + typeopts.put(jtype.getURLtokenPrefix(), opts); + types.add(jtype.getURLtokenPrefix()); + } catch (Throwable x) + { + System.err + .println("Unexpected exception when instantiating rest input type."); + x.printStackTrace(); + } + } + typeList.setListData(types.toArray()); + + } + + @Override + protected void type_SelectionChangedActionPerformed(ListSelectionEvent e) + { + options.removeAll(); + String typen = (String) typeList.getSelectedValue(); + if (typeopts.get(typen) != null) + { + for (JPanel opt : typeopts.get(typen)) + { + opt.setOpaque(true); + options.add(opt,"wrap"); + } + options.invalidate(); + optionsPanel.setVisible(true); + } + else + { + optionsPanel.setVisible(false); + } + dpane.revalidate(); + updateCurrentType(); + } + + boolean updated=false; + public boolean wasUpdated() + { + return updated; + } + + @Override + public void refreshParamLayout() + { + options.invalidate(); + dpane.revalidate(); + } + + @Override + protected void tokChanged_actionPerformed() + { + if (tok.getText().trim().length()>0) + { + if (current!=null) + { + current.token = tok.getText().trim(); + updated = true; + } + } + } + @Override + public void argSetModified(Object modifiedElement, boolean b) + { + updated = updated | b; + if (updated) + { + updateCurrentType(); + } + } + +} diff --git a/src/jalview/gui/RestServiceEditorPane.java b/src/jalview/gui/RestServiceEditorPane.java index 581a44e..4f9c13e 100644 --- a/src/jalview/gui/RestServiceEditorPane.java +++ b/src/jalview/gui/RestServiceEditorPane.java @@ -1,37 +1,30 @@ package jalview.gui; -import jalview.bin.Cache; import jalview.io.packed.DataProvider.JvDataType; -import jalview.jbgui.*; +import jalview.jbgui.GRestServiceEditorPane; import jalview.ws.rest.InputType; import jalview.ws.rest.RestServiceDescription; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; 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.awt.event.MouseEvent; import java.util.HashMap; +import java.util.List; 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.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -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 { @@ -52,9 +45,6 @@ public class RestServiceEditorPane extends GRestServiceEditorPane // begin with initial text description box enabled. urldesc.addKeyListener(new KeyListener() { - long lastWait; - boolean doUpdate; - Thread updater=null; @Override public void keyTyped(KeyEvent e) { @@ -69,7 +59,6 @@ public class RestServiceEditorPane extends GRestServiceEditorPane @Override public void keyPressed(KeyEvent e) { - // TODO Auto-generated method stub } }); @@ -89,13 +78,21 @@ public class RestServiceEditorPane extends GRestServiceEditorPane } }); + currentservice = new RestServiceDescription("Analysis", "service description", "service name", "http://localhost/", "", null, false, false, '-'); + initGuiWith(currentservice); + refreshCutnPaste(false); + updateButtons(); } public RestServiceEditorPane(RestServiceDescription toedit) { - this(); + super(); oldservice = toedit; - currentservice = new RestServiceDescription(toedit); + if (oldservice!=null) + { currentservice = new RestServiceDescription(toedit); + } else { + currentservice = new RestServiceDescription("Analysis", "service description", "service name", "http://localhost/", "", null, false, false, '-'); + } initGuiWith(currentservice); refreshCutnPaste(false); updateButtons(); @@ -106,7 +103,7 @@ public class RestServiceEditorPane extends GRestServiceEditorPane */ public void updateButtons() { - cancelButton.setEnabled(oldservice != null); + cancelButton.setEnabled(true); okButton.setEnabled(currentservice != null && currentservice.isValid()); } @@ -123,12 +120,28 @@ public class RestServiceEditorPane extends GRestServiceEditorPane */ private void initGuiWith(RestServiceDescription currentservice) { + _iparam.clear(); + _rparam.clear(); + action.removeAllItems(); + action.addItem("Alignment"); + action.addItem("Analysis"); + gapChar.removeAllItems(); + gapChar.addItem("."); + gapChar.addItem(" "); + gapChar.addItem("-"); + if (currentservice==null) + { + name.setText(""); + descr.setText(""); + url.setText(""); + urlsuff.setText(""); + action.setSelectedItem("Analysis"); + gapChar.setSelectedItem("-"); + } else { name.setText(currentservice.getName()); descr.setText(currentservice.getDescription()); url.setText(currentservice.getPostUrl()); urlsuff.setText(currentservice.getUrlSuffix()); - _iparam.clear(); - _rparam.clear(); for (Map.Entry inparam : currentservice .getInputParams().entrySet()) { @@ -136,23 +149,143 @@ public class RestServiceEditorPane extends GRestServiceEditorPane + inparam.getValue().getURLtokenPrefix() + ":" + inparam.getValue().getURLEncodedParameter().toString()); } + for (JvDataType oparam : currentservice.getResultDataTypes()) { - _rparam.add((oparam.name())); + _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()); + + gapChar.setSelectedItem(""+currentservice.getGapCharacter()); + } revalidate(); } + private String getSelectedInputToken() + { + if (iprms.getSelectedIndex()>-1) + { + String toktoedit = (String) iprms.getSelectedValue(); + toktoedit=toktoedit.substring(0, toktoedit.indexOf(" ")); + return toktoedit; + } + return null; + } + @Override + protected void iprmListSelection_doubleClicked() + { + String toktoedit = getSelectedInputToken(); + if (toktoedit!=null) + { + InputType toedit = currentservice.getInputParams().get(toktoedit); + String oldParam=toktoedit; + RestInputParamEditDialog dialog=new RestInputParamEditDialog(this, currentservice, toedit); + if (dialog.wasUpdated()) { + currentservice.getInputParams().remove(oldParam); + currentservice.getInputParams().put(dialog.current.token, dialog.current); + initGuiWith(currentservice); + } + + } + } + @Override + protected void iprmsAdd_actionPerformed(ActionEvent e) + { + RestInputParamEditDialog dialog=new RestInputParamEditDialog(this, currentservice, "param"+(1+currentservice.getInputParams().size())); + if (dialog.wasUpdated()) { + currentservice.getInputParams().put(dialog.current.token, dialog.current); + initGuiWith(currentservice); + } + + } + @Override + protected void iprmsRem_actionPerformed(ActionEvent e) + { + String toktoedit = getSelectedInputToken(); + if (toktoedit!=null) + { + currentservice.getInputParams().remove(toktoedit); + initGuiWith(currentservice); + + } + } + @Override + protected void rdata_rightClicked(MouseEvent mouse) + { + final int rdatasel = rdata.getSelectedIndex(); + if (rdatasel>-1) + { + JPopupMenu popup = new JPopupMenu("Select return type"); + for (final JvDataType type:JvDataType.values()) { + popup.add(new JMenuItem(type.name())).addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + currentservice.getResultDataTypes().set(rdatasel, type); + initGuiWith(currentservice); + rdata.setSelectedIndex(rdatasel); + } + }); + } + popup.show(rdata, mouse.getX(), mouse.getY()); + } + } + @Override + protected void rdataAdd_actionPerformed(ActionEvent e) + { + int p; + if ((p=rdata.getSelectedIndex())>-1) + { + currentservice.getResultDataTypes().add(p+1, JvDataType.ANNOTATION); + } else { + currentservice.addResultDatatype(JvDataType.ANNOTATION); + } + initGuiWith(currentservice); + rdata.setSelectedIndex(p==-1 ? currentservice.getResultDataTypes().size()-1 : p+1); + } + @Override + protected void rdataNdown_actionPerformed(ActionEvent e) + { + int p; + if ((p=rdata.getSelectedIndex())>-1 && p<_rparam.size()-1) + { + List rtypes = currentservice.getResultDataTypes(); + JvDataType below = rtypes.get(p+1); + rtypes.set(p+1, rtypes.get(p)); + rtypes.set(p, below); + initGuiWith(currentservice); + rdata.setSelectedIndex(p+1); + } + } + @Override + protected void rdataNup_actionPerformed(ActionEvent e) + { + int p; + if ((p=rdata.getSelectedIndex())>0) + { + List rtypes = currentservice.getResultDataTypes(); + JvDataType above = rtypes.get(p-1); + rtypes.set(p-1, rtypes.get(p)); + rtypes.set(p, above); + initGuiWith(currentservice); + rdata.setSelectedIndex(p-1); + } + } + @Override + protected void rdataRem_actionPerformed(ActionEvent e) + { + if (rdata.getSelectedIndex()>-1) + { + currentservice.getResultDataTypes().remove(rdata.getSelectedIndex()); + initGuiWith(currentservice); + } + } private boolean updateServiceFromGui() { - boolean valid=true; MapinputTypes = new HashMap(); StringBuffer warnings=new StringBuffer(); for (String its:_iparam) @@ -246,37 +379,35 @@ public class RestServiceEditorPane extends GRestServiceEditorPane public void run() { + boolean nulserv=true; 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()), + (nulserv=!nulserv) ? new RestServiceEditorPane(jalview.ws.rest.RestClient + .makeShmmrRestClient().getRestDescription()) : new RestServiceEditorPane(), BorderLayout.CENTER); - df.setBounds(100, 100, 400, 600); + df.setBounds(100, 100, 600, 400); 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 } diff --git a/src/jalview/jbgui/GRestInputParamEditDialog.java b/src/jalview/jbgui/GRestInputParamEditDialog.java new file mode 100644 index 0000000..a277759 --- /dev/null +++ b/src/jalview/jbgui/GRestInputParamEditDialog.java @@ -0,0 +1,93 @@ +package jalview.jbgui; + +import java.awt.Dimension; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import jalview.gui.JvSwingUtils; +import jalview.gui.OptsAndParamsPage; + +import javax.swing.*; +import javax.swing.border.TitledBorder; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import net.miginfocom.swing.MigLayout; + + +public class GRestInputParamEditDialog +{ + + protected JPanel dpane; + protected JPanel okcancel; + protected JList typeList; + protected JTextField tok; + protected JPanel options; + protected JPanel optionsPanel; + public GRestInputParamEditDialog() + { + jbInit(); + } + protected void jbInit() { + dpane = new JPanel(new MigLayout("","[][][fill]","[][fill][]")); + dpane.setPreferredSize(new Dimension(110+100+OptsAndParamsPage.PARAM_WIDTH,400)); + typeList = new JList(); + typeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + typeList.getSelectionModel().addListSelectionListener(new ListSelectionListener() + { + + @Override + public void valueChanged(ListSelectionEvent e) + { + type_SelectionChangedActionPerformed(e); + }; + }); + + tok = new JTextField(); + tok.addKeyListener(new KeyListener() + { + + @Override + public void keyTyped(KeyEvent e) + { + } + + @Override + public void keyReleased(KeyEvent e) + { + tokChanged_actionPerformed(); + } + + @Override + public void keyPressed(KeyEvent e) + { + + } + }); + options = new JPanel(new MigLayout("","[grow 100,fill]","")); + optionsPanel = new JPanel(new MigLayout("","[fill]","[fill]")); + JScrollPane optionView = new JScrollPane(); + optionView.setViewportView(options); + JvSwingUtils.mgAddtoLayout(dpane, "Input Parameter name", new JLabel("Name"), tok, "grow,spanx 3,wrap"); + JPanel paramsType = new JPanel(new MigLayout("","[grow 100,fill]","[grow 100,fill]")); + paramsType.setBorder(new TitledBorder("Select input type")); + JScrollPane jlistScroller=new JScrollPane(); + jlistScroller.setViewportView(typeList); + paramsType.add(jlistScroller,"spanx 2,spany 2"); + dpane.add(paramsType); + optionsPanel.setBorder(new TitledBorder("Set options for type")); + optionsPanel.add(optionView); + dpane.add(optionsPanel,"wrap"); + okcancel = new JPanel(new MigLayout("","[center][center]","[]")); + dpane.add(okcancel,"spanx 3,wrap"); + + } + protected void tokChanged_actionPerformed() + { + + } + protected void type_SelectionChangedActionPerformed(ListSelectionEvent e) + { + } + +} diff --git a/src/jalview/jbgui/GRestServiceEditorPane.java b/src/jalview/jbgui/GRestServiceEditorPane.java index 69b9704..c80e789 100644 --- a/src/jalview/jbgui/GRestServiceEditorPane.java +++ b/src/jalview/jbgui/GRestServiceEditorPane.java @@ -8,6 +8,8 @@ import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; import javax.swing.BoxLayout; import javax.swing.JButton; @@ -20,12 +22,14 @@ import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.JViewport; +import javax.swing.ListSelectionModel; 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 javax.swing.event.ListSelectionListener; import net.miginfocom.swing.MigLayout; @@ -102,13 +106,13 @@ public class GRestServiceEditorPane extends JPanel { 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); + descr = new JTextArea(4, 60); descrVp = new JScrollPane(); descrVp.setViewportView(descr); JvSwingUtils.mgAddtoLayout(cpanel, "Brief description of service", new JLabel("Description:"), descrVp,"wrap"); - url = new JTextArea(2, 20); + url = new JTextArea(2, 60); urlVp = new JScrollPane(); urlVp.setViewportView(url); JvSwingUtils @@ -118,7 +122,7 @@ public class GRestServiceEditorPane extends JPanel { new JLabel("POST URL:"), urlVp,"wrap"); urlsuff = new JTextArea(); - urlsuff.setColumns(20); + urlsuff.setColumns(60); JvSwingUtils .mgAddtoLayout( @@ -179,10 +183,51 @@ public class GRestServiceEditorPane extends JPanel { // Inputparams JPanel iprmsList = new JPanel(); iprmsList.setBorder(new TitledBorder("Data input parameters")); - iprmsList.setLayout(new MigLayout()); + iprmsList.setLayout(new MigLayout("","[grow 90, fill][]")); iprmVp = new JScrollPane(); iprmVp.getViewport().setView(iprms = new JList()); iprmsList.add(iprmVp); + iprms.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + iprms.addMouseListener(new MouseListener() + { + + @Override + public void mouseReleased(MouseEvent e) + { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) + { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent e) + { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent e) + { + // TODO Auto-generated method stub + + } + + @Override + public void mouseClicked(MouseEvent e) + { + if (e.getClickCount()>1) { + iprmListSelection_doubleClicked(); + } + + } + }); JPanel iprmButs = new JPanel(); iprmButs.setLayout(new MigLayout()); @@ -263,8 +308,49 @@ public class GRestServiceEditorPane extends JPanel { JPanel rparamList = new JPanel(); rparamList.setBorder(new TitledBorder("Data returned by service")); - rparamList.setLayout(new MigLayout()); + rparamList.setLayout(new MigLayout("","[grow 90, fill][]")); rdata = new JList(); + rdata.setToolTipText("Right click to edit currently selected parameter."); + rdata.addMouseListener(new MouseListener() + { + + @Override + public void mouseReleased(MouseEvent arg0) + { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent arg0) + { + + } + + @Override + public void mouseExited(MouseEvent arg0) + { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent arg0) + { + // TODO Auto-generated method stub + + } + + @Override + public void mouseClicked(MouseEvent arg0) + { + if (arg0.getButton()==MouseEvent.BUTTON3) + { + rdata_rightClicked(arg0); + } + + } + }); rdataVp = new JScrollPane(); rdataVp.getViewport().setView(rdata); rparamList.add(rdataVp); @@ -280,7 +366,7 @@ public class GRestServiceEditorPane extends JPanel { // Parse flat-text to a service - urldesc = new JTextArea(4,50); + urldesc = new JTextArea(4,60); urldesc.setEditable(true); urldesc.setWrapStyleWord(true); urldescVp = new JScrollPane(); @@ -296,7 +382,7 @@ public class GRestServiceEditorPane extends JPanel { parseResVp = new JScrollPane(); parseResVp.setViewportView(parseRes); parseRes.setWrapStyleWord(true); - parseRes.setColumns(40); + parseRes.setColumns(60); parseWarnings = new JPanel(new MigLayout("","[grow 100, fill]", "[grow 100, fill]")); parseWarnings.setBorder(new TitledBorder("Parsing errors")); parseWarnings.setToolTipText(""+JvSwingUtils.wrapTooltip("Results of parsing the RSBS representation")+""); @@ -327,6 +413,18 @@ public class GRestServiceEditorPane extends JPanel { } + protected void rdata_rightClicked(MouseEvent arg0) + { + // TODO Auto-generated method stub + + } + + protected void iprmListSelection_doubleClicked() + { + // TODO Auto-generated method stub + + } + protected void hSeparable_actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub diff --git a/src/jalview/ws/rest/InputType.java b/src/jalview/ws/rest/InputType.java index 3c0b511..bc55893 100644 --- a/src/jalview/ws/rest/InputType.java +++ b/src/jalview/ws/rest/InputType.java @@ -1,5 +1,11 @@ package jalview.ws.rest; +import jalview.ws.params.ArgumentI; +import jalview.ws.params.InvalidArgumentException; +import jalview.ws.params.OptionI; +import jalview.ws.params.ParameterI; +import jalview.ws.params.simple.IntegerParameter; +import jalview.ws.params.simple.Option; import jalview.ws.rest.params.SeqGroupIndexVector; import java.io.IOException; @@ -10,6 +16,7 @@ import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.regex.Matcher; @@ -32,7 +39,17 @@ public abstract class InputType { * not used yet */ boolean replaceids; - public enum molType { NUC, PROT, MIX} + public enum molType { NUC, PROT, MIX; + + public static Collection toStringValues() + { + Collection c = new ArrayList(); + for (molType type:values()) + { + c.add(type.toString()); + } + return c; + }} public String token; public int min=1; public int max=0; // unbounded @@ -120,7 +137,7 @@ public abstract class InputType { * @return true if property was set */ public abstract boolean configureProperty(String tok, String val, StringBuffer warnings); - + /** * Get unique key for this type of parameter in a URL encoding. * @return the string that prefixes an input parameter of InputType type in the string returned from getURLEncodedParameter @@ -157,7 +174,13 @@ public abstract class InputType { warnings.append("Invalid value for parameter "+mtch.group(1).toLowerCase()+" '"+mtch.group(2)+"' (expected an integer)\n"); } - valid = valid && configureProperty(mtch.group(1), mtch.group(2), warnings); + if (!configureProperty(mtch.group(1), mtch.group(2), warnings)) { + if (warnings.length()==0) + { + warnings.append("Failed to configure InputType :"+getURLtokenPrefix()+" with property string: '"+mtch.group(0)+"'\n (token is '"+mtch.group(1)+"' and value is '"+mtch.group(2)+"')\n"); + } + valid=false; + } } } return valid; @@ -169,7 +192,58 @@ public abstract class InputType { prms.add("min='"+min+"'"); } if (max!=0) { - prms.add("min='"+max+"'"); + prms.add("max='"+max+"'"); } } + + public abstract List getOptions(); + public List getBaseOptions() + { + ArrayList opts = new ArrayList(); + opts.add(new IntegerParameter("min","Minimum number of data of this type",true,1,min,0,-1)); + opts.add(new IntegerParameter("max","Maximum number of data of this type",false,0,max,0,-1)); + return opts; + } + /** + * make a copy of this InputType + * @return + * may not be needed + public abstract InputType copy(); + */ + + /** + * parse a set of configuration options + * @param currentSettings - modified settings originally from getOptions + * @throws InvalidArgumentException thrown if currentSettings contains invalid options for this type. + */ + public void configureFromArgumentI(List currentSettings) throws InvalidArgumentException + { + ArrayList urltoks = new ArrayList(); + String rg; + for (ArgumentI arg: currentSettings) + { + if (arg instanceof ParameterI) + { + rg=arg.getName()+"='"+arg.getValue()+"'"; + } else { + // TODO: revise architecture - this is counter intuitive - options with different values to their names are actually parameters + rg=(arg.getValue().length()>0) ? (arg.getValue().equals(arg.getName()) ? arg.getName():arg.getName()+"='"+arg.getValue()+"'") + : arg.getName(); + } + if (rg.length()>0) { + urltoks.add(rg); + } + } + StringBuffer warnings; + if (!configureFromURLtokenString(urltoks, warnings=new StringBuffer())) + { + throw new InvalidArgumentException(warnings.toString()); + } + } + protected OptionI createMolTypeOption(String name, String descr, + boolean req, molType curType, molType defType) + { + return new Option(name,descr, req, defType==null ? "" : defType.toString(), curType==null ? "" : curType.toString(),molType.toStringValues(), + null); + } } \ No newline at end of file diff --git a/src/jalview/ws/rest/RestServiceDescription.java b/src/jalview/ws/rest/RestServiceDescription.java index 20895a2..dec4d7c 100644 --- a/src/jalview/ws/rest/RestServiceDescription.java +++ b/src/jalview/ws/rest/RestServiceDescription.java @@ -64,12 +64,15 @@ public class RestServiceDescription { super(); this.details = new UIinfo(); - details.Action = action; - details.description = description; - details.Name = name; - this.postUrl = postUrl; - this.urlSuffix = urlSuffix; - this.inputParams = inputParams; + details.Action = action == null ? "" : action; + details.description = description == null ? "" : description; + details.Name = name == null ? "" : name; + this.postUrl = postUrl == null ? "" : postUrl; + this.urlSuffix = urlSuffix == null ? "" : urlSuffix; + if (inputParams != null) + { + this.inputParams = inputParams; + } this.hseparable = hseparable; this.vseparable = vseparable; this.gapCharacter = gapCharacter; @@ -229,7 +232,7 @@ public class RestServiceDescription /** * input info given as key/value pairs - mapped to post arguments */ - Map inputParams = new HashMap(); + Map inputParams = new HashMap(); /** * assigns the given inputType it to its corresponding input parameter token @@ -318,30 +321,20 @@ public class RestServiceDescription public RestServiceDescription(RestServiceDescription toedit) { - // Rather then do the above, we cheat and use our human readable serialization code to clone everything + // Rather then do the above, we cheat and use our human readable + // serialization code to clone everything this(toedit.toString()); /** - if (toedit == null) - { - return; - } - /** - urlSuffix = toedit.urlSuffix; - postUrl = toedit.postUrl; - hseparable = toedit.hseparable; - vseparable = toedit.vseparable; - gapCharacter = toedit.gapCharacter; - details = new RestServiceDescription.UIinfo(); - details.Action = toedit.details.Action; - details.description = toedit.details.description; - details.Name = toedit.details.Name; - for (InputType itype: toedit.inputParams.values()) - { - inputParams.put(itype.token, itype.clone()); - - } - - */ + * if (toedit == null) { return; } /** urlSuffix = toedit.urlSuffix; postUrl + * = toedit.postUrl; hseparable = toedit.hseparable; vseparable = + * toedit.vseparable; gapCharacter = toedit.gapCharacter; details = new + * RestServiceDescription.UIinfo(); details.Action = toedit.details.Action; + * details.description = toedit.details.description; details.Name = + * toedit.details.Name; for (InputType itype: toedit.inputParams.values()) { + * inputParams.put(itype.token, itype.clone()); + * + * } + */ // TODO Implement copy constructor NOW*/ } @@ -380,12 +373,13 @@ public class RestServiceDescription return null; java.util.ArrayList jv = new ArrayList(); int cp = 0, pos, escape; - boolean wasescaped = false; + boolean wasescaped = false,wasquoted=false; String lstitem = null; while ((pos = list.indexOf(separator, cp)) >= cp) { - escape = (pos>0 && list.charAt(pos - 1) == '\\') ? -1 : 0; - if (wasescaped) + + escape = (pos > 0 && list.charAt(pos - 1) == '\\') ? -1 : 0; + if (wasescaped || wasquoted) { // append to previous pos jv.set(jv.size() - 1, @@ -399,11 +393,20 @@ public class RestServiceDescription } cp = pos + seplen; wasescaped = escape == -1; + if (!wasescaped) + { + // last separator may be in an unmatched quote + if (java.util.regex.Pattern.matches("('[^']*')*[^']*'",lstitem)) + { + wasquoted=true; + } + } + } if (cp < list.length()) { String c = list.substring(cp); - if (wasescaped) + if (wasescaped || wasquoted) { // append final separator jv.set(jv.size() - 1, lstitem + separator + c); @@ -455,7 +458,7 @@ public class RestServiceDescription { if (list[i] != null) { - if (v.length()>0) + if (v.length() > 0) { v.append(separator); } @@ -496,7 +499,7 @@ public class RestServiceDescription return true; } ; - boolean valid=true; + boolean valid = true; String val = null; int i; for (String prop : props) @@ -521,9 +524,9 @@ public class RestServiceDescription } if (prop.equals("gapCharacter")) { - if (val == null || val.length()==0 || val.length() > 1) + if (val == null || val.length() == 0 || val.length() > 1) { - valid=false; + valid = false; warnings.append((warnings.length() > 0 ? "\n" : "") + ("Invalid service property: gapCharacter=' ' (single character) - was given '" + val + "'")); @@ -535,9 +538,9 @@ public class RestServiceDescription } if (prop.equals("returns")) { - int l=warnings.length(); + int l = warnings.length(); _configureOutputFormatFrom(val, warnings); - valid = (l!=warnings.length()); + valid = (l != warnings.length()); } } return valid; @@ -546,7 +549,7 @@ public class RestServiceDescription private String _genOutputFormatString() { String buff = ""; - if (resultData==null) + if (resultData == null) { return ""; } @@ -564,9 +567,10 @@ public class RestServiceDescription private void _configureOutputFormatFrom(String outstring, StringBuffer warnings) { - if (outstring.indexOf(";")==-1) { + if (outstring.indexOf(";") == -1) + { // we add a token, for simplicity - outstring = outstring+";"; + outstring = outstring + ";"; } StringTokenizer st = new StringTokenizer(outstring, ";"); String tok = ""; @@ -637,7 +641,7 @@ public class RestServiceDescription details.Name = list[0]; details.Action = list[1]; details.description = list[2]; - invalid|=!configureFromServiceInputProperties(list[3], warnings); + invalid |= !configureFromServiceInputProperties(list[3], warnings); if (list.length > 5) { urlSuffix = list[4]; @@ -645,8 +649,11 @@ public class RestServiceDescription } else { - urlSuffix = null; - invalid |= !configureFromInputParamEncodedUrl(list[4], warnings); + if (list.length > 4) + { + urlSuffix = null; + invalid |= !configureFromInputParamEncodedUrl(list[4], warnings); + } } return !invalid; } @@ -746,7 +753,8 @@ public class RestServiceDescription iprmparams = iprm.substring(colon + 1); iprm = iprm.substring(0, colon); } - valid = parseTypeString(prms.group(0), tok, iprm, iprmparams, iparams, warnings); + valid = parseTypeString(prms.group(0), tok, iprm, iprmparams, + iparams, warnings); } if (valid) { @@ -764,19 +772,25 @@ public class RestServiceDescription return valid; } - public static boolean parseTypeString(String fullstring, String tok, String iprm, String iprmparams, - Map iparams, StringBuffer warnings) + public static Class[] getInputTypes() { - boolean valid=true; - InputType jinput; // TODO - find a better way of maintaining this classlist - for (Class type : new Class[] + return new Class[] { jalview.ws.rest.params.Alignment.class, jalview.ws.rest.params.AnnotationFile.class, SeqGroupIndexVector.class, jalview.ws.rest.params.SeqIdVector.class, jalview.ws.rest.params.SeqVector.class, - jalview.ws.rest.params.Tree.class }) + jalview.ws.rest.params.Tree.class }; + } + + public static boolean parseTypeString(String fullstring, String tok, + String iprm, String iprmparams, Map iparams, + StringBuffer warnings) + { + boolean valid = true; + InputType jinput; + for (Class type : getInputTypes()) { try { @@ -786,20 +800,20 @@ public class RestServiceDescription ArrayList al = new ArrayList(); for (String prprm : separatorListToArray(iprmparams, ",")) { + // hack to ensure that strings like "sep=','" containing unescaped commas as values are concatenated al.add(prprm.trim()); } if (!jinput.configureFromURLtokenString(al, warnings)) { valid = false; - warnings.append("Failed to parse '" + fullstring - + "' as a " + jinput.getURLtokenPrefix() - + " input tag.\n"); + warnings.append("Failed to parse '" + fullstring + "' as a " + + jinput.getURLtokenPrefix() + " input tag.\n"); } else { jinput.token = tok; iparams.put(tok, jinput); - valid=true; + valid = true; } break; } @@ -812,9 +826,20 @@ public class RestServiceDescription return valid; } - public static void main(String argv[]) { + // test separator list + try { + assert(separatorListToArray("foo=',',min='foo',max='1,2,3',fa=','", ",").length==4); + if (separatorListToArray("minsize='2', sep=','", ",").length==2) + { + assert(false); + } + + } catch (AssertionError x) + { + System.err.println("separatorListToArray is faulty."); + } if (argv.length == 0) { if (!testRsdExchange("Test using default Shmmr service", @@ -971,7 +996,7 @@ public class RestServiceDescription return jobId + urlSuffix; } - private List resultData=new ArrayList(); + private List resultData = new ArrayList(); /** * @@ -1003,5 +1028,5 @@ public class RestServiceDescription { return resultData; } - + } diff --git a/src/jalview/ws/rest/params/Alignment.java b/src/jalview/ws/rest/params/Alignment.java index 770b564..dc6e6e8 100644 --- a/src/jalview/ws/rest/params/Alignment.java +++ b/src/jalview/ws/rest/params/Alignment.java @@ -1,6 +1,9 @@ package jalview.ws.rest.params; import jalview.datamodel.AlignmentI; +import jalview.ws.params.OptionI; +import jalview.ws.params.simple.BooleanOption; +import jalview.ws.params.simple.Option; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; @@ -18,6 +21,7 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.Charset; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.apache.http.entity.mime.content.ContentBody; @@ -47,7 +51,7 @@ public class Alignment extends InputType /** * input data as a file upload rather than inline content */ - public boolean writeAsFile; + public boolean writeAsFile=false; @Override public ContentBody formatForInput(RestJob rj) @@ -165,4 +169,20 @@ public class Alignment extends InputType } return false; } + @Override + public List getOptions() + { + List lst = getBaseOptions(); + lst.add(new BooleanOption("jvsuffix","Append jalview style /start-end suffix to ID", false, false, jvsuffix, null)); + lst.add(new BooleanOption("writeasfile","Append jalview style /start-end suffix to ID", false, false, writeAsFile, null)); + + lst.add(new Option("format", + "Alignment upload format", true, "FASTA", + format, Arrays.asList(jalview.io.FormatAdapter.WRITEABLE_FORMATS), null)); + lst.add(createMolTypeOption("type", "Sequence type", false, type, + null)); + + return lst; + } + } \ No newline at end of file diff --git a/src/jalview/ws/rest/params/AnnotationFile.java b/src/jalview/ws/rest/params/AnnotationFile.java index 5abf0fc..b1681a0 100644 --- a/src/jalview/ws/rest/params/AnnotationFile.java +++ b/src/jalview/ws/rest/params/AnnotationFile.java @@ -1,6 +1,8 @@ package jalview.ws.rest.params; import jalview.datamodel.AlignmentI; +import jalview.ws.params.OptionI; +import jalview.ws.params.simple.Option; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; @@ -9,6 +11,7 @@ import jalview.ws.rest.InputType.molType; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.apache.http.entity.mime.content.ContentBody; @@ -90,4 +93,15 @@ public class AnnotationFile extends InputType { } return false; } + @Override + public List getOptions() + { + // TODO - consider disregarding base options here. + List lst = getBaseOptions(); + lst.add(new Option("format", + "Alignment annotation upload format", true, JVANNOT, + format, Arrays.asList(new String[] + { JVANNOT, CSVANNOT}), null)); + return lst; + } } diff --git a/src/jalview/ws/rest/params/JobConstant.java b/src/jalview/ws/rest/params/JobConstant.java index 01b54cb..fddfd3b 100644 --- a/src/jalview/ws/rest/params/JobConstant.java +++ b/src/jalview/ws/rest/params/JobConstant.java @@ -1,5 +1,6 @@ package jalview.ws.rest.params; +import jalview.ws.params.OptionI; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; @@ -80,4 +81,11 @@ public class JobConstant extends InputType warnings.append("IMPLEMENTATION ERROR: No Properties to configure for a Constant parameter."); return false; } + + @Override + public List getOptions() + { + // empty list - this parameter isn't configurable, so don't try. + return new ArrayList(); + } } diff --git a/src/jalview/ws/rest/params/SeqGroupIndexVector.java b/src/jalview/ws/rest/params/SeqGroupIndexVector.java index 7df7d1c..ba2c1b3 100644 --- a/src/jalview/ws/rest/params/SeqGroupIndexVector.java +++ b/src/jalview/ws/rest/params/SeqGroupIndexVector.java @@ -3,6 +3,9 @@ package jalview.ws.rest.params; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.ws.params.OptionI; +import jalview.ws.params.simple.IntegerParameter; +import jalview.ws.params.simple.Option; import jalview.ws.rest.AlignmentProcessor; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; @@ -12,6 +15,7 @@ import jalview.ws.rest.InputType.molType; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Vector; @@ -70,12 +74,13 @@ public class SeqGroupIndexVector extends InputType implements // assume that alignment is properly ordered so groups form consecutive // blocks ArrayList gl = new ArrayList(); - int p=0; + int p = 0; for (SequenceGroup sg : (Vector) al.getGroups()) { - if (sg.getSize()0) + // are there any more sequences ungrouped that should be added as a single + // remaining group ? - these might be at the start or the end + if (gl.size() > 0) { - int[] tail=gl.get(0); - if (tail[0]>0) { - if (1+tail[0]>minsize) + int[] tail = gl.get(0); + if (tail[0] > 0) { - gl.add(0,new int[] { 0,tail[0]-1}); - } else { - // lets be intelligent here - if the remaining sequences aren't enough to make a final group, then don't make one. - // throw new NoValidInputDataException("Group from remaining ungrouped sequences in input contains less than "+minsize+" sequences."); + if (1 + tail[0] > minsize) + { + gl.add(0, new int[] + { 0, tail[0] - 1 }); + } + else + { + // lets be intelligent here - if the remaining sequences aren't enough + // to make a final group, then don't make one. + // throw new + // NoValidInputDataException("Group from remaining ungrouped sequences in input contains less than "+minsize+" sequences."); + } } - } else { - tail=gl.get(gl.size()-1); - if (1+tail[1]minsize) { - gl.add(new int[] { tail[1]+1, al.getHeight()-1}); - } else { - // lets be intelligent here - if the remaining sequences aren't enough to make a final group, then don't make one. - // throw new NoValidInputDataException("Group from remaining ungrouped sequences in input contains less than "+minsize+" sequences."); + if (al.getHeight() - (1 + tail[1]) > minsize) + { + gl.add(new int[] + { tail[1] + 1, al.getHeight() - 1 }); + } + else + { + // lets be intelligent here - if the remaining sequences aren't + // enough to make a final group, then don't make one. + // throw new + // NoValidInputDataException("Group from remaining ungrouped sequences in input contains less than "+minsize+" sequences."); } } } - } else { - gl.add(new int[] { 0, al.getHeight()-1}); } - if (min>=0 && gl.size()0 && gl.size()>max) + if (min >= 0 && gl.size() < min) { - throw new NoValidInputDataException("Too many sequence groups for input. Need at most "+max+" groups (including ungrouped regions)."); + throw new NoValidInputDataException( + "Not enough sequence groups for input. Need at least " + min + + " groups (including ungrouped regions)."); + } + if (max > 0 && gl.size() > max) + { + throw new NoValidInputDataException( + "Too many sequence groups for input. Need at most " + max + + " groups (including ungrouped regions)."); } int[][] vals = gl.toArray(new int[gl.size()][]); int[] srt = new int[gl.size()]; @@ -160,28 +187,34 @@ public class SeqGroupIndexVector extends InputType implements } /** - * set minimum number of sequences allowed in a partition. Default is 1 sequence. - * @param i (number greater than 1) + * set minimum number of sequences allowed in a partition. Default is 1 + * sequence. + * + * @param i + * (number greater than 1) */ public void setMinsize(int i) { - if (minsize>=1) - { - minsize=i; - } else { - minsize=1; - } + if (minsize >= 1) + { + minsize = i; + } + else + { + minsize = 1; + } } + @Override public List getURLEncodedParameter() { ArrayList prms = new ArrayList(); super.addBaseParams(prms); - prms.add("minsize='"+ minsize+"'"); - prms.add("sep='"+ sep+"'"); - if (type!=null) + prms.add("minsize='" + minsize + "'"); + prms.add("sep='" + sep + "'"); + if (type != null) { - prms.add("type='"+type+"'"); + prms.add("type='" + type + "'"); } return prms; } @@ -199,32 +232,36 @@ public class SeqGroupIndexVector extends InputType implements if (tok.startsWith("sep")) { - sep=val; + sep = val; return true; } if (tok.startsWith("minsize")) { - try { - minsize=Integer.valueOf(val); - if (minsize>=0) - return true; + try + { + minsize = Integer.valueOf(val); + if (minsize >= 0) + return true; } catch (Exception x) { - + } - warnings.append("Invalid minsize value '"+val+"'. Must be a positive integer.\n"); + warnings.append("Invalid minsize value '" + val + + "'. Must be a positive integer.\n"); } if (tok.startsWith("type")) { - try { - type=molType.valueOf(val); + try + { + type = molType.valueOf(val); return true; } catch (Exception x) { - warnings.append("Invalid molecule type '"+val+"'. Must be one of ("); - for (molType v:molType.values()) + warnings.append("Invalid molecule type '" + val + + "'. Must be one of ("); + for (molType v : molType.values()) { - warnings.append(" "+v); + warnings.append(" " + v); } warnings.append(")\n"); } @@ -232,4 +269,17 @@ public class SeqGroupIndexVector extends InputType implements return false; } + @Override + public List getOptions() + { + List lst = getBaseOptions(); + lst.add(new Option("sep", + "Separator character between elements of vector", true, ",", + sep, Arrays.asList(new String[] + { " ", ",", ";", "\t", "|" }), null)); + lst.add(new IntegerParameter("minsize", "Minimum size of partition allowed by service", true, 1, minsize, 1,0)); + lst.add(createMolTypeOption("type", "Sequence type", false, type, molType.MIX)); + return lst; + } + } diff --git a/src/jalview/ws/rest/params/SeqIdVector.java b/src/jalview/ws/rest/params/SeqIdVector.java index 5f7c551..c77c8da 100644 --- a/src/jalview/ws/rest/params/SeqIdVector.java +++ b/src/jalview/ws/rest/params/SeqIdVector.java @@ -2,6 +2,8 @@ package jalview.ws.rest.params; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceI; +import jalview.ws.params.OptionI; +import jalview.ws.params.simple.Option; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; @@ -10,6 +12,7 @@ import jalview.ws.rest.InputType.molType; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -18,27 +21,33 @@ import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.StringBody; /** - * input a list of sequence IDs separated by some separator + * input a list of sequence IDs separated by some separator + * * @author JimP - * + * */ -public class SeqIdVector extends InputType { +public class SeqIdVector extends InputType +{ public SeqIdVector() { - super(new Class[] { AlignmentI.class} ); + super(new Class[] + { AlignmentI.class }); } /** * separator for list of sequence IDs - default is ',' */ - String sep=","; + String sep = ","; + molType type; + @Override - public ContentBody formatForInput(RestJob rj) throws UnsupportedEncodingException, NoValidInputDataException + public ContentBody formatForInput(RestJob rj) + throws UnsupportedEncodingException, NoValidInputDataException { StringBuffer idvector = new StringBuffer(); - boolean list=false; - for (SequenceI seq:rj.getSequencesForInput(token, type)) + boolean list = false; + for (SequenceI seq : rj.getSequencesForInput(token, type)) { if (list) { @@ -47,44 +56,66 @@ public class SeqIdVector extends InputType { idvector.append(seq.getName()); } return new StringBody(idvector.toString()); - } + } + @Override public List getURLEncodedParameter() { ArrayList prms = new ArrayList(); super.addBaseParams(prms); - prms.add("sep='"+ sep+"'"); - prms.add("type='"+type+"'"); + prms.add("sep='" + sep + "'"); + if (type!=null) + { + prms.add("type='"+type+"'"); + } return prms; } + @Override public String getURLtokenPrefix() { return "SEQIDS"; } + @Override - public boolean configureProperty(String tok, String val, StringBuffer warnings) + public boolean configureProperty(String tok, String val, + StringBuffer warnings) { if (tok.startsWith("sep")) { - sep=val; + sep = val; return true; } if (tok.startsWith("type")) { - try { - type=molType.valueOf(val); + try + { + type = molType.valueOf(val); return true; } catch (Exception x) { - warnings.append("Invalid molecule type '"+val+"'. Must be one of ("); - for (molType v:molType.values()) + warnings.append("Invalid molecule type '" + val + + "'. Must be one of ("); + for (molType v : molType.values()) { - warnings.append(" "+v); + warnings.append(" " + v); } warnings.append(")\n"); } } return false; } + + @Override + public List getOptions() + { + List lst = getBaseOptions(); + lst.add(new Option("sep", + "Separator character between elements of vector", true, ",", + sep, Arrays.asList(new String[] + { " ", ",", ";", "\t", "|" }), null)); + lst.add(createMolTypeOption("type", "Sequence type", false, type, + null)); + return lst; + } } diff --git a/src/jalview/ws/rest/params/SeqVector.java b/src/jalview/ws/rest/params/SeqVector.java index 3a5b414..040e000 100644 --- a/src/jalview/ws/rest/params/SeqVector.java +++ b/src/jalview/ws/rest/params/SeqVector.java @@ -2,6 +2,8 @@ package jalview.ws.rest.params; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceI; +import jalview.ws.params.OptionI; +import jalview.ws.params.simple.Option; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; @@ -10,10 +12,12 @@ import jalview.ws.rest.InputType.molType; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.StringBody; +import org.jmol.util.ArrayUtil; /** * input a list of sequences separated by some separator @@ -49,7 +53,10 @@ public class SeqVector extends InputType { ArrayList prms = new ArrayList(); super.addBaseParams(prms); prms.add("sep='"+ sep+"'"); - prms.add("type='"+type+"'"); + if (type!=null) + { + prms.add("type='"+type+"'"); + } return prms; } @@ -87,4 +94,18 @@ public class SeqVector extends InputType { return false; } + @Override + public List getOptions() + { + List lst = getBaseOptions(); + lst.add(new Option("sep", + "Separator character between elements of vector", true, ",", + sep, Arrays.asList(new String[] + { " ", ",", ";", "\t", "|" }), null)); + lst.add(createMolTypeOption("type", "Sequence type", false, type, + molType.MIX)); + + return lst; + } + } \ No newline at end of file diff --git a/src/jalview/ws/rest/params/Tree.java b/src/jalview/ws/rest/params/Tree.java index 69d2f58..ff54654 100644 --- a/src/jalview/ws/rest/params/Tree.java +++ b/src/jalview/ws/rest/params/Tree.java @@ -1,6 +1,8 @@ package jalview.ws.rest.params; import jalview.datamodel.AlignmentI; +import jalview.ws.params.ArgumentI; +import jalview.ws.params.OptionI; import jalview.ws.rest.InputType; import jalview.ws.rest.RestJob; import jalview.ws.rest.RestServiceDescription; @@ -53,4 +55,10 @@ public class Tree extends InputType { return true; } + @Override + public List getOptions() + { + return getBaseOptions(); + } + } \ No newline at end of file