From 231cba7c0cb9097957cd61ef96aab8e32e2d0337 Mon Sep 17 00:00:00 2001 From: jprocter Date: Tue, 23 Aug 2011 13:28:20 +0100 Subject: [PATCH] JAL-715 - allow rest service attributes to be exported and imported as a | separated string --- src/jalview/ws/rest/InputType.java | 69 ++++++++++ src/jalview/ws/rest/params/Alignment.java | 142 +++++++++++++++++--- src/jalview/ws/rest/params/AnnotationFile.java | 43 +++++- src/jalview/ws/rest/params/JobConstant.java | 41 ++++++ .../ws/rest/params/SeqGroupIndexVector.java | 64 ++++++++- src/jalview/ws/rest/params/SeqIdVector.java | 48 ++++++- src/jalview/ws/rest/params/SeqVector.java | 49 ++++++- src/jalview/ws/rest/params/Tree.java | 25 +++- 8 files changed, 454 insertions(+), 27 deletions(-) diff --git a/src/jalview/ws/rest/InputType.java b/src/jalview/ws/rest/InputType.java index 9a4f297..28bfda0 100644 --- a/src/jalview/ws/rest/InputType.java +++ b/src/jalview/ws/rest/InputType.java @@ -8,6 +8,9 @@ import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.StringBody; @@ -100,4 +103,70 @@ public abstract class InputType { { return (inputData==null || inputData.size()==0); } + /** + * return a url encoded version of this parameter's value, or an empty string if the parameter has no ='value' content. + * @return + */ + public abstract List getURLEncodedParameter(); + + /** + * set the property known as tok, possibly by assigning it with a given val + * @param tok + * @param val (may be empty or null) + * @param warnings place where parse warnings are reported + * @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 + */ + public abstract String getURLtokenPrefix(); + /** + * parse the given token String and set InputParameter properties appropriately + * @param tokenstring - urlencoded parameter string as returned from getURLEncodedParameter + * @param warnings - place where any warning messages about bad property values are written + * @return true if configuration succeeded, false otherwise. + */ + public boolean configureFromURLtokenString(List tokenstring, StringBuffer warnings) { + boolean valid=true; + for (String tok:tokenstring) + { + Matcher mtch = Pattern.compile("^([^=]+)=?'?([^']*)?'?").matcher(tok); + if (mtch.find()) { + try { + if (mtch.group(1).equals("min")) + { + min = Integer.parseInt(mtch.group(2)); + continue; + + } else + if (mtch.group(1).equals("max")) + { + max = Integer.parseInt(mtch.group(2)); + continue; + } + } + catch (NumberFormatException x) + { + valid=false; + 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); + } + } + return valid; + } + public void addBaseParams(ArrayList prms) + { + // todo : check if replaceids should be a global for the service, rather than for a specific parameter. + if (min!=1) { + prms.add("min='"+min+"'"); + } + if (max!=0) { + prms.add("min='"+max+"'"); + } + } } \ No newline at end of file diff --git a/src/jalview/ws/rest/params/Alignment.java b/src/jalview/ws/rest/params/Alignment.java index 0027057..770b564 100644 --- a/src/jalview/ws/rest/params/Alignment.java +++ b/src/jalview/ws/rest/params/Alignment.java @@ -5,6 +5,7 @@ import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; import jalview.ws.rest.InputType.molType; +import jalview.ws.rest.RestServiceDescription; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; @@ -16,6 +17,8 @@ import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.FileBody; @@ -23,46 +26,143 @@ import org.apache.http.entity.mime.content.StringBody; /** * format an alignment for input to rest service. + * * @author JimP - * + * */ -public class Alignment extends InputType { +public class Alignment extends InputType +{ public Alignment() { - super(new Class[] { AlignmentI.class} ); + super(new Class[] + { AlignmentI.class }); } - String format="FASTA"; + String format = "FASTA"; + molType type; - boolean jvsuffix=false; + + boolean jvsuffix = false; + /** * input data as a file upload rather than inline content */ public boolean writeAsFile; + @Override - public ContentBody formatForInput(RestJob rj) throws UnsupportedEncodingException, NoValidInputDataException + public ContentBody formatForInput(RestJob rj) + throws UnsupportedEncodingException, NoValidInputDataException { - AlignmentI alignment = rj.getAlignmentForInput(token,type); + AlignmentI alignment = rj.getAlignmentForInput(token, type); if (writeAsFile) { - try { - File fa = File.createTempFile("jvmime", ".fa"); - PrintWriter pw = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(fa)), "UTF-8")); - pw.append(new jalview.io.FormatAdapter().formatSequences(format, alignment, jvsuffix)); - pw.close(); - return new FileBody(fa, "text/plain"); - } catch (Exception ex) - { - throw new NoValidInputDataException("Couldn't write out alignment to file.",ex); + try + { + File fa = File.createTempFile("jvmime", ".fa"); + PrintWriter pw = new PrintWriter( + new OutputStreamWriter(new BufferedOutputStream( + new FileOutputStream(fa)), "UTF-8")); + pw.append(new jalview.io.FormatAdapter().formatSequences(format, + alignment, jvsuffix)); + pw.close(); + return new FileBody(fa, "text/plain"); + } catch (Exception ex) + { + throw new NoValidInputDataException( + "Couldn't write out alignment to file.", ex); + } } - } else { + else + { jalview.io.FormatAdapter fa = new jalview.io.FormatAdapter(); fa.setNewlineString("\r\n"); - return new StringBody((fa.formatSequences(format, alignment, jvsuffix))); - //, - //"text/plain",Charset.forName("UTF-8")); + return new StringBody( + (fa.formatSequences(format, alignment, jvsuffix))); + // , + // "text/plain",Charset.forName("UTF-8")); // , "text/plain", Charset.forName("UTF-8")); - // sb.getContentTypeParameters().put("filename", "alignment.fa"); + // sb.getContentTypeParameters().put("filename", "alignment.fa"); + } + } + + @Override + public List getURLEncodedParameter() + { + ArrayList prms = new ArrayList(); + prms.add("format='" + format + "'"); + if (type != null) + { + prms.add("type='" + type.toString() + "'"); + } + if (jvsuffix) + { + prms.add("jvsuffix"); + } + ; + if (writeAsFile) + { + prms.add("writeasfile"); + } + ; + return prms; + } + + @Override + public String getURLtokenPrefix() + { + return "ALIGNMENT"; + } + + @Override + public boolean configureProperty(String tok, String val, + StringBuffer warnings) + { + if (tok.startsWith("jvsuffix")) + { + jvsuffix = true; + return true; + } + if (tok.startsWith("writeasfile")) + { + writeAsFile = true; + return true; + } + + if (tok.startsWith("format")) + { + for (String fmt : jalview.io.FormatAdapter.WRITEABLE_FORMATS) + { + if (val.equalsIgnoreCase(fmt)) + { + format = fmt; + return true; + } + } + warnings.append("Invalid alignment format '" + val + + "'. Must be one of ("); + for (String fmt : jalview.io.FormatAdapter.WRITEABLE_FORMATS) + { + warnings.append(" " + fmt); + } + warnings.append(")\n"); + } + if (tok.startsWith("type")) + { + 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(" " + v); + } + warnings.append(")\n"); + } } + return false; } } \ 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 84dcfb9..5abf0fc 100644 --- a/src/jalview/ws/rest/params/AnnotationFile.java +++ b/src/jalview/ws/rest/params/AnnotationFile.java @@ -4,9 +4,12 @@ import jalview.datamodel.AlignmentI; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; +import jalview.ws.rest.RestServiceDescription; import jalview.ws.rest.InputType.molType; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.StringBody; @@ -49,4 +52,42 @@ public class AnnotationFile extends InputType { return new StringBody(new jalview.io.AnnotationFile().printCSVAnnotations(al.getAlignmentAnnotation())); } } -} \ No newline at end of file + @Override + public List getURLEncodedParameter() + { + ArrayList prms = new ArrayList(); + super.addBaseParams(prms); + prms.add("format='"+format+"'"); + return prms; + } + @Override + public String getURLtokenPrefix() + { + return "ALANNOTATION"; + } + @Override + public boolean configureProperty(String tok, String val, + StringBuffer warnings) + { + + if (tok.startsWith("format")) + { + for (String fmt : new String[] { CSVANNOT, JVANNOT}) + { + if (val.equalsIgnoreCase(fmt)) + { + format = fmt; + return true; + } + } + warnings.append("Invalid annotation file format '" + val + + "'. Must be one of ("); + for (String fmt : new String[] { CSVANNOT, JVANNOT}) + { + warnings.append(" " + fmt); + } + warnings.append(")\n"); + } + return false; + } +} diff --git a/src/jalview/ws/rest/params/JobConstant.java b/src/jalview/ws/rest/params/JobConstant.java index 1ff6964..01b54cb 100644 --- a/src/jalview/ws/rest/params/JobConstant.java +++ b/src/jalview/ws/rest/params/JobConstant.java @@ -5,6 +5,8 @@ import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.StringBody; @@ -39,4 +41,43 @@ public class JobConstant extends InputType return new StringBody(value); } + @Override + public List getURLEncodedParameter() + { + ArrayList prm = new ArrayList(); + + if (value!=null && value.length()>0) + { + prm.add(value); + } + return prm; + } + + @Override + public String getURLtokenPrefix() + { + return ""; + } + + @Override + public boolean configureFromURLtokenString(List tokenstring, + StringBuffer warnings) + { + if (tokenstring.size()>1) { + warnings.append("IMPLEMENTATION ERROR: Constant POST parameters cannot have more than one value."); + return false; + } + if (tokenstring.size()==1) { + value = tokenstring.get(0); + } + return true; + } + + @Override + public boolean configureProperty(String tok, String val, + StringBuffer warnings) + { + warnings.append("IMPLEMENTATION ERROR: No Properties to configure for a Constant parameter."); + return false; + } } diff --git a/src/jalview/ws/rest/params/SeqGroupIndexVector.java b/src/jalview/ws/rest/params/SeqGroupIndexVector.java index 91b1fff..7df7d1c 100644 --- a/src/jalview/ws/rest/params/SeqGroupIndexVector.java +++ b/src/jalview/ws/rest/params/SeqGroupIndexVector.java @@ -7,10 +7,12 @@ import jalview.ws.rest.AlignmentProcessor; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; +import jalview.ws.rest.RestServiceDescription; import jalview.ws.rest.InputType.molType; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.List; import java.util.Vector; import org.apache.http.entity.mime.content.ContentBody; @@ -170,4 +172,64 @@ public class SeqGroupIndexVector extends InputType implements minsize=1; } } -} \ No newline at end of file + @Override + public List getURLEncodedParameter() + { + ArrayList prms = new ArrayList(); + super.addBaseParams(prms); + prms.add("minsize='"+ minsize+"'"); + prms.add("sep='"+ sep+"'"); + if (type!=null) + { + prms.add("type='"+type+"'"); + } + return prms; + } + + @Override + public String getURLtokenPrefix() + { + return "PARTITION"; + } + + @Override + public boolean configureProperty(String tok, String val, + StringBuffer warnings) + { + + if (tok.startsWith("sep")) + { + sep=val; + return true; + } + if (tok.startsWith("minsize")) + { + 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"); + } + if (tok.startsWith("type")) + { + 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(" "+v); + } + warnings.append(")\n"); + } + } + return false; + } + +} diff --git a/src/jalview/ws/rest/params/SeqIdVector.java b/src/jalview/ws/rest/params/SeqIdVector.java index 9bdaed1..5f7c551 100644 --- a/src/jalview/ws/rest/params/SeqIdVector.java +++ b/src/jalview/ws/rest/params/SeqIdVector.java @@ -5,9 +5,14 @@ import jalview.datamodel.SequenceI; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; +import jalview.ws.rest.RestServiceDescription; import jalview.ws.rest.InputType.molType; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.StringBody; @@ -17,7 +22,7 @@ import org.apache.http.entity.mime.content.StringBody; * @author JimP * */ -class SeqIdVector extends InputType { +public class SeqIdVector extends InputType { public SeqIdVector() { super(new Class[] { AlignmentI.class} ); @@ -42,5 +47,44 @@ 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+"'"); + return prms; + } + @Override + public String getURLtokenPrefix() + { + return "SEQIDS"; + } + @Override + public boolean configureProperty(String tok, String val, StringBuffer warnings) + { + if (tok.startsWith("sep")) + { + sep=val; + return true; + } + if (tok.startsWith("type")) + { + 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(" "+v); + } + warnings.append(")\n"); + } + } + return false; } -} \ No newline at end of file +} diff --git a/src/jalview/ws/rest/params/SeqVector.java b/src/jalview/ws/rest/params/SeqVector.java index 9a98f3e..3a5b414 100644 --- a/src/jalview/ws/rest/params/SeqVector.java +++ b/src/jalview/ws/rest/params/SeqVector.java @@ -5,9 +5,12 @@ import jalview.datamodel.SequenceI; import jalview.ws.rest.InputType; import jalview.ws.rest.NoValidInputDataException; import jalview.ws.rest.RestJob; +import jalview.ws.rest.RestServiceDescription; import jalview.ws.rest.InputType.molType; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.StringBody; @@ -17,7 +20,7 @@ import org.apache.http.entity.mime.content.StringBody; * @author JimP * */ -class SeqVector extends InputType { +public class SeqVector extends InputType { String sep; molType type; public SeqVector() @@ -40,4 +43,48 @@ class SeqVector extends InputType { } return new StringBody(idvector.toString()); } + @Override + public List getURLEncodedParameter() + { + ArrayList prms = new ArrayList(); + super.addBaseParams(prms); + prms.add("sep='"+ sep+"'"); + prms.add("type='"+type+"'"); + return prms; + } + + @Override + public String getURLtokenPrefix() + { + return "SEQS"; + } + + @Override + public boolean configureProperty(String tok, String val, + StringBuffer warnings) + { + + if (tok.startsWith("sep")) + { + sep=val; + return true; + } + if (tok.startsWith("type")) + { + 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(" "+v); + } + warnings.append(")\n"); + } + } + return false; + } + } \ 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 91fab40..69d2f58 100644 --- a/src/jalview/ws/rest/params/Tree.java +++ b/src/jalview/ws/rest/params/Tree.java @@ -3,8 +3,12 @@ package jalview.ws.rest.params; import jalview.datamodel.AlignmentI; import jalview.ws.rest.InputType; import jalview.ws.rest.RestJob; +import jalview.ws.rest.RestServiceDescription; +import jalview.ws.rest.InputType.molType; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; import org.apache.http.entity.mime.content.ContentBody; @@ -13,7 +17,7 @@ import org.apache.http.entity.mime.content.ContentBody; * @author JimP * */ -class Tree extends InputType { +public class Tree extends InputType { public Tree() { super(new Class[] { jalview.analysis.NJTree.class} ); @@ -29,5 +33,24 @@ class Tree extends InputType { throw new Error("Tree InputType not yet implemented"); //return null; } + public String getURLtokenPrefix() + { + return "NEWICK"; + } + @Override + public List getURLEncodedParameter() + { + ArrayList prms = new ArrayList(); + super.addBaseParams(prms); + return prms; + } + + @Override + public boolean configureProperty(String tok, String val, + StringBuffer warnings) + { + return true; + } + } \ No newline at end of file -- 1.7.10.2