From add30afdc46a14e61ccf55881fa91b9ca9abfe80 Mon Sep 17 00:00:00 2001 From: jprocter Date: Mon, 17 May 2010 16:12:18 +0000 Subject: [PATCH] refactored old jalview service code to its own package. --- src/jalview/ws/AWSThread.java | 1 + src/jalview/ws/{ => jws1}/Discoverer.java | 3 +- src/jalview/ws/{ => jws1}/JPredClient.java | 6 +- src/jalview/ws/{ => jws1}/JPredThread.java | 1331 ++++++++++---------- src/jalview/ws/{ => jws1}/JWS1Thread.java | 3 +- src/jalview/ws/{ => jws1}/MsaWSClient.java | 6 +- src/jalview/ws/{ => jws1}/MsaWSThread.java | 1427 +++++++++++----------- src/jalview/ws/{ => jws1}/SeqSearchWSClient.java | 630 +++++----- src/jalview/ws/{ => jws1}/SeqSearchWSThread.java | 1359 ++++++++++---------- src/jalview/ws/{ => jws1}/WS1Client.java | 4 +- src/jalview/ws/{ => jws1}/WSJob.java | 4 +- 11 files changed, 2395 insertions(+), 2379 deletions(-) rename src/jalview/ws/{ => jws1}/Discoverer.java (99%) mode change 100755 => 100644 rename src/jalview/ws/{ => jws1}/JPredClient.java (98%) mode change 100755 => 100644 rename src/jalview/ws/{ => jws1}/JPredThread.java (92%) rename src/jalview/ws/{ => jws1}/JWS1Thread.java (96%) rename src/jalview/ws/{ => jws1}/MsaWSClient.java (97%) mode change 100755 => 100644 rename src/jalview/ws/{ => jws1}/MsaWSThread.java (92%) rename src/jalview/ws/{ => jws1}/SeqSearchWSClient.java (94%) rename src/jalview/ws/{ => jws1}/SeqSearchWSThread.java (92%) rename src/jalview/ws/{ => jws1}/WS1Client.java (96%) rename src/jalview/ws/{ => jws1}/WSJob.java (97%) diff --git a/src/jalview/ws/AWSThread.java b/src/jalview/ws/AWSThread.java index 8d9dce5..4f60480 100644 --- a/src/jalview/ws/AWSThread.java +++ b/src/jalview/ws/AWSThread.java @@ -98,6 +98,7 @@ public abstract class AWSThread extends Thread // always output the exception's stack trace to the log Cache.log.warn(WebServiceName + " job(" + jobs[j].jobnum + ") Server exception."); + // todo: could limit trace to cause if this is a SOAPFaultException. ex.printStackTrace(); if (jobs[j].allowedServerExceptions > 0) diff --git a/src/jalview/ws/Discoverer.java b/src/jalview/ws/jws1/Discoverer.java old mode 100755 new mode 100644 similarity index 99% rename from src/jalview/ws/Discoverer.java rename to src/jalview/ws/jws1/Discoverer.java index 5d20dd4..90581dc --- a/src/jalview/ws/Discoverer.java +++ b/src/jalview/ws/jws1/Discoverer.java @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License along with Jalview. If not, see . */ -package jalview.ws; +package jalview.ws.jws1; /** *

@@ -37,6 +37,7 @@ package jalview.ws; * @author not attributable * @version 1.0 */ + import java.util.*; import javax.swing.*; diff --git a/src/jalview/ws/JPredClient.java b/src/jalview/ws/jws1/JPredClient.java old mode 100755 new mode 100644 similarity index 98% rename from src/jalview/ws/JPredClient.java rename to src/jalview/ws/jws1/JPredClient.java index 23f4de6..eab47d7 --- a/src/jalview/ws/JPredClient.java +++ b/src/jalview/ws/jws1/JPredClient.java @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License along with Jalview. If not, see . */ -package jalview.ws; +package jalview.ws.jws1; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -371,7 +371,7 @@ public class JPredClient extends WS1Client if (msa.getSequences().length == 1) { // Single Sequence prediction - new jalview.ws.JPredClient(sh, af.getTitle(), false, msa, af, + new jalview.ws.jws1.JPredClient(sh, af.getTitle(), false, msa, af, true); } else @@ -379,7 +379,7 @@ public class JPredClient extends WS1Client if (msa.getSequences().length > 1) { // Sequence profile based prediction - new jalview.ws.JPredClient(sh, af.getTitle(), true, msa, af, + new jalview.ws.jws1.JPredClient(sh, af.getTitle(), true, msa, af, true); } } diff --git a/src/jalview/ws/JPredThread.java b/src/jalview/ws/jws1/JPredThread.java similarity index 92% rename from src/jalview/ws/JPredThread.java rename to src/jalview/ws/jws1/JPredThread.java index 3589c16..a0036fe 100644 --- a/src/jalview/ws/JPredThread.java +++ b/src/jalview/ws/jws1/JPredThread.java @@ -1,664 +1,667 @@ -/* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5) - * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle - * - * This file is part of Jalview. - * - * Jalview 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 3 of the License, or (at your option) any later version. - * - * Jalview 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 Jalview. If not, see . - */ -package jalview.ws; - -import java.util.*; - -import jalview.analysis.*; -import jalview.bin.*; -import jalview.datamodel.*; -import jalview.gui.*; -import jalview.io.*; -import jalview.util.*; -import vamsas.objects.simple.JpredResult; - -class JPredThread extends JWS1Thread implements WSClientI -{ - // TODO: put mapping between JPredJob input and input data here - - // JNetAnnotation adding is done after result parsing. - class JPredJob extends WSJob - { - // TODO: make JPredJob deal only with what was sent to and received from a - // JNet service - int[] predMap = null; // mapping from sequence(i) to the original - - // sequence(predMap[i]) being predicted on - - vamsas.objects.simple.Sequence sequence; - - vamsas.objects.simple.Msfalignment msa; - - java.util.Hashtable SequenceInfo = null; - - int msaIndex = 0; // the position of the original sequence in the array of - - // Sequences in the input object that this job holds a - // prediction for - - /** - * - * @return true if getResultSet will return a valid alignment and prediction - * result. - */ - public boolean hasResults() - { - if (subjobComplete && result != null && result.isFinished() - && ((JpredResult) result).getPredfile() != null - && ((JpredResult) result).getAligfile() != null) - { - return true; - } - return false; - } - - public boolean hasValidInput() - { - if (sequence != null) - { - return true; - } - return false; - } - - /** - * - * @return null or Object[] { annotated alignment for this prediction, - * ColumnSelection for this prediction} or null if no results - * available. - * @throws Exception - */ - public Object[] getResultSet() throws Exception - { - if (result == null || !result.isFinished()) - { - return null; - } - Alignment al = null; - ColumnSelection alcsel = null; - int FirstSeq = -1; // the position of the query sequence in Alignment al - - JpredResult result = (JpredResult) this.result; - - jalview.bin.Cache.log.debug("Parsing output from JNet job."); - // JPredFile prediction = new JPredFile("C:/JalviewX/files/jpred.txt", - // "File"); - jalview.io.JPredFile prediction = new jalview.io.JPredFile(result - .getPredfile(), "Paste"); - SequenceI[] preds = prediction.getSeqsAsArray(); - jalview.bin.Cache.log.debug("Got prediction profile."); - - if ((this.msa != null) && (result.getAligfile() != null)) - { - jalview.bin.Cache.log.debug("Getting associated alignment."); - // we ignore the returned alignment if we only predicted on a single - // sequence - String format = new jalview.io.IdentifyFile().Identify(result - .getAligfile(), "Paste"); - - if (jalview.io.FormatAdapter.isValidFormat(format)) - { - SequenceI sqs[]; - if (predMap != null) - { - Object[] alandcolsel = input - .getAlignmentAndColumnSelection(getGapChar()); - sqs = (SequenceI[]) alandcolsel[0]; - al = new Alignment(sqs); - alcsel = (ColumnSelection) alandcolsel[1]; - } - else - { - al = new FormatAdapter().readFile(result.getAligfile(), - "Paste", format); - sqs = new SequenceI[al.getHeight()]; - - for (int i = 0, j = al.getHeight(); i < j; i++) - { - sqs[i] = al.getSequenceAt(i); - } - if (!jalview.analysis.SeqsetUtils.deuniquify( - (Hashtable) SequenceInfo, sqs)) - { - throw (new Exception( - "Couldn't recover sequence properties for alignment.")); - } - } - FirstSeq = 0; - al.setDataset(null); - - jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, - FirstSeq, false, predMap); - - } - else - { - throw (new Exception("Unknown format " + format - + " for file : \n" + result.getAligfile())); - } - } - else - { - al = new Alignment(preds); - FirstSeq = prediction.getQuerySeqPosition(); - if (predMap != null) - { - char gc = getGapChar(); - SequenceI[] sqs = (SequenceI[]) ((java.lang.Object[]) input - .getAlignmentAndColumnSelection(gc))[0]; - if (this.msaIndex >= sqs.length) - { - throw new Error( - "Implementation Error! Invalid msaIndex for JPredJob on parent MSA input object!"); - } - - // /// - // Uses RemoveGapsCommand - // /// - new jalview.commands.RemoveGapsCommand("Remove Gaps", - new SequenceI[] - { sqs[msaIndex] }, currentView); - - SequenceI profileseq = al.getSequenceAt(FirstSeq); - profileseq.setSequence(sqs[msaIndex].getSequenceAsString()); - } - - if (!jalview.analysis.SeqsetUtils.SeqCharacterUnhash(al - .getSequenceAt(FirstSeq), SequenceInfo)) - { - throw (new Exception( - "Couldn't recover sequence properties for JNet Query sequence!")); - } - else - { - al.setDataset(null); - jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, - FirstSeq, true, predMap); - SequenceI profileseq = al.getSequenceAt(0); // this includes any gaps. - alignToProfileSeq(al, profileseq); - if (predMap != null) - { - // Adjust input view for gaps - // propagate insertions into profile - alcsel = propagateInsertions(profileseq, al, input); - } - } - } - return new Object[] - { al, alcsel }; // , FirstSeq, noMsa}; - } - - /** - * Given an alignment where all other sequences except profileseq are - * aligned to the ungapped profileseq, insert gaps in the other sequences to - * realign them with the residues in profileseq - * - * @param al - * @param profileseq - */ - private void alignToProfileSeq(Alignment al, SequenceI profileseq) - { - char gc = al.getGapCharacter(); - int[] gapMap = profileseq.gapMap(); - // insert gaps into profile - for (int lp = 0, r = 0; r < gapMap.length; r++) - { - if (gapMap[r] - lp > 1) - { - StringBuffer sb = new StringBuffer(); - for (int s = 0, ns = gapMap[r] - lp; s < ns; s++) - { - sb.append(gc); - } - for (int s = 1, ns = al.getHeight(); s < ns; s++) - { - String sq = al.getSequenceAt(s).getSequenceAsString(); - int diff = gapMap[r] - sq.length(); - if (diff > 0) - { - // pad gaps - sq = sq + sb; - while ((diff = gapMap[r] - sq.length()) > 0) - { - sq = sq - + ((diff >= sb.length()) ? sb.toString() : sb - .substring(0, diff)); - } - al.getSequenceAt(s).setSequence(sq); - } - else - { - al.getSequenceAt(s).setSequence( - sq.substring(0, gapMap[r]) + sb.toString() - + sq.substring(gapMap[r])); - } - } - } - lp = gapMap[r]; - } - } - - /** - * Add gaps into the sequences aligned to profileseq under the given - * AlignmentView - * - * @param profileseq - * @param al - * @param input - */ - private ColumnSelection propagateInsertions(SequenceI profileseq, - Alignment al, AlignmentView input) - { - char gc = al.getGapCharacter(); - Object[] alandcolsel = input.getAlignmentAndColumnSelection(gc); - ColumnSelection nview = (ColumnSelection) alandcolsel[1]; - SequenceI origseq; - nview.pruneDeletions(ShiftList - .parseMap((origseq = ((SequenceI[]) alandcolsel[0])[0]) - .gapMap())); // recover original prediction sequence's - // mapping to view. - int[] viscontigs = nview.getVisibleContigs(0, profileseq.getLength()); - int spos = 0; - int offset = 0; - // input.pruneDeletions(ShiftList.parseMap(((SequenceI[]) - // alandcolsel[0])[0].gapMap())) - // add profile to visible contigs - for (int v = 0; v < viscontigs.length; v += 2) - { - if (viscontigs[v] > spos) - { - StringBuffer sb = new StringBuffer(); - for (int s = 0, ns = viscontigs[v] - spos; s < ns; s++) - { - sb.append(gc); - } - for (int s = 0, ns = al.getHeight(); s < ns; s++) - { - SequenceI sqobj = al.getSequenceAt(s); - if (sqobj != profileseq) - { - String sq = al.getSequenceAt(s).getSequenceAsString(); - if (sq.length() <= spos + offset) - { - // pad sequence - int diff = spos + offset - sq.length() - 1; - if (diff > 0) - { - // pad gaps - sq = sq + sb; - while ((diff = spos + offset - sq.length() - 1) > 0) - { - sq = sq - + ((diff >= sb.length()) ? sb.toString() : sb - .substring(0, diff)); - } - } - sq += sb.toString(); - } - else - { - al.getSequenceAt(s).setSequence( - sq.substring(0, spos + offset) + sb.toString() - + sq.substring(spos + offset)); - } - } - } - // offset+=sb.length(); - } - spos = viscontigs[v + 1] + 1; - } - if ((offset + spos) < profileseq.getLength()) - { - StringBuffer sb = new StringBuffer(); - for (int s = 0, ns = profileseq.getLength() - spos - offset; s < ns; s++) - { - sb.append(gc); - } - for (int s = 1, ns = al.getHeight(); s < ns; s++) - { - String sq = al.getSequenceAt(s).getSequenceAsString(); - // pad sequence - int diff = origseq.getLength() - sq.length(); - while (diff > 0) - { - sq = sq - + ((diff >= sb.length()) ? sb.toString() : sb - .substring(0, diff)); - diff = origseq.getLength() - sq.length(); - } - } - } - return nview; - } - - public JPredJob(Hashtable SequenceInfo, SequenceI seq, int[] delMap) - { - super(); - this.predMap = delMap; - String sq = AlignSeq.extractGaps(Comparison.GapChars, seq - .getSequenceAsString()); - if (sq.length() >= 20) - { - this.SequenceInfo = SequenceInfo; - sequence = new vamsas.objects.simple.Sequence(); - sequence.setId(seq.getName()); - sequence.setSeq(sq); - } - } - - public JPredJob(Hashtable SequenceInfo, SequenceI[] msf, int[] delMap) - { - this(SequenceInfo, msf[0], delMap); - if (sequence != null) - { - if (msf.length > 1) - { - msa = new vamsas.objects.simple.Msfalignment(); - jalview.io.PileUpfile pileup = new jalview.io.PileUpfile(); - msa.setMsf(pileup.print(msf)); - } - } - } - } - - ext.vamsas.Jpred server; - - String altitle = ""; - - JPredThread(WebserviceInfo wsinfo, String altitle, - ext.vamsas.Jpred server, String wsurl, AlignmentView alview, - AlignFrame alframe) - { - super(alframe, wsinfo, alview, wsurl); - this.altitle = altitle; - this.server = server; - } - - JPredThread(WebserviceInfo wsinfo, String altitle, - ext.vamsas.Jpred server, String wsurl, Hashtable SequenceInfo, - SequenceI seq, int[] delMap, AlignmentView alview, - AlignFrame alframe) - { - this(wsinfo, altitle, server, wsurl, alview, alframe); - JPredJob job = new JPredJob(SequenceInfo, seq, delMap); - if (job.hasValidInput()) - { - OutputHeader = wsInfo.getProgressText(); - jobs = new WSJob[] - { job }; - job.jobnum = 0; - } - } - - JPredThread(WebserviceInfo wsinfo, String altitle, - ext.vamsas.Jpred server, Hashtable SequenceInfo, SequenceI[] msf, - int[] delMap, AlignmentView alview, AlignFrame alframe, - String wsurl) - { - this(wsinfo, altitle, server, wsurl, alview, alframe); - JPredJob job = new JPredJob(SequenceInfo, msf, delMap); - if (job.hasValidInput()) - { - jobs = new WSJob[] - { job }; - OutputHeader = wsInfo.getProgressText(); - job.jobnum = 0; - } - } - - public void StartJob(AWsJob j) - { - if (!(j instanceof JPredJob)) - { - throw new Error( - "Implementation error - StartJob(JpredJob) called on " - + j.getClass()); - } - try - { - JPredJob job = (JPredJob) j; - if (job.msa != null) - { - job.jobId = server.predictOnMsa(job.msa); - } - else if (job.sequence != null) - { - job.jobId = server.predict(job.sequence); // debug like : job.jobId = - // "/jobs/www-jpred/jp_Yatat29";// - } - - if (job.jobId != null) - { - if (job.jobId.startsWith("Broken")) - { - job.result = (vamsas.objects.simple.Result) new JpredResult(); - job.result.setInvalid(true); - job.result.setStatus("Submission " + job.jobId); - throw new Exception(job.jobId); - } - else - { - job.submitted = true; - job.subjobComplete = false; - Cache.log.info(WsUrl + " Job Id '" + job.jobId + "'"); - } - } - else - { - throw new Exception("Server timed out - try again later\n"); - } - } catch (Exception e) - { - // kill the whole job. - wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR); - if (e.getMessage().indexOf("Exception") > -1) - { - wsInfo - .setStatus(j.jobnum, - WebserviceInfo.STATE_STOPPED_SERVERERROR); - wsInfo - .setProgressText( - j.jobnum, - "Failed to submit the prediction. (Just close the window)\n" - + "It is most likely that there is a problem with the server.\n"); - System.err - .println("JPredWS Client: Failed to submit the prediction. Quite possibly because of a server error - see below)\n" - + e.getMessage() + "\n"); - - jalview.bin.Cache.log.warn("Server Exception", e); - } - else - { - wsInfo.setStatus(j.jobnum, WebserviceInfo.STATE_STOPPED_ERROR); - // JBPNote - this could be a popup informing the user of the problem. - wsInfo.appendProgressText(j.jobnum, - "Failed to submit the prediction:\n" + e.getMessage() - + wsInfo.getProgressText()); - - jalview.bin.Cache.log.debug("Failed Submission of job " + j.jobnum, - e); - - } - j.allowedServerExceptions = -1; - j.subjobComplete = true; - } - } - - public void parseResult() - { - int results = 0; // number of result sets received - JobStateSummary finalState = new JobStateSummary(); - try - { - for (int j = 0; j < jobs.length; j++) - { - finalState.updateJobPanelState(wsInfo, OutputHeader, jobs[j]); - if (jobs[j].submitted && jobs[j].subjobComplete - && jobs[j].hasResults()) - { - results++; - } - } - } catch (Exception ex) - { - - Cache.log.error("Unexpected exception when processing results for " - + altitle, ex); - wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); - } - if (results > 0) - { - wsInfo.showResultsNewFrame - .addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(java.awt.event.ActionEvent evt) - { - displayResults(true); - } - }); - wsInfo.mergeResults - .addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(java.awt.event.ActionEvent evt) - { - displayResults(false); - } - }); - wsInfo.setResultsReady(); - } - else - { - wsInfo.setFinishedNoResults(); - } - } - - void displayResults(boolean newWindow) - { - // TODO: cope with multiple subjobs. - if (jobs != null) - { - Object[] res = null; - boolean msa = false; - for (int jn = 0; jn < jobs.length; jn++) - { - Object[] jobres = null; - JPredJob j = (JPredJob) jobs[jn]; - - if (j.hasResults()) - { - // hack - we only deal with all single seuqence predictions or all - // profile predictions - msa = (j.msa != null) ? true : msa; - try - { - jalview.bin.Cache.log.debug("Parsing output of job " + jn); - jobres = j.getResultSet(); - jalview.bin.Cache.log.debug("Finished parsing output."); - if (jobs.length == 1) - { - res = jobres; - } - else - { - // do merge with other job results - throw new Error( - "Multiple JNet subjob merging not yet implemented."); - } - } catch (Exception e) - { - jalview.bin.Cache.log.error( - "JNet Client: JPred Annotation Parse Error", e); - wsInfo.setStatus(j.jobnum, WebserviceInfo.STATE_STOPPED_ERROR); - wsInfo.appendProgressText(j.jobnum, OutputHeader + "\n" - + j.result.getStatus() - + "\nInvalid JNet job result data!\n" + e.getMessage()); - j.result.setBroken(true); - } - } - } - - if (res != null) - { - if (newWindow) - { - AlignFrame af; - if (input == null) - { - if (res[1] != null) - { - af = new AlignFrame((Alignment) res[0], - (ColumnSelection) res[1], AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT); - } - else - { - af = new AlignFrame((Alignment) res[0], - AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); - } - } - else - { - /* - * java.lang.Object[] alandcolsel = - * input.getAlignmentAndColumnSelection - * (alignFrame.getViewport().getGapCharacter()); if - * (((SequenceI[])alandcolsel[0])[0].getLength()!=res.getWidth()) { - * if (msa) { throw new Error("Implementation Error! ColumnSelection - * from input alignment will not map to result alignment!"); } } if - * (!msa) { // update hidden regions to account for loss of gaps in - * profile. - if any // gapMap returns insert list, interpreted as - * delete list by pruneDeletions //((ColumnSelection) - * alandcolsel[1]).pruneDeletions(ShiftList.parseMap(((SequenceI[]) - * alandcolsel[0])[0].gapMap())); } - */ - - af = new AlignFrame((Alignment) res[0], - (ColumnSelection) res[1], AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT); - } - Desktop.addInternalFrame(af, altitle, AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT); - } - else - { - Cache.log.info("Append results onto existing alignment."); - } - } - } - } - - public void pollJob(AWsJob job) throws Exception - { - ((JPredJob)job).result = server.getresult(job.jobId); - } - - public boolean isCancellable() - { - return false; - } - - public void cancelJob() - { - throw new Error("Implementation error!"); - } - - public boolean canMergeResults() - { - return false; - } - -} +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5) + * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle + * + * This file is part of Jalview. + * + * Jalview 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 3 of the License, or (at your option) any later version. + * + * Jalview 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 Jalview. If not, see . + */ +package jalview.ws.jws1; + +import java.util.*; + +import jalview.analysis.*; +import jalview.bin.*; +import jalview.datamodel.*; +import jalview.gui.*; +import jalview.io.*; +import jalview.util.*; +import jalview.ws.AWsJob; +import jalview.ws.JobStateSummary; +import jalview.ws.WSClientI; +import vamsas.objects.simple.JpredResult; + +class JPredThread extends JWS1Thread implements WSClientI +{ + // TODO: put mapping between JPredJob input and input data here - + // JNetAnnotation adding is done after result parsing. + class JPredJob extends WSJob + { + // TODO: make JPredJob deal only with what was sent to and received from a + // JNet service + int[] predMap = null; // mapping from sequence(i) to the original + + // sequence(predMap[i]) being predicted on + + vamsas.objects.simple.Sequence sequence; + + vamsas.objects.simple.Msfalignment msa; + + java.util.Hashtable SequenceInfo = null; + + int msaIndex = 0; // the position of the original sequence in the array of + + // Sequences in the input object that this job holds a + // prediction for + + /** + * + * @return true if getResultSet will return a valid alignment and prediction + * result. + */ + public boolean hasResults() + { + if (subjobComplete && result != null && result.isFinished() + && ((JpredResult) result).getPredfile() != null + && ((JpredResult) result).getAligfile() != null) + { + return true; + } + return false; + } + + public boolean hasValidInput() + { + if (sequence != null) + { + return true; + } + return false; + } + + /** + * + * @return null or Object[] { annotated alignment for this prediction, + * ColumnSelection for this prediction} or null if no results + * available. + * @throws Exception + */ + public Object[] getResultSet() throws Exception + { + if (result == null || !result.isFinished()) + { + return null; + } + Alignment al = null; + ColumnSelection alcsel = null; + int FirstSeq = -1; // the position of the query sequence in Alignment al + + JpredResult result = (JpredResult) this.result; + + jalview.bin.Cache.log.debug("Parsing output from JNet job."); + // JPredFile prediction = new JPredFile("C:/JalviewX/files/jpred.txt", + // "File"); + jalview.io.JPredFile prediction = new jalview.io.JPredFile(result + .getPredfile(), "Paste"); + SequenceI[] preds = prediction.getSeqsAsArray(); + jalview.bin.Cache.log.debug("Got prediction profile."); + + if ((this.msa != null) && (result.getAligfile() != null)) + { + jalview.bin.Cache.log.debug("Getting associated alignment."); + // we ignore the returned alignment if we only predicted on a single + // sequence + String format = new jalview.io.IdentifyFile().Identify(result + .getAligfile(), "Paste"); + + if (jalview.io.FormatAdapter.isValidFormat(format)) + { + SequenceI sqs[]; + if (predMap != null) + { + Object[] alandcolsel = input + .getAlignmentAndColumnSelection(getGapChar()); + sqs = (SequenceI[]) alandcolsel[0]; + al = new Alignment(sqs); + alcsel = (ColumnSelection) alandcolsel[1]; + } + else + { + al = new FormatAdapter().readFile(result.getAligfile(), + "Paste", format); + sqs = new SequenceI[al.getHeight()]; + + for (int i = 0, j = al.getHeight(); i < j; i++) + { + sqs[i] = al.getSequenceAt(i); + } + if (!jalview.analysis.SeqsetUtils.deuniquify( + (Hashtable) SequenceInfo, sqs)) + { + throw (new Exception( + "Couldn't recover sequence properties for alignment.")); + } + } + FirstSeq = 0; + al.setDataset(null); + + jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, + FirstSeq, false, predMap); + + } + else + { + throw (new Exception("Unknown format " + format + + " for file : \n" + result.getAligfile())); + } + } + else + { + al = new Alignment(preds); + FirstSeq = prediction.getQuerySeqPosition(); + if (predMap != null) + { + char gc = getGapChar(); + SequenceI[] sqs = (SequenceI[]) ((java.lang.Object[]) input + .getAlignmentAndColumnSelection(gc))[0]; + if (this.msaIndex >= sqs.length) + { + throw new Error( + "Implementation Error! Invalid msaIndex for JPredJob on parent MSA input object!"); + } + + // /// + // Uses RemoveGapsCommand + // /// + new jalview.commands.RemoveGapsCommand("Remove Gaps", + new SequenceI[] + { sqs[msaIndex] }, currentView); + + SequenceI profileseq = al.getSequenceAt(FirstSeq); + profileseq.setSequence(sqs[msaIndex].getSequenceAsString()); + } + + if (!jalview.analysis.SeqsetUtils.SeqCharacterUnhash(al + .getSequenceAt(FirstSeq), SequenceInfo)) + { + throw (new Exception( + "Couldn't recover sequence properties for JNet Query sequence!")); + } + else + { + al.setDataset(null); + jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, + FirstSeq, true, predMap); + SequenceI profileseq = al.getSequenceAt(0); // this includes any gaps. + alignToProfileSeq(al, profileseq); + if (predMap != null) + { + // Adjust input view for gaps + // propagate insertions into profile + alcsel = propagateInsertions(profileseq, al, input); + } + } + } + return new Object[] + { al, alcsel }; // , FirstSeq, noMsa}; + } + + /** + * Given an alignment where all other sequences except profileseq are + * aligned to the ungapped profileseq, insert gaps in the other sequences to + * realign them with the residues in profileseq + * + * @param al + * @param profileseq + */ + private void alignToProfileSeq(Alignment al, SequenceI profileseq) + { + char gc = al.getGapCharacter(); + int[] gapMap = profileseq.gapMap(); + // insert gaps into profile + for (int lp = 0, r = 0; r < gapMap.length; r++) + { + if (gapMap[r] - lp > 1) + { + StringBuffer sb = new StringBuffer(); + for (int s = 0, ns = gapMap[r] - lp; s < ns; s++) + { + sb.append(gc); + } + for (int s = 1, ns = al.getHeight(); s < ns; s++) + { + String sq = al.getSequenceAt(s).getSequenceAsString(); + int diff = gapMap[r] - sq.length(); + if (diff > 0) + { + // pad gaps + sq = sq + sb; + while ((diff = gapMap[r] - sq.length()) > 0) + { + sq = sq + + ((diff >= sb.length()) ? sb.toString() : sb + .substring(0, diff)); + } + al.getSequenceAt(s).setSequence(sq); + } + else + { + al.getSequenceAt(s).setSequence( + sq.substring(0, gapMap[r]) + sb.toString() + + sq.substring(gapMap[r])); + } + } + } + lp = gapMap[r]; + } + } + + /** + * Add gaps into the sequences aligned to profileseq under the given + * AlignmentView + * + * @param profileseq + * @param al + * @param input + */ + private ColumnSelection propagateInsertions(SequenceI profileseq, + Alignment al, AlignmentView input) + { + char gc = al.getGapCharacter(); + Object[] alandcolsel = input.getAlignmentAndColumnSelection(gc); + ColumnSelection nview = (ColumnSelection) alandcolsel[1]; + SequenceI origseq; + nview.pruneDeletions(ShiftList + .parseMap((origseq = ((SequenceI[]) alandcolsel[0])[0]) + .gapMap())); // recover original prediction sequence's + // mapping to view. + int[] viscontigs = nview.getVisibleContigs(0, profileseq.getLength()); + int spos = 0; + int offset = 0; + // input.pruneDeletions(ShiftList.parseMap(((SequenceI[]) + // alandcolsel[0])[0].gapMap())) + // add profile to visible contigs + for (int v = 0; v < viscontigs.length; v += 2) + { + if (viscontigs[v] > spos) + { + StringBuffer sb = new StringBuffer(); + for (int s = 0, ns = viscontigs[v] - spos; s < ns; s++) + { + sb.append(gc); + } + for (int s = 0, ns = al.getHeight(); s < ns; s++) + { + SequenceI sqobj = al.getSequenceAt(s); + if (sqobj != profileseq) + { + String sq = al.getSequenceAt(s).getSequenceAsString(); + if (sq.length() <= spos + offset) + { + // pad sequence + int diff = spos + offset - sq.length() - 1; + if (diff > 0) + { + // pad gaps + sq = sq + sb; + while ((diff = spos + offset - sq.length() - 1) > 0) + { + sq = sq + + ((diff >= sb.length()) ? sb.toString() : sb + .substring(0, diff)); + } + } + sq += sb.toString(); + } + else + { + al.getSequenceAt(s).setSequence( + sq.substring(0, spos + offset) + sb.toString() + + sq.substring(spos + offset)); + } + } + } + // offset+=sb.length(); + } + spos = viscontigs[v + 1] + 1; + } + if ((offset + spos) < profileseq.getLength()) + { + StringBuffer sb = new StringBuffer(); + for (int s = 0, ns = profileseq.getLength() - spos - offset; s < ns; s++) + { + sb.append(gc); + } + for (int s = 1, ns = al.getHeight(); s < ns; s++) + { + String sq = al.getSequenceAt(s).getSequenceAsString(); + // pad sequence + int diff = origseq.getLength() - sq.length(); + while (diff > 0) + { + sq = sq + + ((diff >= sb.length()) ? sb.toString() : sb + .substring(0, diff)); + diff = origseq.getLength() - sq.length(); + } + } + } + return nview; + } + + public JPredJob(Hashtable SequenceInfo, SequenceI seq, int[] delMap) + { + super(); + this.predMap = delMap; + String sq = AlignSeq.extractGaps(Comparison.GapChars, seq + .getSequenceAsString()); + if (sq.length() >= 20) + { + this.SequenceInfo = SequenceInfo; + sequence = new vamsas.objects.simple.Sequence(); + sequence.setId(seq.getName()); + sequence.setSeq(sq); + } + } + + public JPredJob(Hashtable SequenceInfo, SequenceI[] msf, int[] delMap) + { + this(SequenceInfo, msf[0], delMap); + if (sequence != null) + { + if (msf.length > 1) + { + msa = new vamsas.objects.simple.Msfalignment(); + jalview.io.PileUpfile pileup = new jalview.io.PileUpfile(); + msa.setMsf(pileup.print(msf)); + } + } + } + } + + ext.vamsas.Jpred server; + + String altitle = ""; + + JPredThread(WebserviceInfo wsinfo, String altitle, + ext.vamsas.Jpred server, String wsurl, AlignmentView alview, + AlignFrame alframe) + { + super(alframe, wsinfo, alview, wsurl); + this.altitle = altitle; + this.server = server; + } + + JPredThread(WebserviceInfo wsinfo, String altitle, + ext.vamsas.Jpred server, String wsurl, Hashtable SequenceInfo, + SequenceI seq, int[] delMap, AlignmentView alview, + AlignFrame alframe) + { + this(wsinfo, altitle, server, wsurl, alview, alframe); + JPredJob job = new JPredJob(SequenceInfo, seq, delMap); + if (job.hasValidInput()) + { + OutputHeader = wsInfo.getProgressText(); + jobs = new WSJob[] + { job }; + job.setJobnum(0); + } + } + + JPredThread(WebserviceInfo wsinfo, String altitle, + ext.vamsas.Jpred server, Hashtable SequenceInfo, SequenceI[] msf, + int[] delMap, AlignmentView alview, AlignFrame alframe, + String wsurl) + { + this(wsinfo, altitle, server, wsurl, alview, alframe); + JPredJob job = new JPredJob(SequenceInfo, msf, delMap); + if (job.hasValidInput()) + { + jobs = new WSJob[] + { job }; + OutputHeader = wsInfo.getProgressText(); + job.setJobnum(0); + } + } + + public void StartJob(AWsJob j) + { + if (!(j instanceof JPredJob)) + { + throw new Error( + "Implementation error - StartJob(JpredJob) called on " + + j.getClass()); + } + try + { + JPredJob job = (JPredJob) j; + if (job.msa != null) + { + job.setJobId(server.predictOnMsa(job.msa)); + } + else if (job.sequence != null) + { + job.setJobId(server.predict(job.sequence)); // debug like : job.jobId = + // "/jobs/www-jpred/jp_Yatat29";// + } + + if (job.getJobId() != null) + { + if (job.getJobId().startsWith("Broken")) + { + job.result = (vamsas.objects.simple.Result) new JpredResult(); + job.result.setInvalid(true); + job.result.setStatus("Submission " + job.getJobId()); + throw new Exception(job.getJobId()); + } + else + { + job.setSubmitted(true); + job.setSubjobComplete(false); + Cache.log.info(WsUrl + " Job Id '" + job.getJobId() + "'"); + } + } + else + { + throw new Exception("Server timed out - try again later\n"); + } + } catch (Exception e) + { + // kill the whole job. + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR); + if (e.getMessage().indexOf("Exception") > -1) + { + wsInfo + .setStatus(j.getJobnum(), + WebserviceInfo.STATE_STOPPED_SERVERERROR); + wsInfo + .setProgressText( + j.getJobnum(), + "Failed to submit the prediction. (Just close the window)\n" + + "It is most likely that there is a problem with the server.\n"); + System.err + .println("JPredWS Client: Failed to submit the prediction. Quite possibly because of a server error - see below)\n" + + e.getMessage() + "\n"); + + jalview.bin.Cache.log.warn("Server Exception", e); + } + else + { + wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR); + // JBPNote - this could be a popup informing the user of the problem. + wsInfo.appendProgressText(j.getJobnum(), + "Failed to submit the prediction:\n" + e.getMessage() + + wsInfo.getProgressText()); + + jalview.bin.Cache.log.debug("Failed Submission of job " + j.getJobnum(), + e); + + } + j.setAllowedServerExceptions(-1); + j.setSubjobComplete(true); + } + } + + public void parseResult() + { + int results = 0; // number of result sets received + JobStateSummary finalState = new JobStateSummary(); + try + { + for (int j = 0; j < jobs.length; j++) + { + finalState.updateJobPanelState(wsInfo, OutputHeader, jobs[j]); + if (jobs[j].isSubmitted() && jobs[j].isSubjobComplete() + && jobs[j].hasResults()) + { + results++; + } + } + } catch (Exception ex) + { + + Cache.log.error("Unexpected exception when processing results for " + + altitle, ex); + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); + } + if (results > 0) + { + wsInfo.showResultsNewFrame + .addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + displayResults(true); + } + }); + wsInfo.mergeResults + .addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + displayResults(false); + } + }); + wsInfo.setResultsReady(); + } + else + { + wsInfo.setFinishedNoResults(); + } + } + + void displayResults(boolean newWindow) + { + // TODO: cope with multiple subjobs. + if (jobs != null) + { + Object[] res = null; + boolean msa = false; + for (int jn = 0; jn < jobs.length; jn++) + { + Object[] jobres = null; + JPredJob j = (JPredJob) jobs[jn]; + + if (j.hasResults()) + { + // hack - we only deal with all single seuqence predictions or all + // profile predictions + msa = (j.msa != null) ? true : msa; + try + { + jalview.bin.Cache.log.debug("Parsing output of job " + jn); + jobres = j.getResultSet(); + jalview.bin.Cache.log.debug("Finished parsing output."); + if (jobs.length == 1) + { + res = jobres; + } + else + { + // do merge with other job results + throw new Error( + "Multiple JNet subjob merging not yet implemented."); + } + } catch (Exception e) + { + jalview.bin.Cache.log.error( + "JNet Client: JPred Annotation Parse Error", e); + wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR); + wsInfo.appendProgressText(j.getJobnum(), OutputHeader + "\n" + + j.result.getStatus() + + "\nInvalid JNet job result data!\n" + e.getMessage()); + j.result.setBroken(true); + } + } + } + + if (res != null) + { + if (newWindow) + { + AlignFrame af; + if (input == null) + { + if (res[1] != null) + { + af = new AlignFrame((Alignment) res[0], + (ColumnSelection) res[1], AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + } + else + { + af = new AlignFrame((Alignment) res[0], + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + } + } + else + { + /* + * java.lang.Object[] alandcolsel = + * input.getAlignmentAndColumnSelection + * (alignFrame.getViewport().getGapCharacter()); if + * (((SequenceI[])alandcolsel[0])[0].getLength()!=res.getWidth()) { + * if (msa) { throw new Error("Implementation Error! ColumnSelection + * from input alignment will not map to result alignment!"); } } if + * (!msa) { // update hidden regions to account for loss of gaps in + * profile. - if any // gapMap returns insert list, interpreted as + * delete list by pruneDeletions //((ColumnSelection) + * alandcolsel[1]).pruneDeletions(ShiftList.parseMap(((SequenceI[]) + * alandcolsel[0])[0].gapMap())); } + */ + + af = new AlignFrame((Alignment) res[0], + (ColumnSelection) res[1], AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + } + Desktop.addInternalFrame(af, altitle, AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + } + else + { + Cache.log.info("Append results onto existing alignment."); + } + } + } + } + + public void pollJob(AWsJob job) throws Exception + { + ((JPredJob)job).result = server.getresult(job.getJobId()); + } + + public boolean isCancellable() + { + return false; + } + + public void cancelJob() + { + throw new Error("Implementation error!"); + } + + public boolean canMergeResults() + { + return false; + } + +} diff --git a/src/jalview/ws/JWS1Thread.java b/src/jalview/ws/jws1/JWS1Thread.java similarity index 96% rename from src/jalview/ws/JWS1Thread.java rename to src/jalview/ws/jws1/JWS1Thread.java index c4d4c16..4ca24b8 100644 --- a/src/jalview/ws/JWS1Thread.java +++ b/src/jalview/ws/jws1/JWS1Thread.java @@ -15,13 +15,14 @@ * * You should have received a copy of the GNU General Public License along with Jalview. If not, see . */ -package jalview.ws; +package jalview.ws.jws1; import javax.swing.*; import jalview.bin.*; import jalview.datamodel.*; import jalview.gui.*; +import jalview.ws.AWSThread; /** * specific methods for Jalview WS1 web service jobs diff --git a/src/jalview/ws/MsaWSClient.java b/src/jalview/ws/jws1/MsaWSClient.java old mode 100755 new mode 100644 similarity index 97% rename from src/jalview/ws/MsaWSClient.java rename to src/jalview/ws/jws1/MsaWSClient.java index d58e2dc..e081b2e --- a/src/jalview/ws/MsaWSClient.java +++ b/src/jalview/ws/jws1/MsaWSClient.java @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License along with Jalview. If not, see . */ -package jalview.ws; +package jalview.ws.jws1; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -200,7 +200,7 @@ public class MsaWSClient extends WS1Client public void actionPerformed(ActionEvent e) { AlignmentView msa = alignFrame.gatherSequencesForAlignment(); - new jalview.ws.MsaWSClient(serviceHandle, alignFrame.getTitle(), + new jalview.ws.jws1.MsaWSClient(serviceHandle, alignFrame.getTitle(), msa, false, true, alignFrame.getViewport().getAlignment() .getDataset(), alignFrame); @@ -219,7 +219,7 @@ public class MsaWSClient extends WS1Client public void actionPerformed(ActionEvent e) { AlignmentView msa = alignFrame.gatherSequencesForAlignment(); - new jalview.ws.MsaWSClient(serviceHandle, alignFrame.getTitle(), + new jalview.ws.jws1.MsaWSClient(serviceHandle, alignFrame.getTitle(), msa, true, true, alignFrame.getViewport().getAlignment() .getDataset(), alignFrame); diff --git a/src/jalview/ws/MsaWSThread.java b/src/jalview/ws/jws1/MsaWSThread.java similarity index 92% rename from src/jalview/ws/MsaWSThread.java rename to src/jalview/ws/jws1/MsaWSThread.java index ab3dfbe..446aefa 100644 --- a/src/jalview/ws/MsaWSThread.java +++ b/src/jalview/ws/jws1/MsaWSThread.java @@ -1,712 +1,715 @@ -/* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5) - * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle - * - * This file is part of Jalview. - * - * Jalview 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 3 of the License, or (at your option) any later version. - * - * Jalview 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 Jalview. If not, see . - */ -package jalview.ws; - -import java.util.*; - -import jalview.analysis.*; -import jalview.bin.*; -import jalview.datamodel.*; -import jalview.gui.*; -import vamsas.objects.simple.MsaResult; - -/** - *

- * Title: - *

- * - *

- * Description: - *

- * - *

- * Copyright: Copyright (c) 2004 - *

- * - *

- * Company: Dundee University - *

- * - * @author not attributable - * @version 1.0 - */ -class MsaWSThread extends JWS1Thread implements WSClientI -{ - boolean submitGaps = false; // pass sequences including gaps to alignment - - // service - - boolean preserveOrder = true; // and always store and recover sequence - - // order - - class MsaWSJob extends WSJob - { - // hold special input for this - vamsas.objects.simple.SequenceSet seqs = new vamsas.objects.simple.SequenceSet(); - - /** - * MsaWSJob - * - * @param jobNum - * int - * @param jobId - * String - */ - public MsaWSJob(int jobNum, SequenceI[] inSeqs) - { - this.jobnum = jobNum; - if (!prepareInput(inSeqs, 2)) - { - submitted = true; - subjobComplete = true; - result = new MsaResult(); - result.setFinished(true); - result.setStatus("Job never ran - input returned to user."); - } - - } - - Hashtable SeqNames = new Hashtable(); - - Vector emptySeqs = new Vector(); - - /** - * prepare input sequences for MsaWS service - * - * @param seqs - * jalview sequences to be prepared - * @param minlen - * minimum number of residues required for this MsaWS service - * @return true if seqs contains sequences to be submitted to service. - */ - private boolean prepareInput(SequenceI[] seqs, int minlen) - { - int nseqs = 0; - if (minlen < 0) - { - throw new Error( - "Implementation error: minlen must be zero or more."); - } - for (int i = 0; i < seqs.length; i++) - { - if (seqs[i].getEnd() - seqs[i].getStart() > minlen - 1) - { - nseqs++; - } - } - boolean valid = nseqs > 1; // need at least two seqs - vamsas.objects.simple.Sequence[] seqarray = (valid) ? new vamsas.objects.simple.Sequence[nseqs] - : null; - for (int i = 0, n = 0; i < seqs.length; i++) - { - - String newname = jalview.analysis.SeqsetUtils.unique_name(i); // same - // for - // any - // subjob - SeqNames.put(newname, jalview.analysis.SeqsetUtils - .SeqCharacterHash(seqs[i])); - if (valid && seqs[i].getEnd() - seqs[i].getStart() > minlen - 1) - { - seqarray[n] = new vamsas.objects.simple.Sequence(); - seqarray[n].setId(newname); - seqarray[n++].setSeq((submitGaps) ? seqs[i].getSequenceAsString() - : AlignSeq.extractGaps(jalview.util.Comparison.GapChars, - seqs[i].getSequenceAsString())); - } - else - { - String empty = null; - if (seqs[i].getEnd() >= seqs[i].getStart()) - { - empty = (submitGaps) ? seqs[i].getSequenceAsString() : AlignSeq - .extractGaps(jalview.util.Comparison.GapChars, seqs[i] - .getSequenceAsString()); - } - emptySeqs.add(new String[] - { newname, empty }); - } - } - this.seqs = new vamsas.objects.simple.SequenceSet(); - this.seqs.setSeqs(seqarray); - return valid; - } - - /** - * - * @return true if getAlignment will return a valid alignment result. - */ - public boolean hasResults() - { - if (subjobComplete && result != null && result.isFinished() - && ((MsaResult) result).getMsa() != null - && ((MsaResult) result).getMsa().getSeqs() != null) - { - return true; - } - return false; - } - - public Object[] getAlignment() - { - - if (result != null && result.isFinished()) - { - SequenceI[] alseqs = null; - char alseq_gapchar = '-'; - int alseq_l = 0; - if (((MsaResult) result).getMsa() != null) - { - alseqs = getVamsasAlignment(((MsaResult) result).getMsa()); - alseq_gapchar = ((MsaResult) result).getMsa().getGapchar() - .charAt(0); - alseq_l = alseqs.length; - } - if (emptySeqs.size() > 0) - { - SequenceI[] t_alseqs = new SequenceI[alseq_l + emptySeqs.size()]; - // get width - int i, w = 0; - if (alseq_l > 0) - { - for (i = 0, w = alseqs[0].getLength(); i < alseq_l; i++) - { - if (w < alseqs[i].getLength()) - { - w = alseqs[i].getLength(); - } - t_alseqs[i] = alseqs[i]; - alseqs[i] = null; - } - } - // check that aligned width is at least as wide as emptySeqs width. - int ow = w, nw = w; - for (i = 0, w = emptySeqs.size(); i < w; i++) - { - String[] es = (String[]) emptySeqs.get(i); - if (es != null && es[1] != null) - { - int sw = es[1].length(); - if (nw < sw) - { - nw = sw; - } - } - } - // make a gapped string. - StringBuffer insbuff = new StringBuffer(w); - for (i = 0; i < nw; i++) - { - insbuff.append(alseq_gapchar); - } - if (ow < nw) - { - for (i = 0; i < alseq_l; i++) - { - int sw = t_alseqs[i].getLength(); - if (nw > sw) - { - // pad at end - alseqs[i].setSequence(t_alseqs[i].getSequenceAsString() - + insbuff.substring(0, sw - nw)); - } - } - } - for (i = 0, w = emptySeqs.size(); i < w; i++) - { - String[] es = (String[]) emptySeqs.get(i); - if (es[1] == null) - { - t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence(es[0], - insbuff.toString(), 1, 0); - } - else - { - if (es[1].length() < nw) - { - t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence( - es[0], - es[1] + insbuff.substring(0, nw - es[1].length()), - 1, 1 + es[1].length()); - } - else - { - t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence( - es[0], es[1]); - } - } - } - alseqs = t_alseqs; - } - AlignmentOrder msaorder = new AlignmentOrder(alseqs); - // always recover the order - makes parseResult()'s life easier. - jalview.analysis.AlignmentSorter.recoverOrder(alseqs); - // account for any missing sequences - jalview.analysis.SeqsetUtils.deuniquify(SeqNames, alseqs); - return new Object[] - { alseqs, msaorder }; - } - return null; - } - - /** - * mark subjob as cancelled and set result object appropriatly - */ - void cancel() - { - cancelled = true; - subjobComplete = true; - result = null; - } - - /** - * - * @return boolean true if job can be submitted. - */ - public boolean hasValidInput() - { - if (seqs.getSeqs() != null) - { - return true; - } - return false; - } - } - - String alTitle; // name which will be used to form new alignment window. - - Alignment dataset; // dataset to which the new alignment will be - - // associated. - - ext.vamsas.MuscleWS server = null; - - /** - * set basic options for this (group) of Msa jobs - * - * @param subgaps - * boolean - * @param presorder - * boolean - */ - MsaWSThread(ext.vamsas.MuscleWS server, String wsUrl, - WebserviceInfo wsinfo, jalview.gui.AlignFrame alFrame, - AlignmentView alview, String wsname, boolean subgaps, - boolean presorder) - { - super(alFrame, wsinfo, alview, wsname, wsUrl); - this.server = server; - this.submitGaps = subgaps; - this.preserveOrder = presorder; - } - - /** - * create one or more Msa jobs to align visible seuqences in _msa - * - * @param title - * String - * @param _msa - * AlignmentView - * @param subgaps - * boolean - * @param presorder - * boolean - * @param seqset - * Alignment - */ - MsaWSThread(ext.vamsas.MuscleWS server, String wsUrl, - WebserviceInfo wsinfo, jalview.gui.AlignFrame alFrame, - String wsname, String title, AlignmentView _msa, boolean subgaps, - boolean presorder, Alignment seqset) - { - this(server, wsUrl, wsinfo, alFrame, _msa, wsname, subgaps, presorder); - OutputHeader = wsInfo.getProgressText(); - alTitle = title; - dataset = seqset; - - SequenceI[][] conmsa = _msa.getVisibleContigs('-'); - if (conmsa != null) - { - int njobs = conmsa.length; - jobs = new MsaWSJob[njobs]; - for (int j = 0; j < njobs; j++) - { - if (j != 0) - { - jobs[j] = new MsaWSJob(wsinfo.addJobPane(), conmsa[j]); - } - else - { - jobs[j] = new MsaWSJob(0, conmsa[j]); - } - if (njobs > 0) - { - wsinfo - .setProgressName("region " + jobs[j].jobnum, - jobs[j].jobnum); - } - wsinfo.setProgressText(jobs[j].jobnum, OutputHeader); - } - } - } - - public boolean isCancellable() - { - return true; - } - - public void cancelJob() - { - if (!jobComplete && jobs != null) - { - boolean cancelled = true; - for (int job = 0; job < jobs.length; job++) - { - if (jobs[job].submitted && !jobs[job].subjobComplete) - { - String cancelledMessage = ""; - try - { - vamsas.objects.simple.WsJobId cancelledJob = server - .cancel(jobs[job].jobId); - if (cancelledJob.getStatus() == 2) - { - // CANCELLED_JOB - cancelledMessage = "Job cancelled."; - ((MsaWSJob) jobs[job]).cancel(); - wsInfo.setStatus(jobs[job].jobnum, - WebserviceInfo.STATE_CANCELLED_OK); - } - else if (cancelledJob.getStatus() == 3) - { - // VALID UNSTOPPABLE JOB - cancelledMessage += "Server cannot cancel this job. just close the window.\n"; - cancelled = false; - // wsInfo.setStatus(jobs[job].jobnum, - // WebserviceInfo.STATE_RUNNING); - } - - if (cancelledJob.getJobId() != null) - { - cancelledMessage += ("[" + cancelledJob.getJobId() + "]"); - } - - cancelledMessage += "\n"; - } catch (Exception exc) - { - cancelledMessage += ("\nProblems cancelling the job : Exception received...\n" - + exc + "\n"); - Cache.log.warn( - "Exception whilst cancelling " + jobs[job].jobId, exc); - } - wsInfo.setProgressText(jobs[job].jobnum, OutputHeader - + cancelledMessage + "\n"); - } - } - if (cancelled) - { - wsInfo.setStatus(WebserviceInfo.STATE_CANCELLED_OK); - jobComplete = true; - } - this.interrupt(); // kick thread to update job states. - } - else - { - if (!jobComplete) - { - wsInfo - .setProgressText(OutputHeader - + "Server cannot cancel this job because it has not been submitted properly. just close the window.\n"); - } - } - } - - public void pollJob(AWsJob job) throws Exception - { - ((MsaWSJob) job).result = server.getResult(((MsaWSJob) job).jobId); - } - - public void StartJob(AWsJob job) - { - if (!(job instanceof MsaWSJob)) - { - throw new Error("StartJob(MsaWSJob) called on a WSJobInstance " - + job.getClass()); - } - MsaWSJob j = (MsaWSJob) job; - if (j.submitted) - { - if (Cache.log.isDebugEnabled()) - { - Cache.log.debug("Tried to submit an already submitted job " - + j.jobId); - } - return; - } - if (j.seqs.getSeqs() == null) - { - // special case - selection consisted entirely of empty sequences... - j.submitted = true; - j.result = new MsaResult(); - j.result.setFinished(true); - j.result.setStatus("Empty Alignment Job"); - ((MsaResult) j.result).setMsa(null); - } - try - { - vamsas.objects.simple.WsJobId jobsubmit = server.align(j.seqs); - - if ((jobsubmit != null) && (jobsubmit.getStatus() == 1)) - { - j.jobId = jobsubmit.getJobId(); - j.submitted = true; - j.subjobComplete = false; - // 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"); - j.allowedServerExceptions = 0; - wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR); - wsInfo.setStatus(j.jobnum, WebserviceInfo.STATE_STOPPED_SERVERERROR); - wsInfo - .appendProgressText( - j.jobnum, - "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 - } - } - - private jalview.datamodel.Sequence[] getVamsasAlignment( - vamsas.objects.simple.Alignment valign) - { - // TODO: refactor to helper class for vamsas.objects.simple objects - 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 < j; i++) - { - msa[i] = new jalview.datamodel.Sequence(seqs[i].getId(), seqs[i] - .getSeq()); - } - - return msa; - } - - public void parseResult() - { - int results = 0; // number of result sets received - JobStateSummary finalState = new JobStateSummary(); - try - { - for (int j = 0; j < jobs.length; j++) - { - finalState.updateJobPanelState(wsInfo, OutputHeader, jobs[j]); - if (jobs[j].submitted && jobs[j].subjobComplete - && jobs[j].hasResults()) - { - results++; - vamsas.objects.simple.Alignment valign = ((MsaResult)((MsaWSJob) jobs[j]).result) - .getMsa(); - if (valign != null) - { - wsInfo.appendProgressText(jobs[j].jobnum, - "\nAlignment Object Method Notes\n"); - String[] lines = valign.getMethod(); - for (int line = 0; line < lines.length; line++) - { - wsInfo.appendProgressText(jobs[j].jobnum, lines[line] + "\n"); - } - // JBPNote The returned files from a webservice could be - // hidden behind icons in the monitor window that, - // when clicked, pop up their corresponding data - } - } - } - } catch (Exception ex) - { - - Cache.log.error("Unexpected exception when processing results for " - + alTitle, ex); - wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); - } - if (results > 0) - { - wsInfo.showResultsNewFrame - .addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(java.awt.event.ActionEvent evt) - { - displayResults(true); - } - }); - wsInfo.mergeResults - .addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(java.awt.event.ActionEvent evt) - { - displayResults(false); - } - }); - wsInfo.setResultsReady(); - } - else - { - wsInfo.setFinishedNoResults(); - } - } - - void displayResults(boolean newFrame) - { - // view input or result data for each block - Vector alorders = new Vector(); - SequenceI[][] results = new SequenceI[jobs.length][]; - AlignmentOrder[] orders = new AlignmentOrder[jobs.length]; - for (int j = 0; j < jobs.length; j++) - { - if (jobs[j].hasResults()) - { - Object[] res = ((MsaWSJob) jobs[j]).getAlignment(); - alorders.add(res[1]); - results[j] = (SequenceI[]) res[0]; - orders[j] = (AlignmentOrder) res[1]; - - // SequenceI[] alignment = input.getUpdated - } - else - { - results[j] = null; - } - } - Object[] newview = input.getUpdatedView(results, orders, getGapChar()); - // trash references to original result data - for (int j = 0; j < jobs.length; j++) - { - results[j] = null; - orders[j] = null; - } - SequenceI[] alignment = (SequenceI[]) newview[0]; - ColumnSelection columnselection = (ColumnSelection) newview[1]; - Alignment al = new Alignment(alignment); - // TODO: add 'provenance' property to alignment from the method notes - // accompanying each subjob - if (dataset != null) - { - al.setDataset(dataset); - } - - propagateDatasetMappings(al); - // JBNote- TODO: warn user if a block is input rather than aligned data ? - - if (newFrame) - { - AlignFrame af = new AlignFrame(al, columnselection, - AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); - - // initialise with same renderer settings as in parent alignframe. - af.getFeatureRenderer().transferSettings(this.featureSettings); - // update orders - if (alorders.size() > 0) - { - if (alorders.size() == 1) - { - af.addSortByOrderMenuItem(WebServiceName + " Ordering", - (AlignmentOrder) alorders.get(0)); - } - else - { - // construct a non-redundant ordering set - Vector names = new Vector(); - for (int i = 0, l = alorders.size(); i < l; i++) - { - String orderName = new String(" Region " + i); - int j = i + 1; - - while (j < l) - { - if (((AlignmentOrder) alorders.get(i)) - .equals(((AlignmentOrder) alorders.get(j)))) - { - alorders.remove(j); - l--; - orderName += "," + j; - } - else - { - j++; - } - } - - if (i == 0 && j == 1) - { - names.add(new String("")); - } - else - { - names.add(orderName); - } - } - for (int i = 0, l = alorders.size(); i < l; i++) - { - af.addSortByOrderMenuItem(WebServiceName - + ((String) names.get(i)) + " Ordering", - (AlignmentOrder) alorders.get(i)); - } - } - } - - Desktop.addInternalFrame(af, alTitle, AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT); - - } - else - { - System.out.println("MERGE WITH OLD FRAME"); - // TODO: modify alignment in original frame, replacing old for new - // alignment using the commands.EditCommand model to ensure the update can - // be undone - } - } - - public boolean canMergeResults() - { - return false; - } -} +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5) + * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle + * + * This file is part of Jalview. + * + * Jalview 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 3 of the License, or (at your option) any later version. + * + * Jalview 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 Jalview. If not, see . + */ +package jalview.ws.jws1; + +import java.util.*; + +import jalview.analysis.*; +import jalview.bin.*; +import jalview.datamodel.*; +import jalview.gui.*; +import jalview.ws.AWsJob; +import jalview.ws.JobStateSummary; +import jalview.ws.WSClientI; +import vamsas.objects.simple.MsaResult; + +/** + *

+ * Title: + *

+ * + *

+ * Description: + *

+ * + *

+ * Copyright: Copyright (c) 2004 + *

+ * + *

+ * Company: Dundee University + *

+ * + * @author not attributable + * @version 1.0 + */ +class MsaWSThread extends JWS1Thread implements WSClientI +{ + boolean submitGaps = false; // pass sequences including gaps to alignment + + // service + + boolean preserveOrder = true; // and always store and recover sequence + + // order + + class MsaWSJob extends WSJob + { + // hold special input for this + vamsas.objects.simple.SequenceSet seqs = new vamsas.objects.simple.SequenceSet(); + + /** + * MsaWSJob + * + * @param jobNum + * int + * @param jobId + * String + */ + public MsaWSJob(int jobNum, SequenceI[] inSeqs) + { + this.jobnum = jobNum; + if (!prepareInput(inSeqs, 2)) + { + submitted = true; + subjobComplete = true; + result = new MsaResult(); + result.setFinished(true); + result.setStatus("Job never ran - input returned to user."); + } + + } + + Hashtable SeqNames = new Hashtable(); + + Vector emptySeqs = new Vector(); + + /** + * prepare input sequences for MsaWS service + * + * @param seqs + * jalview sequences to be prepared + * @param minlen + * minimum number of residues required for this MsaWS service + * @return true if seqs contains sequences to be submitted to service. + */ + private boolean prepareInput(SequenceI[] seqs, int minlen) + { + int nseqs = 0; + if (minlen < 0) + { + throw new Error( + "Implementation error: minlen must be zero or more."); + } + for (int i = 0; i < seqs.length; i++) + { + if (seqs[i].getEnd() - seqs[i].getStart() > minlen - 1) + { + nseqs++; + } + } + boolean valid = nseqs > 1; // need at least two seqs + vamsas.objects.simple.Sequence[] seqarray = (valid) ? new vamsas.objects.simple.Sequence[nseqs] + : null; + for (int i = 0, n = 0; i < seqs.length; i++) + { + + String newname = jalview.analysis.SeqsetUtils.unique_name(i); // same + // for + // any + // subjob + SeqNames.put(newname, jalview.analysis.SeqsetUtils + .SeqCharacterHash(seqs[i])); + if (valid && seqs[i].getEnd() - seqs[i].getStart() > minlen - 1) + { + seqarray[n] = new vamsas.objects.simple.Sequence(); + seqarray[n].setId(newname); + seqarray[n++].setSeq((submitGaps) ? seqs[i].getSequenceAsString() + : AlignSeq.extractGaps(jalview.util.Comparison.GapChars, + seqs[i].getSequenceAsString())); + } + else + { + String empty = null; + if (seqs[i].getEnd() >= seqs[i].getStart()) + { + empty = (submitGaps) ? seqs[i].getSequenceAsString() : AlignSeq + .extractGaps(jalview.util.Comparison.GapChars, seqs[i] + .getSequenceAsString()); + } + emptySeqs.add(new String[] + { newname, empty }); + } + } + this.seqs = new vamsas.objects.simple.SequenceSet(); + this.seqs.setSeqs(seqarray); + return valid; + } + + /** + * + * @return true if getAlignment will return a valid alignment result. + */ + public boolean hasResults() + { + if (subjobComplete && result != null && result.isFinished() + && ((MsaResult) result).getMsa() != null + && ((MsaResult) result).getMsa().getSeqs() != null) + { + return true; + } + return false; + } + + public Object[] getAlignment() + { + + if (result != null && result.isFinished()) + { + SequenceI[] alseqs = null; + char alseq_gapchar = '-'; + int alseq_l = 0; + if (((MsaResult) result).getMsa() != null) + { + alseqs = getVamsasAlignment(((MsaResult) result).getMsa()); + alseq_gapchar = ((MsaResult) result).getMsa().getGapchar() + .charAt(0); + alseq_l = alseqs.length; + } + if (emptySeqs.size() > 0) + { + SequenceI[] t_alseqs = new SequenceI[alseq_l + emptySeqs.size()]; + // get width + int i, w = 0; + if (alseq_l > 0) + { + for (i = 0, w = alseqs[0].getLength(); i < alseq_l; i++) + { + if (w < alseqs[i].getLength()) + { + w = alseqs[i].getLength(); + } + t_alseqs[i] = alseqs[i]; + alseqs[i] = null; + } + } + // check that aligned width is at least as wide as emptySeqs width. + int ow = w, nw = w; + for (i = 0, w = emptySeqs.size(); i < w; i++) + { + String[] es = (String[]) emptySeqs.get(i); + if (es != null && es[1] != null) + { + int sw = es[1].length(); + if (nw < sw) + { + nw = sw; + } + } + } + // make a gapped string. + StringBuffer insbuff = new StringBuffer(w); + for (i = 0; i < nw; i++) + { + insbuff.append(alseq_gapchar); + } + if (ow < nw) + { + for (i = 0; i < alseq_l; i++) + { + int sw = t_alseqs[i].getLength(); + if (nw > sw) + { + // pad at end + alseqs[i].setSequence(t_alseqs[i].getSequenceAsString() + + insbuff.substring(0, sw - nw)); + } + } + } + for (i = 0, w = emptySeqs.size(); i < w; i++) + { + String[] es = (String[]) emptySeqs.get(i); + if (es[1] == null) + { + t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence(es[0], + insbuff.toString(), 1, 0); + } + else + { + if (es[1].length() < nw) + { + t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence( + es[0], + es[1] + insbuff.substring(0, nw - es[1].length()), + 1, 1 + es[1].length()); + } + else + { + t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence( + es[0], es[1]); + } + } + } + alseqs = t_alseqs; + } + AlignmentOrder msaorder = new AlignmentOrder(alseqs); + // always recover the order - makes parseResult()'s life easier. + jalview.analysis.AlignmentSorter.recoverOrder(alseqs); + // account for any missing sequences + jalview.analysis.SeqsetUtils.deuniquify(SeqNames, alseqs); + return new Object[] + { alseqs, msaorder }; + } + return null; + } + + /** + * mark subjob as cancelled and set result object appropriatly + */ + void cancel() + { + cancelled = true; + subjobComplete = true; + result = null; + } + + /** + * + * @return boolean true if job can be submitted. + */ + public boolean hasValidInput() + { + if (seqs.getSeqs() != null) + { + return true; + } + return false; + } + } + + String alTitle; // name which will be used to form new alignment window. + + Alignment dataset; // dataset to which the new alignment will be + + // associated. + + ext.vamsas.MuscleWS server = null; + + /** + * set basic options for this (group) of Msa jobs + * + * @param subgaps + * boolean + * @param presorder + * boolean + */ + MsaWSThread(ext.vamsas.MuscleWS server, String wsUrl, + WebserviceInfo wsinfo, jalview.gui.AlignFrame alFrame, + AlignmentView alview, String wsname, boolean subgaps, + boolean presorder) + { + super(alFrame, wsinfo, alview, wsname, wsUrl); + this.server = server; + this.submitGaps = subgaps; + this.preserveOrder = presorder; + } + + /** + * create one or more Msa jobs to align visible seuqences in _msa + * + * @param title + * String + * @param _msa + * AlignmentView + * @param subgaps + * boolean + * @param presorder + * boolean + * @param seqset + * Alignment + */ + MsaWSThread(ext.vamsas.MuscleWS server, String wsUrl, + WebserviceInfo wsinfo, jalview.gui.AlignFrame alFrame, + String wsname, String title, AlignmentView _msa, boolean subgaps, + boolean presorder, Alignment seqset) + { + this(server, wsUrl, wsinfo, alFrame, _msa, wsname, subgaps, presorder); + OutputHeader = wsInfo.getProgressText(); + alTitle = title; + dataset = seqset; + + SequenceI[][] conmsa = _msa.getVisibleContigs('-'); + if (conmsa != null) + { + int njobs = conmsa.length; + jobs = new MsaWSJob[njobs]; + for (int j = 0; j < njobs; j++) + { + if (j != 0) + { + jobs[j] = new MsaWSJob(wsinfo.addJobPane(), conmsa[j]); + } + else + { + jobs[j] = new MsaWSJob(0, conmsa[j]); + } + if (njobs > 0) + { + wsinfo + .setProgressName("region " + jobs[j].getJobnum(), + jobs[j].getJobnum()); + } + wsinfo.setProgressText(jobs[j].getJobnum(), OutputHeader); + } + } + } + + public boolean isCancellable() + { + return true; + } + + public void cancelJob() + { + if (!jobComplete && jobs != null) + { + boolean cancelled = true; + for (int job = 0; job < jobs.length; job++) + { + if (jobs[job].isSubmitted() && !jobs[job].isSubjobComplete()) + { + String cancelledMessage = ""; + try + { + vamsas.objects.simple.WsJobId cancelledJob = server + .cancel(jobs[job].getJobId()); + if (cancelledJob.getStatus() == 2) + { + // CANCELLED_JOB + cancelledMessage = "Job cancelled."; + ((MsaWSJob) jobs[job]).cancel(); + wsInfo.setStatus(jobs[job].getJobnum(), + WebserviceInfo.STATE_CANCELLED_OK); + } + else if (cancelledJob.getStatus() == 3) + { + // VALID UNSTOPPABLE JOB + cancelledMessage += "Server cannot cancel this job. just close the window.\n"; + cancelled = false; + // wsInfo.setStatus(jobs[job].jobnum, + // WebserviceInfo.STATE_RUNNING); + } + + if (cancelledJob.getJobId() != null) + { + cancelledMessage += ("[" + cancelledJob.getJobId() + "]"); + } + + cancelledMessage += "\n"; + } catch (Exception exc) + { + cancelledMessage += ("\nProblems cancelling the job : Exception received...\n" + + exc + "\n"); + Cache.log.warn( + "Exception whilst cancelling " + jobs[job].getJobId(), exc); + } + wsInfo.setProgressText(jobs[job].getJobnum(), OutputHeader + + cancelledMessage + "\n"); + } + } + if (cancelled) + { + wsInfo.setStatus(WebserviceInfo.STATE_CANCELLED_OK); + jobComplete = true; + } + this.interrupt(); // kick thread to update job states. + } + else + { + if (!jobComplete) + { + wsInfo + .setProgressText(OutputHeader + + "Server cannot cancel this job because it has not been submitted properly. just close the window.\n"); + } + } + } + + public void pollJob(AWsJob job) throws Exception + { + ((MsaWSJob) job).result = server.getResult(((MsaWSJob) job).getJobId()); + } + + public void StartJob(AWsJob job) + { + if (!(job instanceof MsaWSJob)) + { + throw new Error("StartJob(MsaWSJob) called on a WSJobInstance " + + job.getClass()); + } + MsaWSJob j = (MsaWSJob) job; + if (j.isSubmitted()) + { + if (Cache.log.isDebugEnabled()) + { + Cache.log.debug("Tried to submit an already submitted job " + + j.getJobId()); + } + return; + } + if (j.seqs.getSeqs() == null) + { + // special case - selection consisted entirely of empty sequences... + j.setSubmitted(true); + j.result = new MsaResult(); + j.result.setFinished(true); + j.result.setStatus("Empty Alignment Job"); + ((MsaResult) j.result).setMsa(null); + } + try + { + vamsas.objects.simple.WsJobId jobsubmit = server.align(j.seqs); + + if ((jobsubmit != null) && (jobsubmit.getStatus() == 1)) + { + j.setJobId(jobsubmit.getJobId()); + j.setSubmitted(true); + j.setSubjobComplete(false); + // 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"); + j.setAllowedServerExceptions(0); + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR); + wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_SERVERERROR); + wsInfo + .appendProgressText( + j.getJobnum(), + "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 + } + } + + private jalview.datamodel.Sequence[] getVamsasAlignment( + vamsas.objects.simple.Alignment valign) + { + // TODO: refactor to helper class for vamsas.objects.simple objects + 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 < j; i++) + { + msa[i] = new jalview.datamodel.Sequence(seqs[i].getId(), seqs[i] + .getSeq()); + } + + return msa; + } + + public void parseResult() + { + int results = 0; // number of result sets received + JobStateSummary finalState = new JobStateSummary(); + try + { + for (int j = 0; j < jobs.length; j++) + { + finalState.updateJobPanelState(wsInfo, OutputHeader, jobs[j]); + if (jobs[j].isSubmitted() && jobs[j].isSubjobComplete() + && jobs[j].hasResults()) + { + results++; + vamsas.objects.simple.Alignment valign = ((MsaResult)((MsaWSJob) jobs[j]).result) + .getMsa(); + if (valign != null) + { + wsInfo.appendProgressText(jobs[j].getJobnum(), + "\nAlignment Object Method Notes\n"); + String[] lines = valign.getMethod(); + for (int line = 0; line < lines.length; line++) + { + wsInfo.appendProgressText(jobs[j].getJobnum(), lines[line] + "\n"); + } + // JBPNote The returned files from a webservice could be + // hidden behind icons in the monitor window that, + // when clicked, pop up their corresponding data + } + } + } + } catch (Exception ex) + { + + Cache.log.error("Unexpected exception when processing results for " + + alTitle, ex); + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); + } + if (results > 0) + { + wsInfo.showResultsNewFrame + .addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + displayResults(true); + } + }); + wsInfo.mergeResults + .addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + displayResults(false); + } + }); + wsInfo.setResultsReady(); + } + else + { + wsInfo.setFinishedNoResults(); + } + } + + void displayResults(boolean newFrame) + { + // view input or result data for each block + Vector alorders = new Vector(); + SequenceI[][] results = new SequenceI[jobs.length][]; + AlignmentOrder[] orders = new AlignmentOrder[jobs.length]; + for (int j = 0; j < jobs.length; j++) + { + if (jobs[j].hasResults()) + { + Object[] res = ((MsaWSJob) jobs[j]).getAlignment(); + alorders.add(res[1]); + results[j] = (SequenceI[]) res[0]; + orders[j] = (AlignmentOrder) res[1]; + + // SequenceI[] alignment = input.getUpdated + } + else + { + results[j] = null; + } + } + Object[] newview = input.getUpdatedView(results, orders, getGapChar()); + // trash references to original result data + for (int j = 0; j < jobs.length; j++) + { + results[j] = null; + orders[j] = null; + } + SequenceI[] alignment = (SequenceI[]) newview[0]; + ColumnSelection columnselection = (ColumnSelection) newview[1]; + Alignment al = new Alignment(alignment); + // TODO: add 'provenance' property to alignment from the method notes + // accompanying each subjob + if (dataset != null) + { + al.setDataset(dataset); + } + + propagateDatasetMappings(al); + // JBNote- TODO: warn user if a block is input rather than aligned data ? + + if (newFrame) + { + AlignFrame af = new AlignFrame(al, columnselection, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + + // initialise with same renderer settings as in parent alignframe. + af.getFeatureRenderer().transferSettings(this.featureSettings); + // update orders + if (alorders.size() > 0) + { + if (alorders.size() == 1) + { + af.addSortByOrderMenuItem(WebServiceName + " Ordering", + (AlignmentOrder) alorders.get(0)); + } + else + { + // construct a non-redundant ordering set + Vector names = new Vector(); + for (int i = 0, l = alorders.size(); i < l; i++) + { + String orderName = new String(" Region " + i); + int j = i + 1; + + while (j < l) + { + if (((AlignmentOrder) alorders.get(i)) + .equals(((AlignmentOrder) alorders.get(j)))) + { + alorders.remove(j); + l--; + orderName += "," + j; + } + else + { + j++; + } + } + + if (i == 0 && j == 1) + { + names.add(new String("")); + } + else + { + names.add(orderName); + } + } + for (int i = 0, l = alorders.size(); i < l; i++) + { + af.addSortByOrderMenuItem(WebServiceName + + ((String) names.get(i)) + " Ordering", + (AlignmentOrder) alorders.get(i)); + } + } + } + + Desktop.addInternalFrame(af, alTitle, AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + + } + else + { + System.out.println("MERGE WITH OLD FRAME"); + // TODO: modify alignment in original frame, replacing old for new + // alignment using the commands.EditCommand model to ensure the update can + // be undone + } + } + + public boolean canMergeResults() + { + return false; + } +} diff --git a/src/jalview/ws/SeqSearchWSClient.java b/src/jalview/ws/jws1/SeqSearchWSClient.java similarity index 94% rename from src/jalview/ws/SeqSearchWSClient.java rename to src/jalview/ws/jws1/SeqSearchWSClient.java index fd45209..fe279cf 100644 --- a/src/jalview/ws/SeqSearchWSClient.java +++ b/src/jalview/ws/jws1/SeqSearchWSClient.java @@ -1,315 +1,315 @@ -/* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5) - * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle - * - * This file is part of Jalview. - * - * Jalview 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 3 of the License, or (at your option) any later version. - * - * Jalview 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 Jalview. If not, see . - */ -package jalview.ws; - -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.StringTokenizer; -import java.util.Vector; - -import javax.swing.*; - -import ext.vamsas.*; -import jalview.datamodel.*; -import jalview.gui.*; - -/** - * DOCUMENT ME! - * - * @author $author$ - * @version $Revision$ - */ -public class SeqSearchWSClient extends WS1Client -{ - /** - * server is a WSDL2Java generated stub for an archetypal MsaWSI service. - */ - ext.vamsas.SeqSearchI server; - - AlignFrame alignFrame; - - /** - * Creates a new MsaWSClient object that uses a service given by an externally - * retrieved ServiceHandle - * - * @param sh - * service handle of type AbstractName(MsaWS) - * @param altitle - * DOCUMENT ME! - * @param msa - * DOCUMENT ME! - * @param submitGaps - * DOCUMENT ME! - * @param preserveOrder - * DOCUMENT ME! - */ - - public SeqSearchWSClient(ext.vamsas.ServiceHandle sh, String altitle, - jalview.datamodel.AlignmentView msa, String db, - Alignment seqdataset, AlignFrame _alignFrame) - { - super(); - alignFrame = _alignFrame; - // can generalise the two errors below for metadata mapping from interface - // name to service client name - if (!sh.getAbstractName().equals(this.getServiceActionKey())) - { - JOptionPane.showMessageDialog(Desktop.desktop, - "The Service called \n" + sh.getName() - + "\nis not a \nSequence Search Service !", - "Internal Jalview Error", JOptionPane.WARNING_MESSAGE); - - return; - } - - if ((wsInfo = setWebService(sh)) == null) - { - JOptionPane.showMessageDialog(Desktop.desktop, - "The Sequence Search Service named " + sh.getName() - + " is unknown", "Internal Jalview Error", - JOptionPane.WARNING_MESSAGE); - - return; - } - startSeqSearchClient(altitle, msa, db, seqdataset); - - } - - /** - * non-process web service interaction - use this for calling HEADLESS - * synchronous service methods - * - * @param sh - */ - public SeqSearchWSClient(ServiceHandle sh) - { - setWebService(sh, true); - } - - public SeqSearchWSClient() - { - - super(); - // add a class reference to the list - } - - private void startSeqSearchClient(String altitle, AlignmentView msa, - String db, Alignment seqdataset) - { - if (!locateWebService()) - { - return; - } - String visdb = (db == null || db == "") ? "default" : db; // need a visible - // name for a - // sequence db - boolean profileSearch = msa.getSequences().length > 2 ? true : false; - // single sequence or profile from alignment view - wsInfo.setProgressText("Searching " - + visdb - + (!profileSearch ? " with sequence " - + msa.getSequences()[0].getRefSeq().getName() - : " with profile") + " from " + altitle - + "\nJob details\n"); - - String jobtitle = WebServiceName - + ((WebServiceName.indexOf("earch") > -1) ? " " : " search ") - + " of " - + visdb - + (!profileSearch ? " with sequence " - + msa.getSequences()[0].getRefSeq().getName() - : " with profile") + " from " + altitle; - SeqSearchWSThread ssthread = new SeqSearchWSThread(server, WsURL, - wsInfo, alignFrame, WebServiceName, jobtitle, msa, db, - seqdataset); - wsInfo.setthisService(ssthread); - ssthread.start(); - } - - /** - * Initializes the server field with a valid service implementation. - * - * @return true if service was located. - */ - private boolean locateWebService() - { - // this can be abstracted using reflection - // TODO: MuscleWS transmuted to generic MsaWS client - SeqSearchServiceLocator loc = new SeqSearchServiceLocator(); // Default - - try - { - this.server = (SeqSearchI) loc.getSeqSearchService(new java.net.URL( - WsURL)); - ((SeqSearchServiceSoapBindingStub) 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(WebserviceInfo.ERROR); - ex.printStackTrace(); - - return false; - } - - loc.getEngine().setOption("axis", "1"); - - return true; - } - - protected String getServiceActionKey() - { - return "SeqSearch"; - } - - protected String getServiceActionDescription() - { - return "Sequence Database Search"; - } - - // simple caching of db parameters for each service endpoint - private static Hashtable dbParamsForEndpoint; - static - { - dbParamsForEndpoint = new Hashtable(); - } - - public String[] getSupportedDatabases() throws Exception - { - - // check that we haven't already been to this service endpoint - if (dbParamsForEndpoint.containsKey(WsURL)) - { - return (String[]) dbParamsForEndpoint.get(WsURL); - } - if (!locateWebService()) - { - throw new Exception("Cannot contact service endpoint at " + WsURL); - } - String database = server.getDatabase(); - if (database == null) - { - dbParamsForEndpoint.put(WsURL, new String[] - {}); - return null; - } - StringTokenizer en = new StringTokenizer(database.trim(), ",| "); - String[] dbs = new String[en.countTokens()]; - for (int i = 0; i < dbs.length; i++) - { - dbs[i++] = en.nextToken().trim(); - } - dbParamsForEndpoint.put(WsURL, dbs); - return dbs; - } - - public void attachWSMenuEntry(JMenu wsmenu, final ServiceHandle sh, - final AlignFrame af) - { - // look for existing database service submenus on wsmenu - Hashtable dbsrchs = new Hashtable(); - Vector newdbsrch = new Vector(); - Component entries[] = wsmenu.getComponents(); - for (int i = 0; entries != null && i < entries.length; i++) - { - if (entries[i] instanceof JMenu) - { - dbsrchs.put(entries[i].getName(), entries[i]); - } - } - JMenu defmenu = (JMenu) dbsrchs.get("Default Database"); - if (defmenu == null) - { - dbsrchs.put("Default Database", defmenu = new JMenu( - "Default Database")); - newdbsrch.addElement(defmenu); - } - - String dbs[] = null; - try - { - dbs = new jalview.ws.SeqSearchWSClient(sh).getSupportedDatabases(); - } catch (Exception e) - { - jalview.bin.Cache.log.warn( - "Database list request failed, so disabling SeqSearch Service client " - + sh.getName() + " at " + sh.getEndpointURL(), e); - return; - } - JMenuItem method; - // do default entry - defmenu.add(method = new JMenuItem(sh.getName())); - method.setToolTipText(sh.getEndpointURL()); - method.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - // use same input gatherer as for secondary structure prediction - // we could actually parameterise the gatherer method here... - AlignmentView msa = af.gatherSeqOrMsaForSecStrPrediction(); - new jalview.ws.SeqSearchWSClient(sh, af.getTitle(), msa, null, af - .getViewport().getAlignment().getDataset(), af); - } - }); - // add entry for each database the service supports - for (int db = 0; dbs != null && db < dbs.length; db++) - { - JMenu dbmenu = (JMenu) dbsrchs.get(dbs[db]); - if (dbmenu == null) - { - dbsrchs.put(dbs[db], dbmenu = new JMenu(dbs[db])); - newdbsrch.addElement(dbmenu); - } - // add the client handler code for this service - dbmenu.add(method = new JMenuItem(sh.getName())); - method.setToolTipText(sh.getEndpointURL()); - final String searchdb = dbs[db]; - method.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - AlignmentView msa = af.gatherSeqOrMsaForSecStrPrediction(); - new jalview.ws.SeqSearchWSClient(sh, af.getTitle(), msa, - searchdb, af.getViewport().getAlignment().getDataset(), - af); - } - }); - } - // add the databases onto the seqsearch menu - Enumeration e = newdbsrch.elements(); - while (e.hasMoreElements()) - { - Object el = e.nextElement(); - if (el instanceof JMenu) - { - wsmenu.add((JMenu) el); - } - else - { - wsmenu.add((JMenuItem) el); - } - } - - } -} +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5) + * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle + * + * This file is part of Jalview. + * + * Jalview 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 3 of the License, or (at your option) any later version. + * + * Jalview 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 Jalview. If not, see . + */ +package jalview.ws.jws1; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Vector; + +import javax.swing.*; + +import ext.vamsas.*; +import jalview.datamodel.*; +import jalview.gui.*; + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ +public class SeqSearchWSClient extends WS1Client +{ + /** + * server is a WSDL2Java generated stub for an archetypal MsaWSI service. + */ + ext.vamsas.SeqSearchI server; + + AlignFrame alignFrame; + + /** + * Creates a new MsaWSClient object that uses a service given by an externally + * retrieved ServiceHandle + * + * @param sh + * service handle of type AbstractName(MsaWS) + * @param altitle + * DOCUMENT ME! + * @param msa + * DOCUMENT ME! + * @param submitGaps + * DOCUMENT ME! + * @param preserveOrder + * DOCUMENT ME! + */ + + public SeqSearchWSClient(ext.vamsas.ServiceHandle sh, String altitle, + jalview.datamodel.AlignmentView msa, String db, + Alignment seqdataset, AlignFrame _alignFrame) + { + super(); + alignFrame = _alignFrame; + // can generalise the two errors below for metadata mapping from interface + // name to service client name + if (!sh.getAbstractName().equals(this.getServiceActionKey())) + { + JOptionPane.showMessageDialog(Desktop.desktop, + "The Service called \n" + sh.getName() + + "\nis not a \nSequence Search Service !", + "Internal Jalview Error", JOptionPane.WARNING_MESSAGE); + + return; + } + + if ((wsInfo = setWebService(sh)) == null) + { + JOptionPane.showMessageDialog(Desktop.desktop, + "The Sequence Search Service named " + sh.getName() + + " is unknown", "Internal Jalview Error", + JOptionPane.WARNING_MESSAGE); + + return; + } + startSeqSearchClient(altitle, msa, db, seqdataset); + + } + + /** + * non-process web service interaction - use this for calling HEADLESS + * synchronous service methods + * + * @param sh + */ + public SeqSearchWSClient(ServiceHandle sh) + { + setWebService(sh, true); + } + + public SeqSearchWSClient() + { + + super(); + // add a class reference to the list + } + + private void startSeqSearchClient(String altitle, AlignmentView msa, + String db, Alignment seqdataset) + { + if (!locateWebService()) + { + return; + } + String visdb = (db == null || db == "") ? "default" : db; // need a visible + // name for a + // sequence db + boolean profileSearch = msa.getSequences().length > 2 ? true : false; + // single sequence or profile from alignment view + wsInfo.setProgressText("Searching " + + visdb + + (!profileSearch ? " with sequence " + + msa.getSequences()[0].getRefSeq().getName() + : " with profile") + " from " + altitle + + "\nJob details\n"); + + String jobtitle = WebServiceName + + ((WebServiceName.indexOf("earch") > -1) ? " " : " search ") + + " of " + + visdb + + (!profileSearch ? " with sequence " + + msa.getSequences()[0].getRefSeq().getName() + : " with profile") + " from " + altitle; + SeqSearchWSThread ssthread = new SeqSearchWSThread(server, WsURL, + wsInfo, alignFrame, WebServiceName, jobtitle, msa, db, + seqdataset); + wsInfo.setthisService(ssthread); + ssthread.start(); + } + + /** + * Initializes the server field with a valid service implementation. + * + * @return true if service was located. + */ + private boolean locateWebService() + { + // this can be abstracted using reflection + // TODO: MuscleWS transmuted to generic MsaWS client + SeqSearchServiceLocator loc = new SeqSearchServiceLocator(); // Default + + try + { + this.server = (SeqSearchI) loc.getSeqSearchService(new java.net.URL( + WsURL)); + ((SeqSearchServiceSoapBindingStub) 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(WebserviceInfo.ERROR); + ex.printStackTrace(); + + return false; + } + + loc.getEngine().setOption("axis", "1"); + + return true; + } + + protected String getServiceActionKey() + { + return "SeqSearch"; + } + + protected String getServiceActionDescription() + { + return "Sequence Database Search"; + } + + // simple caching of db parameters for each service endpoint + private static Hashtable dbParamsForEndpoint; + static + { + dbParamsForEndpoint = new Hashtable(); + } + + public String[] getSupportedDatabases() throws Exception + { + + // check that we haven't already been to this service endpoint + if (dbParamsForEndpoint.containsKey(WsURL)) + { + return (String[]) dbParamsForEndpoint.get(WsURL); + } + if (!locateWebService()) + { + throw new Exception("Cannot contact service endpoint at " + WsURL); + } + String database = server.getDatabase(); + if (database == null) + { + dbParamsForEndpoint.put(WsURL, new String[] + {}); + return null; + } + StringTokenizer en = new StringTokenizer(database.trim(), ",| "); + String[] dbs = new String[en.countTokens()]; + for (int i = 0; i < dbs.length; i++) + { + dbs[i++] = en.nextToken().trim(); + } + dbParamsForEndpoint.put(WsURL, dbs); + return dbs; + } + + public void attachWSMenuEntry(JMenu wsmenu, final ServiceHandle sh, + final AlignFrame af) + { + // look for existing database service submenus on wsmenu + Hashtable dbsrchs = new Hashtable(); + Vector newdbsrch = new Vector(); + Component entries[] = wsmenu.getComponents(); + for (int i = 0; entries != null && i < entries.length; i++) + { + if (entries[i] instanceof JMenu) + { + dbsrchs.put(entries[i].getName(), entries[i]); + } + } + JMenu defmenu = (JMenu) dbsrchs.get("Default Database"); + if (defmenu == null) + { + dbsrchs.put("Default Database", defmenu = new JMenu( + "Default Database")); + newdbsrch.addElement(defmenu); + } + + String dbs[] = null; + try + { + dbs = new jalview.ws.jws1.SeqSearchWSClient(sh).getSupportedDatabases(); + } catch (Exception e) + { + jalview.bin.Cache.log.warn( + "Database list request failed, so disabling SeqSearch Service client " + + sh.getName() + " at " + sh.getEndpointURL(), e); + return; + } + JMenuItem method; + // do default entry + defmenu.add(method = new JMenuItem(sh.getName())); + method.setToolTipText(sh.getEndpointURL()); + method.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + // use same input gatherer as for secondary structure prediction + // we could actually parameterise the gatherer method here... + AlignmentView msa = af.gatherSeqOrMsaForSecStrPrediction(); + new jalview.ws.jws1.SeqSearchWSClient(sh, af.getTitle(), msa, null, af + .getViewport().getAlignment().getDataset(), af); + } + }); + // add entry for each database the service supports + for (int db = 0; dbs != null && db < dbs.length; db++) + { + JMenu dbmenu = (JMenu) dbsrchs.get(dbs[db]); + if (dbmenu == null) + { + dbsrchs.put(dbs[db], dbmenu = new JMenu(dbs[db])); + newdbsrch.addElement(dbmenu); + } + // add the client handler code for this service + dbmenu.add(method = new JMenuItem(sh.getName())); + method.setToolTipText(sh.getEndpointURL()); + final String searchdb = dbs[db]; + method.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + AlignmentView msa = af.gatherSeqOrMsaForSecStrPrediction(); + new jalview.ws.jws1.SeqSearchWSClient(sh, af.getTitle(), msa, + searchdb, af.getViewport().getAlignment().getDataset(), + af); + } + }); + } + // add the databases onto the seqsearch menu + Enumeration e = newdbsrch.elements(); + while (e.hasMoreElements()) + { + Object el = e.nextElement(); + if (el instanceof JMenu) + { + wsmenu.add((JMenu) el); + } + else + { + wsmenu.add((JMenuItem) el); + } + } + + } +} diff --git a/src/jalview/ws/SeqSearchWSThread.java b/src/jalview/ws/jws1/SeqSearchWSThread.java similarity index 92% rename from src/jalview/ws/SeqSearchWSThread.java rename to src/jalview/ws/jws1/SeqSearchWSThread.java index 550ae43..259a0b9 100644 --- a/src/jalview/ws/SeqSearchWSThread.java +++ b/src/jalview/ws/jws1/SeqSearchWSThread.java @@ -1,678 +1,681 @@ -/* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5) - * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle - * - * This file is part of Jalview. - * - * Jalview 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 3 of the License, or (at your option) any later version. - * - * Jalview 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 Jalview. If not, see . - */ -package jalview.ws; - -import java.util.*; - -import jalview.analysis.*; -import jalview.bin.*; -import jalview.datamodel.*; -import jalview.gui.*; -import jalview.io.NewickFile; -import vamsas.objects.simple.MsaResult; -import vamsas.objects.simple.SeqSearchResult; - -/** - *

- * Title: - *

- * - *

- * Description: - *

- * - *

- * Copyright: Copyright (c) 2004 - *

- * - *

- * Company: Dundee University - *

- * - * @author not attributable - * @version 1.0 - */ -class SeqSearchWSThread extends JWS1Thread implements WSClientI -{ - String dbs = null; - - boolean profile = false; - - class SeqSearchWSJob extends WSJob - { - // hold special input for this - vamsas.objects.simple.SequenceSet seqs = new vamsas.objects.simple.SequenceSet(); - - /** - * MsaWSJob - * - * @param jobNum - * int - * @param jobId - * String - */ - public SeqSearchWSJob(int jobNum, SequenceI[] inSeqs) - { - this.jobnum = jobNum; - if (!prepareInput(inSeqs, 2)) - { - submitted = true; - subjobComplete = true; - result = new MsaResult(); - result.setFinished(true); - result.setStatus("Job never ran - input returned to user."); - } - - } - - Hashtable SeqNames = new Hashtable(); - - Vector emptySeqs = new Vector(); - - /** - * prepare input sequences for service - * - * @param seqs - * jalview sequences to be prepared - * @param minlen - * minimum number of residues required for this MsaWS service - * @return true if seqs contains sequences to be submitted to service. - */ - private boolean prepareInput(SequenceI[] seqs, int minlen) - { - int nseqs = 0; - if (minlen < 0) - { - throw new Error( - "Implementation error: minlen must be zero or more."); - } - for (int i = 0; i < seqs.length; i++) - { - if (seqs[i].getEnd() - seqs[i].getStart() > minlen - 1) - { - nseqs++; - } - } - boolean valid = nseqs >= 1; // need at least one sequence for valid input - // TODO: generalise - vamsas.objects.simple.Sequence[] seqarray = (valid) ? new vamsas.objects.simple.Sequence[nseqs] - : null; - boolean submitGaps = (nseqs == 1) ? false : true; // profile is submitted - // with gaps - for (int i = 0, n = 0; i < seqs.length; i++) - { - - String newname = jalview.analysis.SeqsetUtils.unique_name(i); // same - // for - // any - // subjob - SeqNames.put(newname, jalview.analysis.SeqsetUtils - .SeqCharacterHash(seqs[i])); - if (valid && seqs[i].getEnd() - seqs[i].getStart() > minlen - 1) - { - seqarray[n] = new vamsas.objects.simple.Sequence(); - seqarray[n].setId(newname); - seqarray[n++].setSeq((submitGaps) ? seqs[i].getSequenceAsString() - : AlignSeq.extractGaps(jalview.util.Comparison.GapChars, - seqs[i].getSequenceAsString())); - } - else - { - String empty = null; - if (seqs[i].getEnd() >= seqs[i].getStart()) - { - empty = (submitGaps) ? seqs[i].getSequenceAsString() : AlignSeq - .extractGaps(jalview.util.Comparison.GapChars, seqs[i] - .getSequenceAsString()); - } - emptySeqs.add(new String[] - { newname, empty }); - } - } - if (submitGaps) - { - // almost certainly have to remove gapped columns here - } - this.seqs = new vamsas.objects.simple.SequenceSet(); - this.seqs.setSeqs(seqarray); - return valid; - } - - /** - * - * @return true if getAlignment will return a valid alignment result. - */ - public boolean hasResults() - { - if (subjobComplete - && result != null - && result.isFinished() - && ((SeqSearchResult) result).getAlignment() != null - && ((SeqSearchResult) result).getAlignment().getSeqs() != null) - { - return true; - } - return false; - } - - /** - * return sequence search results for display - * - * @return null or { Alignment(+features and annotation), NewickFile)} - */ - public Object[] getAlignment(Alignment dataset, Hashtable featureColours) - { - - if (result != null && result.isFinished()) - { - SequenceI[] alseqs = null; - // char alseq_gapchar = '-'; - // int alseq_l = 0; - if (((SeqSearchResult) result).getAlignment() != null) - { - alseqs = getVamsasAlignment(((SeqSearchResult) result) - .getAlignment()); - // alseq_gapchar = ( (SeqSearchResult) - // result).getAlignment().getGapchar().charAt(0); - // alseq_l = alseqs.length; - } - /** - * what has to be done. 1 - annotate returned alignment with annotation - * file and sequence features file, and associate any tree-nodes. 2. - * connect alignment back to any associated dataset: 2.a. deuniquify - * recovers sequence information - but additionally, relocations must be - * made from the returned aligned sequence back to the dataset. - */ - // construct annotated alignment as it would be done by the jalview - // applet - jalview.datamodel.Alignment al = new Alignment(alseqs); - // al.setDataset(dataset); - // make dataset - String inFile = null; - try - { - inFile = ((SeqSearchResult) result).getAnnotation(); - if (inFile != null && inFile.length() > 0) - { - new jalview.io.AnnotationFile().readAnnotationFile(al, inFile, - jalview.io.AppletFormatAdapter.PASTE); - } - } catch (Exception e) - { - System.err - .println("Failed to parse the annotation file associated with the alignment."); - System.err.println(">>>EOF" + inFile + "\n<< 0) - { - jalview.io.FeaturesFile ff = new jalview.io.FeaturesFile( - inFile, jalview.io.AppletFormatAdapter.PASTE); - ff.parse(al, featureColours, false); - } - } catch (Exception e) - { - System.err - .println("Failed to parse the Features file associated with the alignment."); - System.err.println(">>>EOF" + inFile + "\n<< 0) - { - nf = new jalview.io.NewickFile(inFile, - jalview.io.AppletFormatAdapter.PASTE); - if (!nf.isValid()) - { - nf.close(); - nf = null; - } - } - } catch (Exception e) - { - System.err - .println("Failed to parse the treeFile associated with the alignment."); - System.err.println(">>>EOF" + inFile + "\n<< 0) - { - wsinfo - .setProgressName("region " + jobs[j].jobnum, - jobs[j].jobnum); - } - wsinfo.setProgressText(jobs[j].jobnum, OutputHeader); - } - } - } - - public boolean isCancellable() - { - return true; - } - - public void cancelJob() - { - if (!jobComplete && jobs != null) - { - boolean cancelled = true; - for (int job = 0; job < jobs.length; job++) - { - if (jobs[job].submitted && !jobs[job].subjobComplete) - { - String cancelledMessage = ""; - try - { - vamsas.objects.simple.WsJobId cancelledJob = server - .cancel(jobs[job].jobId); - if (cancelledJob.getStatus() == 2) - { - // CANCELLED_JOB - cancelledMessage = "Job cancelled."; - ((SeqSearchWSJob) jobs[job]).cancel(); - wsInfo.setStatus(jobs[job].jobnum, - WebserviceInfo.STATE_CANCELLED_OK); - } - else if (cancelledJob.getStatus() == 3) - { - // VALID UNSTOPPABLE JOB - cancelledMessage += "Server cannot cancel this job. just close the window.\n"; - cancelled = false; - // wsInfo.setStatus(jobs[job].jobnum, - // WebserviceInfo.STATE_RUNNING); - } - - if (cancelledJob.getJobId() != null) - { - cancelledMessage += ("[" + cancelledJob.getJobId() + "]"); - } - - cancelledMessage += "\n"; - } catch (Exception exc) - { - cancelledMessage += ("\nProblems cancelling the job : Exception received...\n" - + exc + "\n"); - Cache.log.warn( - "Exception whilst cancelling " + jobs[job].jobId, exc); - } - wsInfo.setProgressText(jobs[job].jobnum, OutputHeader - + cancelledMessage + "\n"); - } - } - if (cancelled) - { - wsInfo.setStatus(WebserviceInfo.STATE_CANCELLED_OK); - jobComplete = true; - } - this.interrupt(); // kick thread to update job states. - } - else - { - if (!jobComplete) - { - wsInfo - .setProgressText(OutputHeader - + "Server cannot cancel this job because it has not been submitted properly. just close the window.\n"); - } - } - } - - public void pollJob(AWsJob job) throws Exception - { - ((SeqSearchWSJob) job).result = server - .getResult(((SeqSearchWSJob) job).jobId); - } - - public void StartJob(AWsJob job) - { - if (!(job instanceof SeqSearchWSJob)) - { - throw new Error("StartJob(MsaWSJob) called on a WSJobInstance " - + job.getClass()); - } - SeqSearchWSJob j = (SeqSearchWSJob) job; - if (j.submitted) - { - if (Cache.log.isDebugEnabled()) - { - Cache.log.debug("Tried to submit an already submitted job " - + j.jobId); - } - return; - } - if (j.seqs.getSeqs() == null) - { - // special case - selection consisted entirely of empty sequences... - j.submitted = true; - j.result = new MsaResult(); - j.result.setFinished(true); - j.result.setStatus("Empty Alignment Job"); - ((MsaResult) j.result).setMsa(null); - } - try - { - vamsas.objects.simple.WsJobId jobsubmit = server.search(j.seqs - .getSeqs()[0], dbArg); - - if ((jobsubmit != null) && (jobsubmit.getStatus() == 1)) - { - j.jobId = jobsubmit.getJobId(); - j.submitted = true; - j.subjobComplete = false; - // 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"); - j.allowedServerExceptions = 0; - wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR); - wsInfo.setStatus(j.jobnum, WebserviceInfo.STATE_STOPPED_SERVERERROR); - wsInfo - .appendProgressText( - j.jobnum, - "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 - } - } - - 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 < j; i++) - { - msa[i] = new jalview.datamodel.Sequence(seqs[i].getId(), seqs[i] - .getSeq()); - } - - return msa; - } - - public void parseResult() - { - int results = 0; // number of result sets received - JobStateSummary finalState = new JobStateSummary(); - try - { - for (int j = 0; j < jobs.length; j++) - { - finalState.updateJobPanelState(wsInfo, OutputHeader, jobs[j]); - if (jobs[j].submitted && jobs[j].subjobComplete - && jobs[j].hasResults()) - { - results++; - vamsas.objects.simple.Alignment valign = ((SeqSearchResult) ((SeqSearchWSJob)jobs[j]).result) - .getAlignment(); - if (valign != null) - { - wsInfo.appendProgressText(jobs[j].jobnum, - "\nAlignment Object Method Notes\n"); - String[] lines = valign.getMethod(); - for (int line = 0; line < lines.length; line++) - { - wsInfo.appendProgressText(jobs[j].jobnum, lines[line] + "\n"); - } - // JBPNote The returned files from a webservice could be - // hidden behind icons in the monitor window that, - // when clicked, pop up their corresponding data - } - } - } - } catch (Exception ex) - { - - Cache.log.error("Unexpected exception when processing results for " - + alTitle, ex); - wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); - } - if (results > 0) - { - wsInfo.showResultsNewFrame - .addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(java.awt.event.ActionEvent evt) - { - displayResults(true); - } - }); - wsInfo.mergeResults - .addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(java.awt.event.ActionEvent evt) - { - displayResults(false); - } - }); - wsInfo.setResultsReady(); - } - else - { - wsInfo.setFinishedNoResults(); - } - } - - void displayResults(boolean newFrame) - { - if (!newFrame) - { - System.err.println("MERGE WITH OLD FRAME NOT IMPLEMENTED"); - return; - } - // each subjob is an independent alignment for the moment - // Alignment al[] = new Alignment[jobs.length]; - // NewickFile nf[] = new NewickFile[jobs.length]; - for (int j = 0; j < jobs.length; j++) - { - Hashtable featureColours = new Hashtable(); - Alignment al = null; - NewickFile nf = null; - if (jobs[j].hasResults()) - { - Object[] res = ((SeqSearchWSJob) jobs[j]).getAlignment(dataset, - featureColours); - if (res == null) - { - continue; - } - ; - al = (Alignment) res[0]; - nf = (NewickFile) res[1]; - } - else - { - al = null; - nf = null; - continue; - } - /* - * We can't map new alignment back with insertions from input's hidden - * regions until dataset mapping is sorted out... but basically it goes - * like this: 1. Merge each domain hit back onto the visible segments in - * the same way as a Jnet prediction is mapped back - * - * Object[] newview = input.getUpdatedView(results, orders, getGapChar()); - * // trash references to original result data for (int j = 0; j < - * jobs.length; j++) { results[j] = null; orders[j] = null; } SequenceI[] - * alignment = (SequenceI[]) newview[0]; ColumnSelection columnselection = - * (ColumnSelection) newview[1]; Alignment al = new Alignment(alignment); - * - * if (dataset != null) { al.setDataset(dataset); } - * - * propagateDatasetMappings(al); } - */ - - AlignFrame af = new AlignFrame(al,// columnselection, - AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); - if (nf != null) - { - af.ShowNewickTree(nf, "Tree from " + this.alTitle); - } - // initialise with same renderer settings as in parent alignframe. - af.getFeatureRenderer().transferSettings(this.featureSettings); - Desktop.addInternalFrame(af, alTitle, AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT); - } - } - - public boolean canMergeResults() - { - return false; - } -} +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5) + * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle + * + * This file is part of Jalview. + * + * Jalview 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 3 of the License, or (at your option) any later version. + * + * Jalview 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 Jalview. If not, see . + */ +package jalview.ws.jws1; + +import java.util.*; + +import jalview.analysis.*; +import jalview.bin.*; +import jalview.datamodel.*; +import jalview.gui.*; +import jalview.io.NewickFile; +import jalview.ws.AWsJob; +import jalview.ws.JobStateSummary; +import jalview.ws.WSClientI; +import vamsas.objects.simple.MsaResult; +import vamsas.objects.simple.SeqSearchResult; + +/** + *

+ * Title: + *

+ * + *

+ * Description: + *

+ * + *

+ * Copyright: Copyright (c) 2004 + *

+ * + *

+ * Company: Dundee University + *

+ * + * @author not attributable + * @version 1.0 + */ +class SeqSearchWSThread extends JWS1Thread implements WSClientI +{ + String dbs = null; + + boolean profile = false; + + class SeqSearchWSJob extends WSJob + { + // hold special input for this + vamsas.objects.simple.SequenceSet seqs = new vamsas.objects.simple.SequenceSet(); + + /** + * MsaWSJob + * + * @param jobNum + * int + * @param jobId + * String + */ + public SeqSearchWSJob(int jobNum, SequenceI[] inSeqs) + { + this.jobnum = jobNum; + if (!prepareInput(inSeqs, 2)) + { + submitted = true; + subjobComplete = true; + result = new MsaResult(); + result.setFinished(true); + result.setStatus("Job never ran - input returned to user."); + } + + } + + Hashtable SeqNames = new Hashtable(); + + Vector emptySeqs = new Vector(); + + /** + * prepare input sequences for service + * + * @param seqs + * jalview sequences to be prepared + * @param minlen + * minimum number of residues required for this MsaWS service + * @return true if seqs contains sequences to be submitted to service. + */ + private boolean prepareInput(SequenceI[] seqs, int minlen) + { + int nseqs = 0; + if (minlen < 0) + { + throw new Error( + "Implementation error: minlen must be zero or more."); + } + for (int i = 0; i < seqs.length; i++) + { + if (seqs[i].getEnd() - seqs[i].getStart() > minlen - 1) + { + nseqs++; + } + } + boolean valid = nseqs >= 1; // need at least one sequence for valid input + // TODO: generalise + vamsas.objects.simple.Sequence[] seqarray = (valid) ? new vamsas.objects.simple.Sequence[nseqs] + : null; + boolean submitGaps = (nseqs == 1) ? false : true; // profile is submitted + // with gaps + for (int i = 0, n = 0; i < seqs.length; i++) + { + + String newname = jalview.analysis.SeqsetUtils.unique_name(i); // same + // for + // any + // subjob + SeqNames.put(newname, jalview.analysis.SeqsetUtils + .SeqCharacterHash(seqs[i])); + if (valid && seqs[i].getEnd() - seqs[i].getStart() > minlen - 1) + { + seqarray[n] = new vamsas.objects.simple.Sequence(); + seqarray[n].setId(newname); + seqarray[n++].setSeq((submitGaps) ? seqs[i].getSequenceAsString() + : AlignSeq.extractGaps(jalview.util.Comparison.GapChars, + seqs[i].getSequenceAsString())); + } + else + { + String empty = null; + if (seqs[i].getEnd() >= seqs[i].getStart()) + { + empty = (submitGaps) ? seqs[i].getSequenceAsString() : AlignSeq + .extractGaps(jalview.util.Comparison.GapChars, seqs[i] + .getSequenceAsString()); + } + emptySeqs.add(new String[] + { newname, empty }); + } + } + if (submitGaps) + { + // almost certainly have to remove gapped columns here + } + this.seqs = new vamsas.objects.simple.SequenceSet(); + this.seqs.setSeqs(seqarray); + return valid; + } + + /** + * + * @return true if getAlignment will return a valid alignment result. + */ + public boolean hasResults() + { + if (subjobComplete + && result != null + && result.isFinished() + && ((SeqSearchResult) result).getAlignment() != null + && ((SeqSearchResult) result).getAlignment().getSeqs() != null) + { + return true; + } + return false; + } + + /** + * return sequence search results for display + * + * @return null or { Alignment(+features and annotation), NewickFile)} + */ + public Object[] getAlignment(Alignment dataset, Hashtable featureColours) + { + + if (result != null && result.isFinished()) + { + SequenceI[] alseqs = null; + // char alseq_gapchar = '-'; + // int alseq_l = 0; + if (((SeqSearchResult) result).getAlignment() != null) + { + alseqs = getVamsasAlignment(((SeqSearchResult) result) + .getAlignment()); + // alseq_gapchar = ( (SeqSearchResult) + // result).getAlignment().getGapchar().charAt(0); + // alseq_l = alseqs.length; + } + /** + * what has to be done. 1 - annotate returned alignment with annotation + * file and sequence features file, and associate any tree-nodes. 2. + * connect alignment back to any associated dataset: 2.a. deuniquify + * recovers sequence information - but additionally, relocations must be + * made from the returned aligned sequence back to the dataset. + */ + // construct annotated alignment as it would be done by the jalview + // applet + jalview.datamodel.Alignment al = new Alignment(alseqs); + // al.setDataset(dataset); + // make dataset + String inFile = null; + try + { + inFile = ((SeqSearchResult) result).getAnnotation(); + if (inFile != null && inFile.length() > 0) + { + new jalview.io.AnnotationFile().readAnnotationFile(al, inFile, + jalview.io.AppletFormatAdapter.PASTE); + } + } catch (Exception e) + { + System.err + .println("Failed to parse the annotation file associated with the alignment."); + System.err.println(">>>EOF" + inFile + "\n<< 0) + { + jalview.io.FeaturesFile ff = new jalview.io.FeaturesFile( + inFile, jalview.io.AppletFormatAdapter.PASTE); + ff.parse(al, featureColours, false); + } + } catch (Exception e) + { + System.err + .println("Failed to parse the Features file associated with the alignment."); + System.err.println(">>>EOF" + inFile + "\n<< 0) + { + nf = new jalview.io.NewickFile(inFile, + jalview.io.AppletFormatAdapter.PASTE); + if (!nf.isValid()) + { + nf.close(); + nf = null; + } + } + } catch (Exception e) + { + System.err + .println("Failed to parse the treeFile associated with the alignment."); + System.err.println(">>>EOF" + inFile + "\n<< 0) + { + wsinfo + .setProgressName("region " + jobs[j].getJobnum(), + jobs[j].getJobnum()); + } + wsinfo.setProgressText(jobs[j].getJobnum(), OutputHeader); + } + } + } + + public boolean isCancellable() + { + return true; + } + + public void cancelJob() + { + if (!jobComplete && jobs != null) + { + boolean cancelled = true; + for (int job = 0; job < jobs.length; job++) + { + if (jobs[job].isSubmitted() && !jobs[job].isSubjobComplete()) + { + String cancelledMessage = ""; + try + { + vamsas.objects.simple.WsJobId cancelledJob = server + .cancel(jobs[job].getJobId()); + if (cancelledJob.getStatus() == 2) + { + // CANCELLED_JOB + cancelledMessage = "Job cancelled."; + ((SeqSearchWSJob) jobs[job]).cancel(); + wsInfo.setStatus(jobs[job].getJobnum(), + WebserviceInfo.STATE_CANCELLED_OK); + } + else if (cancelledJob.getStatus() == 3) + { + // VALID UNSTOPPABLE JOB + cancelledMessage += "Server cannot cancel this job. just close the window.\n"; + cancelled = false; + // wsInfo.setStatus(jobs[job].jobnum, + // WebserviceInfo.STATE_RUNNING); + } + + if (cancelledJob.getJobId() != null) + { + cancelledMessage += ("[" + cancelledJob.getJobId() + "]"); + } + + cancelledMessage += "\n"; + } catch (Exception exc) + { + cancelledMessage += ("\nProblems cancelling the job : Exception received...\n" + + exc + "\n"); + Cache.log.warn( + "Exception whilst cancelling " + jobs[job].getJobId(), exc); + } + wsInfo.setProgressText(jobs[job].getJobnum(), OutputHeader + + cancelledMessage + "\n"); + } + } + if (cancelled) + { + wsInfo.setStatus(WebserviceInfo.STATE_CANCELLED_OK); + jobComplete = true; + } + this.interrupt(); // kick thread to update job states. + } + else + { + if (!jobComplete) + { + wsInfo + .setProgressText(OutputHeader + + "Server cannot cancel this job because it has not been submitted properly. just close the window.\n"); + } + } + } + + public void pollJob(AWsJob job) throws Exception + { + ((SeqSearchWSJob) job).result = server + .getResult(((SeqSearchWSJob) job).getJobId()); + } + + public void StartJob(AWsJob job) + { + if (!(job instanceof SeqSearchWSJob)) + { + throw new Error("StartJob(MsaWSJob) called on a WSJobInstance " + + job.getClass()); + } + SeqSearchWSJob j = (SeqSearchWSJob) job; + if (j.isSubmitted()) + { + if (Cache.log.isDebugEnabled()) + { + Cache.log.debug("Tried to submit an already submitted job " + + j.getJobId()); + } + return; + } + if (j.seqs.getSeqs() == null) + { + // special case - selection consisted entirely of empty sequences... + j.setSubmitted(true); + j.result = new MsaResult(); + j.result.setFinished(true); + j.result.setStatus("Empty Alignment Job"); + ((MsaResult) j.result).setMsa(null); + } + try + { + vamsas.objects.simple.WsJobId jobsubmit = server.search(j.seqs + .getSeqs()[0], dbArg); + + if ((jobsubmit != null) && (jobsubmit.getStatus() == 1)) + { + j.setJobId(jobsubmit.getJobId()); + j.setSubmitted(true); + j.setSubjobComplete(false); + // 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"); + j.setAllowedServerExceptions(0); + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR); + wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_SERVERERROR); + wsInfo + .appendProgressText( + j.getJobnum(), + "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 + } + } + + 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 < j; i++) + { + msa[i] = new jalview.datamodel.Sequence(seqs[i].getId(), seqs[i] + .getSeq()); + } + + return msa; + } + + public void parseResult() + { + int results = 0; // number of result sets received + JobStateSummary finalState = new JobStateSummary(); + try + { + for (int j = 0; j < jobs.length; j++) + { + finalState.updateJobPanelState(wsInfo, OutputHeader, jobs[j]); + if (jobs[j].isSubmitted() && jobs[j].isSubjobComplete() + && jobs[j].hasResults()) + { + results++; + vamsas.objects.simple.Alignment valign = ((SeqSearchResult) ((SeqSearchWSJob)jobs[j]).result) + .getAlignment(); + if (valign != null) + { + wsInfo.appendProgressText(jobs[j].getJobnum(), + "\nAlignment Object Method Notes\n"); + String[] lines = valign.getMethod(); + for (int line = 0; line < lines.length; line++) + { + wsInfo.appendProgressText(jobs[j].getJobnum(), lines[line] + "\n"); + } + // JBPNote The returned files from a webservice could be + // hidden behind icons in the monitor window that, + // when clicked, pop up their corresponding data + } + } + } + } catch (Exception ex) + { + + Cache.log.error("Unexpected exception when processing results for " + + alTitle, ex); + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); + } + if (results > 0) + { + wsInfo.showResultsNewFrame + .addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + displayResults(true); + } + }); + wsInfo.mergeResults + .addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(java.awt.event.ActionEvent evt) + { + displayResults(false); + } + }); + wsInfo.setResultsReady(); + } + else + { + wsInfo.setFinishedNoResults(); + } + } + + void displayResults(boolean newFrame) + { + if (!newFrame) + { + System.err.println("MERGE WITH OLD FRAME NOT IMPLEMENTED"); + return; + } + // each subjob is an independent alignment for the moment + // Alignment al[] = new Alignment[jobs.length]; + // NewickFile nf[] = new NewickFile[jobs.length]; + for (int j = 0; j < jobs.length; j++) + { + Hashtable featureColours = new Hashtable(); + Alignment al = null; + NewickFile nf = null; + if (jobs[j].hasResults()) + { + Object[] res = ((SeqSearchWSJob) jobs[j]).getAlignment(dataset, + featureColours); + if (res == null) + { + continue; + } + ; + al = (Alignment) res[0]; + nf = (NewickFile) res[1]; + } + else + { + al = null; + nf = null; + continue; + } + /* + * We can't map new alignment back with insertions from input's hidden + * regions until dataset mapping is sorted out... but basically it goes + * like this: 1. Merge each domain hit back onto the visible segments in + * the same way as a Jnet prediction is mapped back + * + * Object[] newview = input.getUpdatedView(results, orders, getGapChar()); + * // trash references to original result data for (int j = 0; j < + * jobs.length; j++) { results[j] = null; orders[j] = null; } SequenceI[] + * alignment = (SequenceI[]) newview[0]; ColumnSelection columnselection = + * (ColumnSelection) newview[1]; Alignment al = new Alignment(alignment); + * + * if (dataset != null) { al.setDataset(dataset); } + * + * propagateDatasetMappings(al); } + */ + + AlignFrame af = new AlignFrame(al,// columnselection, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + if (nf != null) + { + af.ShowNewickTree(nf, "Tree from " + this.alTitle); + } + // initialise with same renderer settings as in parent alignframe. + af.getFeatureRenderer().transferSettings(this.featureSettings); + Desktop.addInternalFrame(af, alTitle, AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + } + } + + public boolean canMergeResults() + { + return false; + } +} diff --git a/src/jalview/ws/WS1Client.java b/src/jalview/ws/jws1/WS1Client.java similarity index 96% rename from src/jalview/ws/WS1Client.java rename to src/jalview/ws/jws1/WS1Client.java index a05bf7f..83ea028 100644 --- a/src/jalview/ws/WS1Client.java +++ b/src/jalview/ws/jws1/WS1Client.java @@ -1,10 +1,12 @@ /** * */ -package jalview.ws; +package jalview.ws.jws1; import jalview.gui.AlignFrame; import jalview.gui.WebserviceInfo; +import jalview.ws.WSClient; +import jalview.ws.WSMenuEntryProviderI; import javax.swing.JMenu; diff --git a/src/jalview/ws/WSJob.java b/src/jalview/ws/jws1/WSJob.java similarity index 97% rename from src/jalview/ws/WSJob.java rename to src/jalview/ws/jws1/WSJob.java index 2a2e315..c2e1bf9 100644 --- a/src/jalview/ws/WSJob.java +++ b/src/jalview/ws/jws1/WSJob.java @@ -1,7 +1,9 @@ /** * */ -package jalview.ws; +package jalview.ws.jws1; + +import jalview.ws.AWsJob; abstract class WSJob extends AWsJob { -- 1.7.10.2