X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fws%2FMsaWSClient.java;h=94e19e794c1efd0d1f4a5d2fb29514a5f94d5d05;hb=c954e7c8d0953fee214bf897608410a1bc41ec13;hp=44ffa113e73171c3491e94b263663d64d07a9e36;hpb=895aec0787b4b2104c1a78d98fab530d586693ac;p=jalview.git diff --git a/src/jalview/ws/MsaWSClient.java b/src/jalview/ws/MsaWSClient.java index 44ffa11..94e19e7 100755 --- a/src/jalview/ws/MsaWSClient.java +++ b/src/jalview/ws/MsaWSClient.java @@ -1,233 +1,378 @@ +/* +* Jalview - A Sequence Alignment Editor and Viewer +* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ package jalview.ws; -import org.apache.axis.client.*; -import javax.xml.namespace.QName; -import java.util.*; +import ext.vamsas.*; + +import jalview.analysis.AlignSeq; + import jalview.datamodel.*; + import jalview.gui.*; -import javax.swing.*; -import java.util.*; -import java.awt.*; -import jalview.analysis.AlignSeq; -import ext.vamsas.*; + +import org.apache.axis.client.*; + import vamsas.objects.*; -public class MsaWSClient -{ - int jobsRunning = 0; - ext.vamsas.MuscleWS server; - WebserviceInfo wsInfo; - /** - * MsaWSClient - * - * @param msa SequenceI[] - */ - public MsaWSClient(SequenceI[] msa) - { - wsInfo = new jalview.gui.WebserviceInfo("Muscle Alignment job", - "Edgar, Robert C. (2004), MUSCLE: multiple sequence alignment with high accuracy and high throughput, Nucleic Acids Research 32(5), 1792-97."); +import java.awt.*; +import java.util.*; - wsInfo.setProgressText("Job details\n"); +import javax.swing.*; +import javax.xml.namespace.QName; - MuscleWSServiceLocator loc = new MuscleWSServiceLocator(); // Default - try { - this.server = (MuscleWS) loc.getMuscleWS(); // JBPNote will be set from properties - } - catch (Exception ex) { - wsInfo.setProgressText("Serious! MuscleWS Service location failed\nfor URL :" - +loc.getMuscleWSAddress()+"\n"+ex.getMessage()); - ex.printStackTrace(); - } - MsaWSThread musclethread = new MsaWSThread(msa); - wsInfo.setthisService(musclethread); - musclethread.start(); - } +public class MsaWSClient extends WSClient { + /** + * server is a WSDL2Java generated stub for an archetypal MsaWSI service. + */ + ext.vamsas.MuscleWS server; + public MsaWSClient(String MsaWSName, String altitle, SequenceI[] msa, + boolean submitGaps, boolean preserveOrder) { + if (setWebService(MsaWSName) == false) { + JOptionPane.showMessageDialog(Desktop.desktop, + "The Multiple Sequence Alignment Service named " + MsaWSName + + " is unknown", "Internal Jalview Error", + JOptionPane.WARNING_MESSAGE); - protected class MsaWSThread extends Thread implements WSClientI - { - String ServiceName = "MuscleWS"; - public boolean isCancellable() - { - return true; + return; + } + + wsInfo = new jalview.gui.WebserviceInfo(WebServiceJobTitle, + WebServiceReference); + + if (!locateWebService()) { + return; + } + + wsInfo.setProgressText(((submitGaps) ? "Re-alignment" : "Alignment") + + " of " + altitle + "\nJob details\n"); + + MsaWSThread musclethread = new MsaWSThread(WebServiceName + + " alignment of " + altitle, msa, submitGaps, preserveOrder); + wsInfo.setthisService(musclethread); + musclethread.start(); } - String OutputHeader; - vamsas.objects.simple.MsaResult result = null; - vamsas.objects.simple.SequenceSet seqs = new vamsas.objects.simple. - SequenceSet(); - String jobId; - int allowedServerExceptions = 3; // thread dies if too many exceptions. - MsaWSThread(SequenceI[] msa) - { - OutputHeader = wsInfo.getProgressText(); - vamsas.objects.simple.Sequence[] seqarray = new vamsas.objects.simple. - Sequence[msa.length]; - for (int i = 0; i < msa.length; i++) - { - seqarray[i] = new vamsas.objects.simple.Sequence(); - seqarray[i].setId(msa[i].getName()); - seqarray[i].setSeq(AlignSeq.extractGaps("-. ", msa[i].getSequence())); - } - this.seqs = new vamsas.objects.simple.SequenceSet(); - this.seqs.setSeqs(seqarray); + // JBPNote Nasty object-global state setting methods shouldn't be allowed + private boolean setWebService(String MsaWSName) { + if (MsaWServices.info.containsKey(MsaWSName)) { + WebServiceName = MsaWSName; + + String[] wsinfo = (String[]) MsaWServices.info.get(MsaWSName); + WsURL = wsinfo[0]; + WebServiceJobTitle = wsinfo[1]; + WebServiceReference = wsinfo[2]; + + return true; + } else { + return false; + } } - boolean jobComplete = false; + private boolean locateWebService() { + // TODO: MuscleWS transmuted to generic MsaWS client + MuscleWSServiceLocator loc = new MuscleWSServiceLocator(); // Default - public void cancelJob() { - if (!jobComplete) { - String cancelledMessage=""; try { - vamsas.objects.simple.WsJobId cancelledJob = server.cancel(jobId); - if (cancelledJob.getStatus() == 2) - { - // CANCELLED_JOB - cancelledMessage = "Job cancelled."; - jobComplete = true; - jobsRunning--; - result = null; - } - else - if (cancelledJob.getStatus() == 3) - { - // VALID UNSTOPPABLE JOB - cancelledMessage += - "Server cannot cancel this job. just close the window.\n"; - } - if (cancelledJob.getJobId() != null) - cancelledMessage += "[" + cancelledJob.getJobId() + "]"; - cancelledMessage +="\n"; - } catch (Exception exc) { - cancelledMessage +="\nProblems cancelling the job : Exception received...\n"+exc+"\n"; - exc.printStackTrace(); + this.server = (MuscleWS) loc.getMuscleWS(new java.net.URL(WsURL)); + ((MuscleWSSoapBindingStub) this.server).setTimeout(60000); // One minute timeout + } catch (Exception ex) { + wsInfo.setProgressText("Serious! " + WebServiceName + + " Service location failed\nfor URL :" + WsURL + "\n" + + ex.getMessage()); + wsInfo.setStatus(wsInfo.ERROR); + ex.printStackTrace(); + + return false; } - wsInfo.setProgressText(OutputHeader + cancelledMessage+"\n"); - } + + loc.getEngine().setOption("axis", "1"); + + return true; } - public void run() - { - - StartJob(); - - while (!jobComplete && (allowedServerExceptions > 0)) - { - try - { - result = server.getResult(jobId); - - if( result.isRunning() ) - wsInfo.setStatus(WebserviceInfo.STATE_RUNNING); - else if( result.isQueued() ) - wsInfo.setStatus(WebserviceInfo.STATE_QUEUING); - - if (result.isFinished()) - { - parseResult(); - jobComplete = true; - jobsRunning--; - } - else - { - wsInfo.setProgressText(OutputHeader + "\n" + result.getStatus()); - if (! (result.isJobFailed() || result.isServerError())) - { - Thread.sleep(5000); - // System.out.println("I'm alive "+seqid+" "+jobid); + protected class MsaWSThread extends Thread implements WSClientI { + String ServiceName = WebServiceName; + String OutputHeader; + vamsas.objects.simple.MsaResult result = null; + vamsas.objects.simple.SequenceSet seqs = new vamsas.objects.simple.SequenceSet(); + Hashtable SeqNames = null; + boolean submitGaps = false; // and always store and recover sequence order + boolean preserveOrder = true; // and always store and recover sequence order + String jobId; + String alTitle; // name which will be used to form new alignment window. + int allowedServerExceptions = 3; // thread dies if too many exceptions. + boolean jobComplete = false; + + MsaWSThread(String title, SequenceI[] msa, boolean subgaps, + boolean presorder) { + alTitle = title; + submitGaps = subgaps; + preserveOrder = presorder; + + OutputHeader = wsInfo.getProgressText(); + SeqNames = new Hashtable(); + + vamsas.objects.simple.Sequence[] seqarray = new vamsas.objects.simple.Sequence[msa.length]; + + for (int i = 0; i < msa.length; i++) { + String newname = jalview.analysis.SeqsetUtils.unique_name(i); + + // uniquify as we go + // TODO: JBPNote: this is a ubiquitous transformation - set of jalview seq objects to vamsas sequences with name preservation + SeqNames.put(newname, + jalview.analysis.SeqsetUtils.SeqCharacterHash(msa[i])); + seqarray[i] = new vamsas.objects.simple.Sequence(); + seqarray[i].setId(newname); + seqarray[i].setSeq((submitGaps) ? msa[i].getSequence() + : AlignSeq.extractGaps( + jalview.util.Comparison.GapChars, msa[i].getSequence())); } - } + + this.seqs = new vamsas.objects.simple.SequenceSet(); + this.seqs.setSeqs(seqarray); } - catch (Exception ex) - { - allowedServerExceptions--; - wsInfo.appendProgressText("\n"+ServiceName+" Server exception!\n" + ex.getMessage()); - ex.printStackTrace(); + + public boolean isCancellable() { + return true; } - } - if (! (result!=null && (result.isJobFailed() || result.isServerError()))) - wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_OK); - else - wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); - } + public void cancelJob() { + if ((jobId != null) && !jobId.equals("") && !jobComplete) { + String cancelledMessage = ""; - void StartJob() - { - try - { - vamsas.objects.simple.WsJobId jobsubmit = server.align(seqs); - if (jobsubmit.getStatus()==1) { - System.out.println(jobId=jobsubmit.getJobId()); - } else { - throw new Exception(jobsubmit.getJobId()); + try { + vamsas.objects.simple.WsJobId cancelledJob = server.cancel(jobId); + + if (cancelledJob.getStatus() == 2) { + // CANCELLED_JOB + cancelledMessage = "Job cancelled."; + wsInfo.setStatus(WebserviceInfo.STATE_CANCELLED_OK); + jobComplete = true; + jobsRunning--; + result = null; + } else if (cancelledJob.getStatus() == 3) { + // VALID UNSTOPPABLE JOB + cancelledMessage += "Server cannot cancel this job. just close the window.\n"; + } + + if (cancelledJob.getJobId() != null) { + cancelledMessage += ("[" + cancelledJob.getJobId() + + "]"); + } + + cancelledMessage += "\n"; + } catch (Exception exc) { + cancelledMessage += ("\nProblems cancelling the job : Exception received...\n" + + exc + "\n"); + exc.printStackTrace(); + } + + wsInfo.setProgressText(OutputHeader + cancelledMessage + "\n"); + } else { + if (!jobComplete) { + wsInfo.setProgressText(OutputHeader + + "Server cannot cancel this job because it has not been submitted properly. just close the window.\n"); + } + } } - } - catch (Exception e) - { - System.out.println(ServiceName + " Client: Failed to submit the prediction\n" + - e.toString() + "\n"); - e.printStackTrace(); - } - } - private void addFloatAnnotations(Alignment al, int[] gapmap, Vector values, String Symname, String Visname, float min, float max, int winLength) { + public void run() { + StartJob(); - Annotation[] annotations = new Annotation[al.getWidth()]; - for (int j = 0; j < values.size(); j++) - { - float value = Float.parseFloat(values.get(j).toString()); - annotations[gapmap[j]] = new Annotation("", value+"",' ',value); - } - al.addAnnotation(new AlignmentAnnotation(Symname, Visname, annotations, min, max, winLength)); - } - private jalview.datamodel.Sequence[] getVamsasAlignment(vamsas.objects.simple.Alignment valign) { - vamsas.objects.simple.Sequence[] seqs = valign.getSeqs().getSeqs(); - jalview.datamodel.Sequence[] msa = new jalview.datamodel.Sequence[seqs.length]; - for (int i=0, j=seqs.length; i 0)) { + try { + if ((result = server.getResult(jobId)) == null) { + throw (new Exception( + "Timed out when communicating with server\nTry again later.\n")); + } + + if (result.isRunning()) { + wsInfo.setStatus(WebserviceInfo.STATE_RUNNING); + } else if (result.isQueued()) { + wsInfo.setStatus(WebserviceInfo.STATE_QUEUING); + } + + if (result.isFinished()) { + parseResult(); + jobComplete = true; + jobsRunning--; + } else { + if (result.getStatus() != null) { + wsInfo.setProgressText(OutputHeader + "\n" + + result.getStatus()); + } + + if (!(result.isJobFailed() || result.isServerError())) { + Thread.sleep(5000); + + // System.out.println("I'm alive "+seqid+" "+jobid); + } else { + break; + } + } + } catch (Exception ex) { + allowedServerExceptions--; + wsInfo.appendProgressText("\n" + ServiceName + + " Server exception!\n" + ex.getMessage()); + System.err.println(ServiceName + " Server exception: " + + ex.getMessage()); + + // ex.printStackTrace(); JBPNote Debug + try { + if (allowedServerExceptions > 0) { + Thread.sleep(5000); + } + } catch (InterruptedException ex1) { + } + } + } + + if (allowedServerExceptions == 0) { + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR); + } else { + if (!((result != null) && + (result.isJobFailed() || result.isServerError()))) { + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_OK); + } else { + if (result.isFailed()) { + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); + } + + if (result.isServerError()) { + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR); + } + } + } } - if (result.getStatus()!=null) { - OutputHeader += "\n"+result.getStatus(); + + void StartJob() { + try { + vamsas.objects.simple.WsJobId jobsubmit = server.align(seqs); + + if ((jobsubmit != null) && (jobsubmit.getStatus() == 1)) { + jobId = jobsubmit.getJobId(); + System.out.println(WsURL + " Job Id '" + jobId + "'"); + } else { + if (jobsubmit == null) { + throw new Exception("Server at " + WsURL + + " returned null object, it probably cannot be contacted. Try again later ?"); + } + + throw new Exception(jobsubmit.getJobId()); + } + } catch (Exception e) { + // TODO: JBPNote catch timeout or other fault types explicitly + // For unexpected errors + System.err.println(WebServiceName + + "Client: Failed to submit the sequences for alignment (probably a server side problem)\n" + + "When contacting Server:"+WsURL + "\n" + e.toString() + "\n"); + this.allowedServerExceptions = 0; + wsInfo.setStatus(wsInfo.STATE_STOPPED_SERVERERROR); + wsInfo.appendProgressText("Failed to submit sequences for alignment.\n" + + "It is most likely that there is a problem with the server.\n" + + "Just close the window\n"); + + // e.printStackTrace(); // TODO: JBPNote DEBUG + } } - if (result.getMsa()!=null) { - OutputHeader += "\nAlignment Object Method Notes\n"; - String lines[] = result.getMsa().getMethod(); - for (int line=0;line