import java.util.Arrays;
import java.util.Deque;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
import java.util.Vector;
import javax.swing.ButtonGroup;
{
return lastFeatureSettingsBounds;
}
+
+ /*
+ * Caching hashmaps for jalview.rest.API
+ */
+ private static Map<String, AlignFrame> alignFrameMap = null;
+
+ public static AlignFrame getAlignFrameFromRestId(String id)
+ {
+ if (id == null || alignFrameMap == null)
+ return null;
+ return alignFrameMap.get(id);
+ }
+
+ public void cacheAlignFrameFromRestId(String id)
+ {
+ if (id == null)
+ return;
+ if (alignFrameMap == null)
+ alignFrameMap = new HashMap<>();
+ alignFrameMap.put(id, this);
+ }
}
class PrintThread extends Thread
* @param guiIndic
* @param selectedDb
* @param queryString
+ * @param interactive
*/
public SequenceFetcher(IProgressIndicator guiIndic,
final String selectedDb, final String queryString)
{
+ this(guiIndic, selectedDb, queryString, true);
+ }
+
+ public SequenceFetcher(IProgressIndicator guiIndic,
+ final String selectedDb, final String queryString,
+ boolean interactive)
+ {
this.progressIndicator = guiIndic;
getSequenceFetcherSingleton();
this.guiWindow = progressIndicator;
alignFrame = (AlignFrame) progressIndicator;
}
- jbInit(selectedDb);
+ jbInit(selectedDb, interactive);
textArea.setText(queryString);
frame = new JInternalFrame();
.getString("label.additional_sequence_fetcher"));
}
- private void jbInit(String selectedDb)
+ private void jbInit(String selectedDb, boolean interactive)
{
this.setLayout(new BorderLayout());
jScrollPane1.getViewport().add(textArea);
idsPanel.add(jScrollPane1, BorderLayout.CENTER);
+ // En/disable or show/hide interactive elements
+ database.setEnabled(interactive);
+ exampleAccession.setVisible(interactive);
+ replacePunctuation.setVisible(interactive);
+ okBtn.setVisible(interactive);
+ exampleBtn.setVisible(interactive);
+ closeBtn.setVisible(interactive);
+ backBtn.setVisible(interactive);
+ jLabel1.setVisible(interactive);
+ clear.setVisible(interactive);
+ textArea.setEnabled(interactive);
+
this.add(actionPanel, BorderLayout.SOUTH);
this.add(idsPanel, BorderLayout.CENTER);
this.add(databasePanel, BorderLayout.NORTH);
+
}
/**
*/
public void ok_actionPerformed()
{
- ok_actionPerformed(false);
+ ok_actionPerformed(false, null);
}
- public CompletableFuture ok_actionPerformed(boolean returnFuture)
+ public CompletableFuture<Void> ok_actionPerformed(boolean returnFuture,
+ String id)
{
/*
* tidy inputs and check there is something to search for
backBtn.setEnabled(false);
CompletableFuture<Void> worker = CompletableFuture
- .runAsync(new Thread(this));
+ .runAsync(() -> runAndCacheAlignFrame(returnFuture, id));
return returnFuture ? worker : null;
}
+ private void runAndCacheAlignFrame(boolean cacheAlignFrame, String id)
+ {
+ AlignFrame af = this.run(cacheAlignFrame);
+ if (cacheAlignFrame && id != null && af != null)
+ af.cacheAlignFrameFromRestId(id);
+ }
+
private void resetDialog()
{
exampleBtn.setEnabled(true);
@Override
public void run()
{
+ run(false);
+ }
+
+ public AlignFrame run(boolean returnAlignFrame)
+ {
boolean addToLast = false;
List<String> aresultq = new ArrayList<>();
List<String> presultTitle = new ArrayList<>();
: MessageManager.getString("status.processing"),
Thread.currentThread().hashCode());
// process results
+ AlignFrame af = null;
while (presult.size() > 0)
{
- parseResult(presult.remove(0), presultTitle.remove(0), null,
+ af = parseResult(presult.remove(0), presultTitle.remove(0), null,
preferredFeatureColours);
}
// only remove visual delay after we finished parsing.
showErrorMessage(sb.toString());
}
resetDialog();
+ return returnAlignFrame ? af : null;
}
/**
return "Retrieved from " + database.getSelectedItem();
}
- AlignmentI parseResult(AlignmentI al, String title,
+ AlignFrame parseResult(AlignmentI al, String title,
FileFormatI currentFileFormat,
FeatureSettingsModelI preferredFeatureColours)
{
+ AlignFrame af = alignFrame;
if (al != null && al.getHeight() > 0)
{
if (title == null)
{
title = getDefaultRetrievalTitle();
}
- if (alignFrame == null)
+ if (af == null)
{
- AlignFrame af = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
+ af = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
if (currentFileFormat != null)
{
}
else
{
- alignFrame.viewport.addAlignment(al, title);
+ af.viewport.addAlignment(al, title);
}
}
- return al;
+ return af;
}
void showErrorMessage(final String error)
addEndpoint(new FetchSequencesEndpoint(this));
addEndpoint(new InputAlignmentEndpoint(this));
addEndpoint(new HighlightSequenceEndpoint(this));
+ addEndpoint(new SelectSequencesEndpoint(this));
setPath(MY_PATH);
this.registerHandler();
return true;
}
+ public int[][] parseIntRanges(String rangesString)
+ {
+ String[] rangeStrings = rangesString.split(",");
+ int[][] ranges = new int[2][rangeStrings.length];
+ for (int i = 0; i < rangeStrings.length; i++)
+ {
+ String range = rangeStrings[i];
+ try
+ {
+ int hyphenpos = range.indexOf('-');
+ if (hyphenpos < 0)
+ {
+ ranges[0][i] = Integer.parseInt(range);
+ ranges[1][i] = ranges[0][i];
+ }
+ else
+ {
+ ranges[0][i] = Integer.parseInt(range.substring(0, hyphenpos));
+ ranges[1][i] = Integer.parseInt(range.substring(hyphenpos + 1));
+ }
+ } catch (NumberFormatException nfe)
+ {
+ return null;
+ }
+ }
+ return ranges;
+ }
+
}
\ No newline at end of file
if (checkStatus(request, response, Status.STARTED))
{
- returnStatus(response);
+ String finishedString = null;
+ if (getStatus() == Status.FINISHED)
+ {
+ finishedString = finished(request, response);
+ }
+ returnStatus(request, response, finishedString);
return;
}
if (getCompletableFuture() == null)
{
- final Map<String, String> finalMap = stringsPassedToProcessAsync;
+ final Map<String, String> finalStringMap = stringsPassedToProcessAsync;
setCompletableFuture(CompletableFuture.runAsync(() -> {
// subclass method
- this.processAsync(request, response, finalMap);
+ this.processAsync(request, response, finalStringMap);
}));
}
- finaliseCompletableFuture();
+ addWhenCompleteCompletableFuture();
// subclass method
finalise(request, response);
{
}
+ protected String finished(HttpServletRequest request,
+ HttpServletResponse response)
+ {
+ return null;
+ }
+
/*
* Shared methods below here
*/
// don't change a job's status if it has finished or died
if (getStatus() == Status.FINISHED || getStatus() == Status.ERROR)
return;
- getAPI().getStatusMap().put(id, status);
+ API.getStatusMap().put(id, status);
}
protected Status getStatus()
{
- return getAPI().getStatusMap().get(getId());
+ getAPI();
+ return API.getStatusMap().get(getId());
}
protected void returnStatus(HttpServletResponse response)
{
+ returnStatus(null, response, null);
+ }
+
+ protected void returnStatus(HttpServletRequest request,
+ HttpServletResponse response, String message)
+ {
String id = getId();
try
{
{
writer.write("id=" + id + "\n");
}
- if (getAPI().getRequestMap().get(id) != null)
+ getAPI();
+ if (API.getRequestMap().get(id) != null)
{
- writer.write("request="
- + getAPI().getRequestMap().get(id).toString() + "\n");
+ getAPI();
+ writer.write(
+ "request=" + API.getRequestMap().get(id).toString() + "\n");
}
if (getStatus() != null)
{
}
writer.write("status=" + getStatus().toString() + "\n");
}
+ if (message != null)
+ {
+ writer.write(message);
+ }
} catch (IOException e)
{
Cache.debug(e);
{
if (set != null)
changeStatus(set);
- getAPI().getRequestMap().put(id, request.getRequestURI());
+ API.getRequestMap().put(id, request.getRequestURI());
return false;
}
else
}
}
- protected void finaliseCompletableFuture()
+ protected void addWhenCompleteCompletableFuture()
{
String id = getId();
cf.whenComplete((Void, e) -> {
package jalview.rest;
+import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import jalview.api.AlignmentViewPanel;
import jalview.bin.Cache;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.gui.SequenceFetcher;
+import jalview.structure.StructureSelectionManager;
import jalview.util.DBRefUtils;
public class FetchSequencesEndpoint extends AbstractEndpointAsync
String db = DBRefUtils.getCanonicalName(dbName);
Desktop desktop = Desktop.instance;
- sf = new SequenceFetcher(desktop, db, dbId);
- setCompletableFuture(sf.ok_actionPerformed(true));
+ sf = new SequenceFetcher(desktop, db, dbId, false);
+ setCompletableFuture(sf.ok_actionPerformed(true, getId()));
}
protected void processAsync(HttpServletRequest request,
{
sf.close_actionPerformed(null);
}
+
+ protected String finished(HttpServletRequest request,
+ HttpServletResponse response)
+ {
+ AlignFrame af = AlignFrame.getAlignFrameFromRestId(getId());
+ if (af == null)
+ {
+ return null;
+ }
+ List<AlignmentViewPanel> aps = (List<AlignmentViewPanel>) af
+ .getAlignPanels();
+ StringBuilder sb = new StringBuilder();
+ for (AlignmentViewPanel ap : aps)
+ {
+ StructureSelectionManager ssm = ap.getStructureSelectionManager();
+ // ap.getAlignViewport().getSequenceSetId()
+ AlignmentI al = ap.getAlignment();
+ List<SequenceI> seqs = (List<SequenceI>) al.getSequences();
+ for (SequenceI seq : seqs)
+ {
+ if (sb.length() > 0)
+ sb.append(",");
+ sb.append(seq.getName());
+ }
+ }
+ sb.insert(0, "sequences=");
+ sb.append("\n");
+ return sb.toString();
+ }
+
}
package jalview.rest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import jalview.api.AlignmentViewPanel;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.structure.StructureSelectionManager;
+
public class HighlightSequenceEndpoint extends AbstractEndpoint
{
public HighlightSequenceEndpoint(API api)
super(api, path, name, parameters, description);
}
- protected static final String path = "highlight";
+ protected static final String path = "highlightsequence";
- private static final String name = "Highlight positions";
+ private static final String name = "Highlight sequence positions";
private static final String parameters = "<sequence names>,<ranges>";
- private static final String description = "Highlight the specified sequences with the specified range(s)";
+ private static final String description = "Highlight the specified sequences at the specified position";
public void processEndpoint(HttpServletRequest request,
HttpServletResponse response)
}
String[] parameters = getEndpointPathParameters(request);
- String rangesString = parameters[0];
- String[] rangeStrings = rangesString.split(",");
- int[][] ranges = new int[rangeStrings.length][2];
- for (int i = 0; i < rangeStrings.length; i++)
+ String posString = parameters[1];
+ int pos = -1;
+ try
+ {
+ pos = Integer.parseInt(posString);
+ } catch (NumberFormatException e)
+ {
+ returnError(request, response,
+ "Could not parse postition integer " + posString);
+ }
+
+ String sequenceNames = parameters[0];
+ String fromIdString = request.getParameter("fromId");
+
+ Map<SequenceI, StructureSelectionManager> ssmMap = new HashMap<>();
+ AlignFrame[] alignFrames;
+ if (fromIdString != null)
{
- String range = rangeStrings[i];
- try
+ AlignFrame af = AlignFrame.getAlignFrameFromRestId(fromIdString);
+ if (af == null)
{
- int hyphenpos = range.indexOf('-');
- if (hyphenpos < 0)
- {
- ranges[i][0] = Integer.parseInt(range);
- ranges[i][1] = ranges[i][0];
- }
- else
+ returnError(request, response,
+ "fromId value '" + fromIdString + "' results not found");
+ return;
+ }
+ alignFrames = new AlignFrame[] { af };
+ }
+ else
+ {
+ alignFrames = Desktop.getAlignFrames();
+ }
+ if (alignFrames == null)
+ return;
+ for (int i = 0; i < alignFrames.length; i++)
+ {
+ AlignFrame af = alignFrames[i];
+ List<AlignmentViewPanel> aps = (List<AlignmentViewPanel>) af
+ .getAlignPanels();
+ for (AlignmentViewPanel ap : aps)
+ {
+ StructureSelectionManager ssm = ap.getStructureSelectionManager();
+ // ap.getAlignViewport().getSequenceSetId()
+ AlignmentI al = ap.getAlignment();
+ List<SequenceI> seqs = (List<SequenceI>) al.getSequences();
+ for (SequenceI seq : seqs)
{
- ranges[i][0] = Integer.parseInt(range.substring(0, hyphenpos));
- ranges[i][1] = Integer.parseInt(range.substring(hyphenpos));
+ Cache.info("REMOVEME sequence name=" + seq.getName());
+ if (sequenceNames.equals(seq.getName()))
+ {
+ Cache.info("REMOVEME MATCHED " + seq.getName());
+ ssmMap.put(seq, ssm);
+ }
}
- } catch (NumberFormatException nfe)
+ }
+ }
+ // highlight
+ for (SequenceI seq : ssmMap.keySet())
+ {
+ StructureSelectionManager ssm = ssmMap.get(seq);
+ if (ssm == null)
{
- returnError(request, response,
- "couldn't parse ranges component '" + range + "'");
- return;
+ Cache.info("REMOVEME skipping sequence " + seq.getName());
+ continue;
}
+ Cache.info("REMOVEME Attempting to highlight sequence "
+ + seq.getName() + " at postition " + pos);
+ ssm.mouseOverSequence(seq, pos, -1, null);
}
}
--- /dev/null
+package jalview.rest;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+
+public class SelectSequencesEndpoint extends AbstractEndpoint
+{
+ public SelectSequencesEndpoint(API api)
+ {
+ super(api, path, name, parameters, description);
+ }
+
+ protected static final String path = "selectsequences";
+
+ private static final String name = "Select sequence(s) positions";
+
+ private static final String parameters = "<sequence names>,<range>";
+
+ private static final String description = "Select the specified sequence(s) with the specified range";
+
+ public void processEndpoint(HttpServletRequest request,
+ HttpServletResponse response)
+ {
+ if (!checkParameters(request, response, 2))
+ {
+ return;
+ }
+ String[] parameters = getEndpointPathParameters(request);
+
+ String rangesString = parameters[1];
+ int[][] ranges = parseIntRanges(rangesString);
+ if (ranges == null || ranges.length < 2 || ranges[0].length < 1)
+ {
+ returnError(request, response,
+ "couldn't parse range '" + rangesString + "'");
+ return;
+ }
+ if (ranges[0].length > 1)
+ {
+ returnError(request, response,
+ "only provide 1 range '" + rangesString + "'");
+ return;
+ }
+ int start = ranges[0][0];
+ int end = ranges[1][0];
+
+ String sequenceNamesString = parameters[0];
+ List<String> sequenceNames = Arrays
+ .asList(sequenceNamesString.split(","));
+ String fromIdString = request.getParameter("fromId");
+
+ AlignFrame[] alignFrames;
+ if (fromIdString != null)
+ {
+ AlignFrame af = AlignFrame.getAlignFrameFromRestId(fromIdString);
+ if (af == null)
+ {
+ returnError(request, response,
+ "fromId value '" + fromIdString + "' results not found");
+ return;
+ }
+ alignFrames = new AlignFrame[] { af };
+ }
+ else
+ {
+ alignFrames = Desktop.getAlignFrames();
+ }
+ if (alignFrames == null)
+ return;
+ for (int i = 0; i < alignFrames.length; i++)
+ {
+ AlignFrame af = alignFrames[i];
+ List<AlignmentViewPanel> aps = (List<AlignmentViewPanel>) af
+ .getAlignPanels();
+ for (AlignmentViewPanel ap : aps)
+ {
+ AlignViewportI avp = ap.getAlignViewport();
+ // ap.getAlignViewport().getSequenceSetId()
+ AlignmentI al = ap.getAlignment();
+ List<SequenceI> seqs = (List<SequenceI>) al.getSequences();
+ SequenceGroup stretchGroup = new SequenceGroup();
+ for (SequenceI seq : seqs)
+ {
+ if (sequenceNames.contains(seq.getName()))
+ {
+ stretchGroup.addSequence(seq, false);
+ }
+ }
+ stretchGroup.setStartRes(start);
+ stretchGroup.setEndRes(end);
+ avp.setSelectionGroup(stretchGroup);
+ ap.paintAlignment(false, false);
+ avp.sendSelection();
+ }
+ }
+ }
+}
\ No newline at end of file