X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fws%2Frest%2FRestJobThread.java;h=c100a72034e0cff84eb0a1433994c0d91bb24767;hb=9659f01c9954d78d03e47aaedb89f6122f2b7142;hp=bd718134eab947ec81b4d103c3d6ceff96e79e28;hpb=6451d24f0987cf8283341750672ba95ee085fc9c;p=jalview.git diff --git a/src/jalview/ws/rest/RestJobThread.java b/src/jalview/ws/rest/RestJobThread.java index bd71813..c100a72 100644 --- a/src/jalview/ws/rest/RestJobThread.java +++ b/src/jalview/ws/rest/RestJobThread.java @@ -2,15 +2,19 @@ package jalview.ws.rest; import jalview.bin.Cache; import jalview.datamodel.AlignmentI; +import jalview.datamodel.ColumnSelection; +import jalview.gui.AlignFrame; import jalview.gui.WebserviceInfo; import jalview.io.packed.DataProvider; import jalview.io.packed.JalviewDataset; +import jalview.io.packed.JalviewDataset.AlignmentSet; import jalview.io.packed.ParsePackedSet; import jalview.io.packed.SimpleDataProvider; import jalview.io.packed.DataProvider.JvDataType; import jalview.ws.AWSThread; import jalview.ws.AWsJob; +import java.awt.Desktop; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; @@ -44,7 +48,8 @@ public class RestJobThread extends AWSThread public RestJobThread(RestClient restClient) { - super(); + super(restClient.af, null, restClient._input, + restClient.service.postUrl); this.restClient = restClient; // may not be needed // Test Code // minimal job - submit given input and parse result onto alignment as @@ -60,13 +65,15 @@ public class RestJobThread extends AWSThread jobs = new RestJob[1]; jobs[0] = new RestJob(0, this, restClient._input.getVisibleAlignment(restClient.service - .getGapCharacter())); + .getGapCharacter()), + restClient._input.getVisibleContigs()); // need a function to get a range on a view/alignment and return both // annotation, groups and selection subsetted to just that region. } else { + int[] viscontig = restClient._input.getVisibleContigs(); AlignmentI[] viscontigals = restClient._input .getVisibleContigAlignments(restClient.service .getGapCharacter()); @@ -75,13 +82,15 @@ public class RestJobThread extends AWSThread jobs = new RestJob[viscontigals.length]; for (int j = 0; j < jobs.length; j++) { + int[] visc = new int[] + { viscontig[j * 2], viscontig[j * 2 + 1] }; if (j != 0) { - jobs[j] = new RestJob(j, this, viscontigals[j]); + jobs[j] = new RestJob(j, this, viscontigals[j], visc); } else { - jobs[j] = new RestJob(0, this, viscontigals[j]); + jobs[j] = new RestJob(0, this, viscontigals[j], visc); } } } @@ -178,7 +187,8 @@ public class RestJobThread extends AWSThread throws Exception { StringBuffer respText = new StringBuffer(); - // con.setContentHandlerFactory(new jalview.ws.io.mime.HttpContentHandler()); + // con.setContentHandlerFactory(new + // jalview.ws.io.mime.HttpContentHandler()); HttpRequestBase request = null; String messages = ""; if (stg == Stage.SUBMIT) @@ -244,8 +254,12 @@ public class RestJobThread extends AWSThread processResultSet(rj, response, request); break; case 202: - rj.statMessage = "Job submitted successfully. Results available at this URL:\n" - + rj.getJobId() + "\n"; + rj.statMessage = "
Job submitted successfully. Results available at this URL:\n" + + "" + + rj.getJobId() + + "
"; rj.running = true; break; case 302: @@ -274,6 +288,7 @@ public class RestJobThread extends AWSThread rj.setAllowedServerExceptions(0); rj.setSubjobComplete(true); rj.error = true; + rj.running = false; completeStatus(rj, response, "" + getStage(stg) + "failed. Reason below:\n"); break; @@ -346,9 +361,24 @@ public class RestJobThread extends AWSThread } HttpEntity en = con.getEntity(); /* - * Just show the content as a string. + * Just append the content as a string. */ - rj.statMessage = EntityUtils.toString(en); + String f; + StringBuffer content = new StringBuffer(f = EntityUtils.toString(en)); + f = f.toLowerCase(); + int body = f.indexOf(" -1) + { + content.delete(0, f.indexOf(">", body)); + } + if (body > -1 && sb.length() > 0) + { + sb.append("\n"); + content.insert(0, sb); + sb = null; + } + f = null; + rj.statMessage = content.toString(); } @Override @@ -379,108 +409,220 @@ public class RestJobThread extends AWSThread public void parseResult() { // crazy users will see this message - System.err.println("WARNING: Rest job result parser is INCOMPLETE!"); + // TODO: finish this! and remove the message below! + Cache.log.warn("Rest job result parser is currently INCOMPLETE!"); + int validres = 0; for (RestJob rj : (RestJob[]) jobs) { - // TODO: call each jobs processResults() method and collect valid - // contexts. if (rj.hasResponse() && rj.resSet != null && rj.resSet.isValid()) { String ln = null; - System.out.println("Parsing data for job " + rj.getJobId()); - if (!restClient.isAlignmentModified()) + try { - try - { - /* - * while ((ln=rj.resSet.nextLine())!=null) { System.out.println(ln); - * } } - */ - List dp = new ArrayList(); - restClient.af.newView_actionPerformed(null); - dp.add(new SimpleDataProvider(JvDataType.ANNOTATION, rj.resSet, null)); - JalviewDataset context = new JalviewDataset(restClient.av.getAlignment().getDataset(), null, null,restClient.av.getAlignment()); - ParsePackedSet pps = new ParsePackedSet(); - pps.getAlignment(context, dp); - - // do an ap.refresh restClient.av.alignmentChanged(Desktop.getAlignmentPanels(restClient.av.getViewId())[0]); - System.out.println("Finished parsing data for job " - + rj.getJobId()); - - } catch (Exception ex) + Cache.log.debug("Parsing data for job " + rj.getJobId()); + rj.parseResultSet(); + if (rj.hasResults()) { - System.out.println("Failed to finish parsing data for job " - + rj.getJobId()); - ex.printStackTrace(); + validres++; } + Cache.log.debug("Finished parsing data for job " + rj.getJobId()); + + } catch (Error ex) + { + Cache.log.warn("Failed to finish parsing data for job " + + rj.getJobId()); + ex.printStackTrace(); + } catch (Exception ex) + { + Cache.log.warn("Failed to finish parsing data for job " + + rj.getJobId()); + ex.printStackTrace(); } } } - /** - * decisions based on job result content + state of alignFrame that - * originated the job: - */ - /* - * 1. Can/Should this job automatically open a new window for results - */ - wsInfo.setViewResultsImmediatly(false); + if (validres > 0) + { + // add listeners and activate result display gui elements + /** + * decisions based on job result content + state of alignFrame that + * originated the job: + */ + /* + * 1. Can/Should this job automatically open a new window for results + */ + if (true) + { + wsInfo.setViewResultsImmediatly(false); + } + else + { + // realiseResults(true, true); + } + // otherwise, should automatically view results + + // TODO: check if at least one or more contexts are valid - if so, enable + // gui + wsInfo.showResultsNewFrame.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + realiseResults(false); + } + + }); + wsInfo.mergeResults.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + realiseResults(true); + } + + }); + + wsInfo.setResultsReady(); + } + else + { + // tell the user nothing was returned. + } + } + + public void realiseResults(boolean merge) + { /* * 2. Should the job modify the parent alignment frame/view(s) (if they * still exist and the alignment hasn't been edited) in order to display new * annotation/features. */ /** - * alignments. New alignments are added to dataset, and subsequently - * annotated/visualised accordingly. 1. New alignment frame created for new - * alignment. Decide if any vis settings should be inherited from old - * alignment frame (e.g. sequence ordering ?). 2. Subsequent data added to - * alignment as below: + * alignment panels derived from each alignment set returned by service. */ + ArrayList destPanels = new ArrayList(); /** - * annotation update to original/newly created context alignment: 1. - * identify alignment where annotation is to be loaded onto. 2. Add - * annotation, excluding any duplicates. 3. Ensure annotation is visible on - * alignment - honouring ordering given by file. + * current pane being worked with */ + jalview.gui.AlignmentPanel destPanel; /** - * features updated to original or newly created context alignment: 1. - * Features are(or were already) added to dataset. 2. Feature settings - * modified to ensure all features are displayed - honouring any ordering - * given by result file. Consider merging action with the code used by the - * DAS fetcher to update alignment views with new info. + * when false, zeroth pane is panel derived from input deta. */ - /** - * Seq associated data files (PDB files). 1. locate seq association in - * current dataset/alignment context and add file as normal - keep handle of - * any created ref objects. 2. decide if new data should be displayed : PDB - * display: if alignment has PDB display already, should new pdb files be - * aligned to it ? - * - */ - // TODO: check if at least one or more contexts are valid - if so, enable - // gui - wsInfo.showResultsNewFrame.addActionListener(new ActionListener() + boolean newAlignment = false; + if (merge) { - - @Override - public void actionPerformed(ActionEvent e) + if (!restClient.isAlignmentModified()) { - // TODO: call method to show results in new window + destPanel = restClient.recoverAlignPanelForView(); + if (restClient.isShowResultsInNewView()) + { + destPanel = destPanel.alignFrame.newView(false); + } + // add the destination panel to frame zero of result panel set + destPanels.add(destPanel); } - - }); - wsInfo.mergeResults.addActionListener(new ActionListener() + } + if (destPanels.size()==0) { - - @Override - public void actionPerformed(ActionEvent e) + Object[] idat = input.getAlignmentAndColumnSelection(restClient.av + .getGapCharacter()); + AlignFrame af = new AlignFrame((AlignmentI) idat[0], + (ColumnSelection) idat[1], AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + jalview.gui.Desktop.addInternalFrame(af, + "Results for " + restClient.service.details.Name + " " + + restClient.service.details.Action + " on " + + restClient.af.getTitle(), AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + destPanel = af.alignPanel; + // create totally new alignment from stashed data/results + newAlignment = true; + } + // Now process results, adding/creating new views as necessary. + { + boolean hsepjobs = restClient.service.isHseparable(); + boolean vsepjobs = restClient.service.isVseparable(); + // total number of distinct alignment sets generated by job set. + int totalSets = 0, numAlSets = 0; + for (int j = 0; j < jobs.length; j++) { - // TODO: call method to merge results into existing window - } + RestJob rj = (RestJob) jobs[j]; + if (rj.hasResults()) + { + JalviewDataset rset = rj.context; + numAlSets = rset.hasAlignments() ? 0 : rset.getAl().size(); + if (numAlSets > 0) + { + for (int als = 0; als < numAlSets; als++) + { + // gather data from context + if (vsepjobs) + { + // todo: merge data from each group/sequence onto whole + // alignment + } + else + { + if (hsepjobs) + { + // map single result back on to all visible region of original alignment + if (als==0 && rj.isInputContextModified()) + { + // transfer features, annotation, groups, etc, from input context to align panel derived from input data + new jalview.datamodel.Alignment(new jalview.datamodel.SequenceI[] {null}).getAlignmentAnnotation(); + } + + } + else + { + // map result onto visible contigs. + AlignmentSet alset = rset.getAl().get(als); + if (als>0 ) + if (als == 0) + { + + // alignment is added straight to + } + } + } + } + } + } + // transfer results onto panel - }); + } + /** + * alignments. New alignments are added to dataset, and subsequently + * annotated/visualised accordingly. 1. New alignment frame created for + * new alignment. Decide if any vis settings should be inherited from old + * alignment frame (e.g. sequence ordering ?). 2. Subsequent data added to + * alignment as below: + */ + /** + * annotation update to original/newly created context alignment: 1. + * identify alignment where annotation is to be loaded onto. 2. Add + * annotation, excluding any duplicates. 3. Ensure annotation is visible + * on alignment - honouring ordering given by file. + */ + /** + * features updated to original or newly created context alignment: 1. + * Features are(or were already) added to dataset. 2. Feature settings + * modified to ensure all features are displayed - honouring any ordering + * given by result file. Consider merging action with the code used by the + * DAS fetcher to update alignment views with new info. + */ + /** + * Seq associated data files (PDB files). 1. locate seq association in + * current dataset/alignment context and add file as normal - keep handle + * of any created ref objects. 2. decide if new data should be displayed : + * PDB display: if alignment has PDB display already, should new pdb files + * be aligned to it ? + * + */ - wsInfo.setResultsReady(); + } + // destPanel.adjustAnnotationHeight(); }