From af83e7d123133d2bb44b0bcafe538e300304a1b1 Mon Sep 17 00:00:00 2001 From: BobHanson Date: Fri, 5 Jun 2020 00:53:39 -0500 Subject: [PATCH] Refactoring of Jalview, JalviewAppLoader, JalviewApp, various applet-related interfaces - makes JalviewJSApp the JavaScript interface "app" class - removes JS interface from Jalview - removes JalviewAppLoader and associated duplication of classes - adds JavaScript selection and "oninit" listeners (untested) --- src/jalview/api/JalviewApp.java | 82 - .../JalviewJSApp.java} | 2652 +++++++++++++------- .../js}/JSFunctionExec.java | 2 +- .../js}/JalviewLiteJsApi.java | 4 +- .../{javascript => appletgui/js}/JsCallBack.java | 2 +- .../js}/JsSelectionSender.java | 2 +- .../js}/MouseOverListener.java | 2 +- .../js}/MouseOverStructureListener.java | 3 +- src/jalview/bin/AppletParams.java | 549 ++-- src/jalview/bin/ArgsParser.java | 34 +- src/jalview/bin/Jalview.java | 997 +------- src/jalview/bin/JalviewJS2.java | 29 +- src/jalview/bin/JalviewJSApi.java | 1215 +++++---- src/jalview/bin/JalviewLite.java | 24 +- src/jalview/ext/jmol/JalviewJmolBinding.java | 4 +- src/jalview/gui/AlignFrame.java | 5 - src/jalview/gui/Desktop.java | 2 +- src/jalview/project/Jalview2XML.java | 13 +- .../structure/StructureSelectionManager.java | 6 +- src/jalview/util/Platform.java | 5 + src/swingjs/api/JSUtilI.java | 25 +- unused/JalviewAppLoader.java | 27 + unused/JalviewJSApp.java | 12 + 23 files changed, 2810 insertions(+), 2886 deletions(-) delete mode 100644 src/jalview/api/JalviewApp.java rename src/jalview/{bin/JalviewAppLoader.java => api/JalviewJSApp.java} (56%) rename src/jalview/{javascript => appletgui/js}/JSFunctionExec.java (99%) rename src/jalview/{javascript => appletgui/js}/JalviewLiteJsApi.java (99%) rename src/jalview/{javascript => appletgui/js}/JsCallBack.java (97%) rename src/jalview/{javascript => appletgui/js}/JsSelectionSender.java (99%) rename src/jalview/{javascript => appletgui/js}/MouseOverListener.java (99%) rename src/jalview/{javascript => appletgui/js}/MouseOverStructureListener.java (99%) create mode 100644 unused/JalviewAppLoader.java create mode 100644 unused/JalviewJSApp.java diff --git a/src/jalview/api/JalviewApp.java b/src/jalview/api/JalviewApp.java deleted file mode 100644 index e488d6e..0000000 --- a/src/jalview/api/JalviewApp.java +++ /dev/null @@ -1,82 +0,0 @@ -package jalview.api; - -import jalview.datamodel.ColumnSelection; -import jalview.datamodel.HiddenColumns; -import jalview.datamodel.PDBEntry; -import jalview.datamodel.SequenceGroup; -import jalview.datamodel.SequenceI; -import jalview.io.DataSourceType; -import jalview.io.NewickFile; -import jalview.javascript.JSFunctionExec; -import jalview.javascript.MouseOverStructureListener; -import jalview.structure.SelectionSource; -import jalview.structure.VamsasSource; - -//import java.applet.AppletContext; -import java.io.IOException; -import java.net.URL; -import java.util.Hashtable; -import java.util.Vector; - -import netscape.javascript.JSObject; - -public interface JalviewApp -{ - public String getParameter(String name); - - public boolean getDefaultParameter(String name, boolean def); - - public URL getDocumentBase(); - - public URL getCodeBase(); - - public void setAlignPdbStructures(boolean defaultParameter); - - public void newStructureView(PDBEntry pdb, SequenceI[] seqs, - String[] chains, DataSourceType protocol); - - public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs, - String[][] chains, String[] protocols); - - public void updateForAnnotations(); - - public AlignViewportI getViewport(); - - public void setFeatureGroupState(String[] groups, boolean state); - - public boolean parseFeaturesFile(String param, DataSourceType protocol); - - public void newFeatureSettings(); - - public boolean loadScoreFile(String sScoreFile) throws IOException; - - public void loadTree(NewickFile fin, String treeFile) throws IOException; - - public Vector getJsExecQueue(JSFunctionExec jsFunctionExec); - -// deprecated public AppletContext getAppletContext(); - - public boolean isJsfallbackEnabled(); - - public JSObject getJSObject(); - - public StructureSelectionManagerProvider getStructureSelectionManagerProvider(); - - public void updateColoursFromMouseOver(Object source, - MouseOverStructureListener mouseOverStructureListener); - - public Object[] getSelectionForListener(SequenceGroup seqsel, ColumnSelection colsel, - HiddenColumns hidden, SelectionSource source, Object alignFrame); - - public String arrayToSeparatorList(String[] array); - - public Hashtable getJSHashes(); - - Hashtable> getJSMessages(); - - public Object getFrameForSource(VamsasSource source); - - public jalview.renderer.seqfeatures.FeatureRenderer getNewFeatureRenderer( - AlignViewportI vp); - -} diff --git a/src/jalview/bin/JalviewAppLoader.java b/src/jalview/api/JalviewJSApp.java similarity index 56% rename from src/jalview/bin/JalviewAppLoader.java rename to src/jalview/api/JalviewJSApp.java index 1cdeaec..693ea63 100644 --- a/src/jalview/bin/JalviewAppLoader.java +++ b/src/jalview/api/JalviewJSApp.java @@ -1,7 +1,18 @@ -package jalview.bin; +package jalview.api; -import jalview.api.JalviewApp; -import jalview.api.StructureSelectionManagerProvider; +import java.awt.EventQueue; +//import java.applet.AppletContext; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.StringTokenizer; +import java.util.Vector; + +import jalview.bin.ArgsParser; +import jalview.bin.Jalview; +import jalview.bin.JalviewJSApi; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentOrder; @@ -13,7 +24,10 @@ import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; import jalview.gui.AlignViewport; +import jalview.gui.AlignmentPanel; +import jalview.gui.CalculationChooser; import jalview.gui.Desktop; +import jalview.gui.StructureViewer; import jalview.io.AnnotationFile; import jalview.io.AppletFormatAdapter; import jalview.io.DataSourceType; @@ -25,57 +39,49 @@ import jalview.io.IdentifyFile; import jalview.io.JPredFile; import jalview.io.JnetAnnotationMaker; import jalview.io.NewickFile; +import jalview.renderer.seqfeatures.FeatureRenderer; +import jalview.structure.SelectionListener; import jalview.structure.SelectionSource; import jalview.structure.StructureSelectionManager; +import jalview.structure.VamsasSource; import jalview.util.HttpUtils; import jalview.util.MessageManager; +import jalview.util.Platform; -import java.awt.EventQueue; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; -import java.util.Vector; +//import netscape.javascript.JSObject; /** - * A class to load parameters for either JalviewLite or Jalview + * Basically the JalviewLite application, but without JalviewLite * * @author hansonr * */ -public class JalviewAppLoader +public class JalviewJSApp implements JalviewJSApi { + private ArgsParser aparser; - private JalviewApp app; // Jalview or JalviewJS or JalviewLite + private String j2sAppletID; private boolean debug; - String separator = "\u00AC"; // JalviewLite note: the default used to + private String[] ret = new String[1]; + + private String separator = "\u00AC"; // JalviewLite note: the default used to // be '|', but many sequence IDS include // pipes. - public String getSeparator() - { - return separator; - } - - public void setSeparator(String separator) + public JalviewJSApp(ArgsParser aparser) { - this.separator = separator; + this.aparser = aparser; + this.j2sAppletID = (String) aparser.getAppletValue("j2sAppletID", + "Jalview", true); + Platform.setAppClass(this); } - public JalviewAppLoader(boolean debug) - { - this.debug = debug; - } - public void load(JalviewApp app) + public void load(AlignFrame af) { - - this.app = app; - - String sep = app.getParameter("separator"); + String sep = (String) getAppletParameter("separator", true); if (sep != null) { if (sep.length() > 0) @@ -89,773 +95,1385 @@ public class JalviewAppLoader } } - loadTree(); + loadTree(af); loadScoreFile(); - loadFeatures(); - loadAnnotations(); - loadJnetFile(); - loadPdbFiles(); - callInitCallback(); + loadFeatures(af); + loadAnnotations(af); + loadJnetFile(af); + loadPdbFiles(af); + } + + public String getAppID(String frameType) + { + return j2sAppletID + (frameType == null ? "" : "-" + frameType); + } + + // TODO BH 2019 + // + // These are methods that are in JalviewLite that various classes call + // but are not in JalviewLiteJsApi. Or, even if they are, other classes + // call + // them to JalviewLite directly. Some may not be necessary, but they have + // to + // be at least mentioned here, or the classes calling them should + // reference + // JalviewLite itself. + + // private boolean alignPDBStructures; // From JalviewLite; not implemented + // + private Hashtable> jsmessages; + + private Hashtable jshashes; + + @Override + public String getParameter(String name) + { + return (String) getAppletParameter(name, true); + } + + @Override + public Object getAppletParameter(String name, boolean asString) + { + return aparser.getAppletValue(name, null, asString); } /** - * Load PDBFiles if any specified by parameter(s). Returns true if loaded, - * else false. - * - * @param loaderFrame - * @return + * Get the applet-like code base even though this is an application. */ - protected boolean loadPdbFiles() + + @Override + public URL getCodeBase() { - boolean result = false; - /* - * Undocumented for 2.6 - - * related to JAL-434 - */ + return Platform.getCodeBase(); + } - boolean doAlign = app.getDefaultParameter("alignpdbfiles", false); - app.setAlignPdbStructures(doAlign); - /* - * - * - * - * - * - */ + /** + * Get the applet-like document base even though this is an application. + */ - // Accumulate pdbs here if they are heading for the same view (if - // alignPdbStructures is true) - Vector pdbs = new Vector<>(); - // create a lazy matcher if we're asked to - jalview.analysis.SequenceIdMatcher matcher = (app - .getDefaultParameter("relaxedidmatch", false)) - ? new jalview.analysis.SequenceIdMatcher( - app.getViewport().getAlignment() - .getSequencesArray()) - : null; + @Override + public URL getDocumentBase() + { + return Platform.getDocumentBase(); + } - int pdbFileCount = 0; - String param; - do + @Override + public Object getFrameForSource(VamsasSource source) + { + if (source != null) { - if (pdbFileCount > 0) - { - param = app.getParameter("PDBFILE" + pdbFileCount); - } - else + AlignFrame af; + if (source instanceof jalview.gui.AlignViewport + && source == (af = Jalview.getCurrentAlignFrame()) + .getViewport()) { - param = app.getParameter("PDBFILE"); + // should be valid if it just generated an event! + return af; } + // TODO: ensure that if '_af' is specified along with a handler + // function, then only events from that alignFrame are sent to that + // function + } + return null; + } - if (param != null) - { - PDBEntry pdb = new PDBEntry(); + @Override + public Hashtable getJSHashes() + { + return (jshashes == null ? (jshashes = new Hashtable<>()) : jshashes); + } - String seqstring; - SequenceI[] seqs = null; - String[] chains = null; + @Override + public Hashtable> getJSMessages() + { + return (jsmessages == null ? (jsmessages = new Hashtable<>()) + : jsmessages); + } - StringTokenizer st = new StringTokenizer(param, " "); + @Override + public Object getJSObject() + { + return Jalview.getInstance(); + } - if (st.countTokens() < 2) - { - String sequence = app.getParameter("PDBSEQ"); - if (sequence != null) - { - seqs = new SequenceI[] { matcher == null - ? (Sequence) app.getViewport().getAlignment() - .findName(sequence) - : matcher.findIdMatch(sequence) }; - } + @Override + public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp) + { + return new jalview.gui.FeatureRenderer((AlignmentPanel) vp); + } - } - else - { - param = st.nextToken(); - List tmp = new ArrayList<>(); - List tmp2 = new ArrayList<>(); + @Override + public Object[] getSelectionForListener(SequenceGroup seqsel, + ColumnSelection colsel, HiddenColumns hidden, + SelectionSource source, Object alignFrame) + { + return getSelectionForListener(null, seqsel, colsel, hidden, source, + alignFrame); + } - while (st.hasMoreTokens()) - { - seqstring = st.nextToken(); - StringTokenizer st2 = new StringTokenizer(seqstring, "="); - if (st2.countTokens() > 1) - { - // This is the chain - tmp2.add(st2.nextToken()); - seqstring = st2.nextToken(); - } - tmp.add(matcher == null - ? (Sequence) app.getViewport().getAlignment() - .findName(seqstring) - : matcher.findIdMatch(seqstring)); - } + /** + * scorefile + * + */ - seqs = tmp.toArray(new SequenceI[tmp.size()]); - if (tmp2.size() == tmp.size()) - { - chains = tmp2.toArray(new String[tmp2.size()]); - } - } - pdb.setId(param); - ret[0] = param; - DataSourceType protocol = resolveFileProtocol(app, ret); - // TODO check JAL-357 for files in a jar (CLASSLOADER) - pdb.setFile(ret[0]); + @Override + public boolean loadScoreFile(String sScoreFile) throws IOException + { + return loadScoreFile(null, sScoreFile); + } + + public boolean loadScoreFile(AlignFrame af, String sScoreFile) throws IOException + { + (af == null ? Jalview.getCurrentAlignFrame() : af).loadJalviewDataFile(sScoreFile, null, null, null); + return true; + } - if (seqs != null) - { - for (int i = 0; i < seqs.length; i++) - { - if (seqs[i] != null) - { - ((Sequence) seqs[i]).addPDBId(pdb); - StructureSelectionManager - .getStructureSelectionManager( - (StructureSelectionManagerProvider) app) - .registerPDBEntry(pdb); - } - else - { - if (debug) - { - // this may not really be a problem but we give a warning - // anyway - System.err.println( - "Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence " - + i + ")"); - } - } - } + public void loadTree(AlignFrame af, NewickFile nf, String treeFile) throws IOException + { + if (af == null) + af = Jalview.getCurrentAlignFrame(); + af.getViewport() + .setCurrentTree(af.showNewickTree(nf, treeFile).getTree()); + } - if (doAlign) - { - pdbs.addElement(new Object[] { pdb, seqs, chains, protocol }); - } - else - { - app.newStructureView(pdb, seqs, chains, protocol); - } - } - } + @Override + public void newFeatureSettings() + { + System.err.println( + "Jalview applet interface newFeatureSettings not implemented"); + } - pdbFileCount++; - } while (param != null || pdbFileCount < 10); - if (pdbs.size() > 0) - { - SequenceI[][] seqs = new SequenceI[pdbs.size()][]; - PDBEntry[] pdb = new PDBEntry[pdbs.size()]; - String[][] chains = new String[pdbs.size()][]; - String[] protocols = new String[pdbs.size()]; - for (int pdbsi = 0, pdbsiSize = pdbs - .size(); pdbsi < pdbsiSize; pdbsi++) - { - Object[] o = pdbs.elementAt(pdbsi); - pdb[pdbsi] = (PDBEntry) o[0]; - seqs[pdbsi] = (SequenceI[]) o[1]; - chains[pdbsi] = (String[]) o[2]; - protocols[pdbsi] = (String) o[3]; - } - app.alignedStructureView(pdb, seqs, chains, protocols); - result = true; - } - return result; + // + // + // public void setAlignPdbStructures(boolean defaultParameter) + // { + // alignPDBStructures = true; + // } + // + + @Override + public void newStructureView(PDBEntry pdb, SequenceI[] seqs, + String[] chains, DataSourceType protocol) + { + newStructureView(null, pdb, seqs, chains, protocol); + } - /** - * Load in a Jnetfile if specified by parameter. Returns true if loaded, else - * false. - * - * @param alignFrame - * @return - */ - protected boolean loadJnetFile() + public void newStructureView(AlignFrame af, PDBEntry pdb, + SequenceI[] seqs, String[] chains, DataSourceType protocol) { - boolean result = false; - String param = app.getParameter("jnetfile"); - if (param == null) - { - // jnet became jpred around 2016 - param = app.getParameter("jpredfile"); - } - if (param != null) - { - try - { - ret[0] = param; - DataSourceType protocol = resolveFileProtocol(app, ret); - JPredFile predictions = new JPredFile(ret[0], protocol); - JnetAnnotationMaker.add_annotation(predictions, - app.getViewport().getAlignment(), 0, false); - // false == do not add sequence profile from concise output - app.getViewport().getAlignment().setupJPredAlignment(); - app.updateForAnnotations(); - result = true; - } catch (Exception ex) - { - ex.printStackTrace(); - } - } - return result; + StructureViewer.launchStructureViewer( + (af == null ? Jalview.getCurrentAlignFrame() : af).alignPanel, + pdb, seqs); } /** - * Load annotations if specified by parameter. Returns true if loaded, else - * false. + * features + * @param af * - * @param alignFrame - * @return */ - protected boolean loadAnnotations() + + @Override + public boolean parseFeaturesFile(String filename, DataSourceType protocol) { - boolean result = false; - String param = app.getParameter("annotations"); - if (param != null) - { - ret[0] = param; - DataSourceType protocol = resolveFileProtocol(app, ret); - param = ret[0]; - if (new AnnotationFile().annotateAlignmentView(app.getViewport(), - param, protocol)) - { - app.updateForAnnotations(); - result = true; - } - else - { - System.err - .println("Annotations were not added from annotation file '" - + param + "'"); - } - } - return result; + return parseFeaturesFile(null, filename, protocol); + } + + public boolean parseFeaturesFile(AlignFrame af, String filename, DataSourceType protocol) + { + return af.parseFeaturesFile(filename, protocol); } + @Override + public void setFeatureGroupState(String[] groups, boolean state) + { + setFeatureGroupState(null, groups, state); + } + + public void setFeatureGroupState(AlignFrame af, String[] groups, boolean state) { + (af == null ? Jalview.getCurrentAlignFrame() : af).setFeatureGroupState(groups, state); + } /** - * Load features file and view settings as specified by parameters. Returns - * true if features were loaded, else false. + * annotations, jpredfile, jnetfile * - * @param alignFrame - * @return */ - protected boolean loadFeatures() + + @Override + public void updateForAnnotations() { - boolean result = false; - // /////////////////////////// - // modify display of features - // we do this before any features have been loaded, ensuring any hidden - // groups are hidden when features first displayed - // - // hide specific groups - // - String param = app.getParameter("hidefeaturegroups"); - if (param != null) - { - app.setFeatureGroupState(separatorListToArray(param, separator), - false); - // app.setFeatureGroupStateOn(newAlignFrame, param, false); - } - // show specific groups - param = app.getParameter("showfeaturegroups"); - if (param != null) - { - app.setFeatureGroupState(separatorListToArray(param, separator), - true); - // app.setFeatureGroupStateOn(newAlignFrame, param, true); - } - // and now load features - param = app.getParameter("features"); - if (param != null) - { - ret[0] = param; - DataSourceType protocol = resolveFileProtocol(app, ret); - - result = app.parseFeaturesFile(ret[0], protocol); - } - - param = app.getParameter("showFeatureSettings"); - if (param != null && param.equalsIgnoreCase("true")) - { - app.newFeatureSettings(); - } - return result; + updateForAnnotations(null); } - /** - * Load a score file if specified by parameter. Returns true if file was - * loaded, else false. - * - * @param loaderFrame - */ - protected boolean loadScoreFile() + public void updateForAnnotations(AlignFrame af) { - boolean result = false; - String sScoreFile = app.getParameter("scoreFile"); - if (sScoreFile != null && !"".equals(sScoreFile)) - { - try - { - if (debug) - { - System.err.println( - "Attempting to load T-COFFEE score file from the scoreFile parameter"); - } - result = app.loadScoreFile(sScoreFile); - if (!result) - { - System.err.println( - "Failed to parse T-COFFEE parameter as a valid score file ('" - + sScoreFile + "')"); - } - } catch (Exception e) - { - System.err.printf("Cannot read score file: '%s'. Cause: %s \n", - sScoreFile, e.getMessage()); - } - } - return result; + (af == null ? Jalview.getCurrentAlignFrame() : af).updateForAnnotations(); } - String[] ret = new String[1]; - - /** - * Load a tree for the alignment if specified by parameter. Returns true if a - * tree was loaded, else false. - * - * @param loaderFrame - * @return - */ - protected boolean loadTree() + @Override + public boolean addPdbFile(AlignFrame alf, String sequenceId, + String pdbEntryString, String pdbFile) { - boolean result = false; - String treeFile = app.getParameter("tree"); - if (treeFile == null) + if (alf == null) { - treeFile = app.getParameter("treeFile"); + alf = Jalview.getCurrentAlignFrame(); } - - if (treeFile != null) + SequenceI toaddpdb = alf.getViewport().getAlignment() + .findName(sequenceId); + boolean needtoadd = false; + if (toaddpdb != null) { - try + Vector pdbe = toaddpdb.getAllPDBEntries(); + PDBEntry pdbentry = null; + if (pdbe != null && pdbe.size() > 0) { - ret[0] = treeFile; - NewickFile fin = new NewickFile(treeFile, - resolveFileProtocol(app, ret)); - fin.parse(); - - if (fin.getTree() != null) + for (int pe = 0, peSize = pdbe.size(); pe < peSize; pe++) { - app.loadTree(fin, ret[0]); - result = true; - if (debug) + pdbentry = pdbe.elementAt(pe); + if (!pdbentry.getId().equals(pdbEntryString) + && !pdbentry.getFile().equals(pdbFile)) { - System.out.println("Successfully imported tree."); + pdbentry = null; } - } - else - { - if (debug) + else { - System.out.println( - "Tree parameter did not resolve to a valid tree."); + continue; } } - } catch (Exception ex) + } + if (pdbentry == null) { - ex.printStackTrace(); + pdbentry = new PDBEntry(); + pdbentry.setId(pdbEntryString); + pdbentry.setFile(pdbFile); + needtoadd = true; // add this new entry to sequence. + } + // resolve data source + // TODO: this code should be a refactored to an io package + DataSourceType protocol = AppletFormatAdapter.resolveProtocol(pdbFile, + FileFormat.PDB); + if (protocol == null) + { + return false; + } + if (needtoadd) + { + pdbentry.setProperty("protocol", protocol); + toaddpdb.addPDBId(pdbentry); + alf.alignPanel.getStructureSelectionManager() + .registerPDBEntry(pdbentry); } } - return result; + return true; } - /** - * form a complete URL given a path to a resource and a reference location on - * the same server - * - * @param targetPath - * - an absolute path on the same server as localref or a document - * located relative to localref - * @param localref - * - a URL on the same server as url - * @return a complete URL for the resource located by url - */ - public static String resolveUrlForLocalOrAbsolute(String targetPath, - URL localref) + @Override + public String arrayToSeparatorList(String[] array) { - String resolvedPath = ""; - if (targetPath.startsWith("/")) - { - String codebase = localref.toString(); - String localfile = localref.getFile(); - resolvedPath = codebase.substring(0, - codebase.length() - localfile.length()) + targetPath; - return resolvedPath; - } - - /* - * get URL path and strip off any trailing file e.g. - * www.jalview.org/examples/index.html#applets?a=b is trimmed to - * www.jalview.org/examples/ - */ - String urlPath = localref.toString(); - String directoryPath = urlPath; - int lastSeparator = directoryPath.lastIndexOf("/"); - if (lastSeparator > 0) - { - directoryPath = directoryPath.substring(0, lastSeparator + 1); - } - - if (targetPath.startsWith("/")) - { - /* - * construct absolute URL to a file on the server - this is not allowed? - */ - // String localfile = localref.getFile(); - // resolvedPath = urlPath.substring(0, - // urlPath.length() - localfile.length()) - // + targetPath; - resolvedPath = directoryPath + targetPath.substring(1); - } - else - { - resolvedPath = directoryPath + targetPath; - } - // if (debug) - // { - // System.err.println( - // "resolveUrlForLocalOrAbsolute returning " + resolvedPath); - // } - return resolvedPath; + return arrayToSeparatorList(array, separator); } /** - * parse the string into a list + * concatenate the list with separator * * @param list * @param separator - * @return elements separated by separator + * @return concatenated string */ - public static String[] separatorListToArray(String list, String separator) + public static String arrayToSeparatorList(String[] list, String separator) { - // TODO use StringUtils version (slightly different...) - int seplen = separator.length(); - if (list == null || list.equals("") || list.equals(separator)) - { - return null; - } - Vector jv = new Vector<>(); - int cp = 0, pos; - while ((pos = list.indexOf(separator, cp)) > cp) - { - jv.addElement(list.substring(cp, pos)); - cp = pos + seplen; - } - if (cp < list.length()) - { - String c = list.substring(cp); - if (!c.equals(separator)) - { - jv.addElement(c); - } - } - if (jv.size() > 0) + // TODO use StringUtils version + StringBuffer v = new StringBuffer(); + if (list != null && list.length > 0) { - String[] v = new String[jv.size()]; - for (int i = 0; i < v.length; i++) + for (int i = 0, iSize = list.length; i < iSize; i++) { - v[i] = jv.elementAt(i); + if (list[i] != null) + { + if (i > 0) + { + v.append(separator); + } + v.append(list[i]); + } } - jv.removeAllElements(); // if (debug) // { - // System.err.println("Array from '" + separator - // + "' separated List:\n" + v.length); - // for (int i = 0; i < v.length; i++) - // { - // System.err.println("item " + i + " '" + v[i] + "'"); - // } + // System.err + // .println("Returning '" + separator + "' separated List:\n"); + // System.err.println(v); // } - return v; + return v.toString(); } // if (debug) // { // System.err.println( - // "Empty Array from '" + separator + "' separated List"); + // "Returning empty '" + separator + "' separated List\n"); // } - return null; + return "" + separator; } - public static DataSourceType resolveFileProtocol(JalviewApp app, - String[] retPath) + @Override + public String getAlignment(String format) { - String path = retPath[0]; - /* - * is it paste data? - */ - if (path.startsWith("PASTE")) - { - retPath[0] = path.substring(5); - return DataSourceType.PASTE; - } + return getAlignmentFrom(null, format, null); + } - /* - * is it a URL? - */ - if (path.indexOf("://") >= 0) - { - return DataSourceType.URL; - } + @Override + public String getAlignment(String format, String suffix) + { + return getAlignmentFrom(Jalview.getCurrentAlignFrame(), format, suffix); + } - /* - * try relative to document root - */ - URL documentBase = app.getDocumentBase(); - String withDocBase = resolveUrlForLocalOrAbsolute(path, documentBase); - if (HttpUtils.isValidUrl(withDocBase)) - { - // if (debug) - // { - // System.err.println("Prepended document base '" + documentBase - // + "' to make: '" + withDocBase + "'"); - // } - retPath[0] = withDocBase; - return DataSourceType.URL; + @Override + public String getAlignmentFrom(AlignFrame alf, String format) + { + return getAlignmentFrom(alf, format, null); + } + + @Override + public String getAlignmentFrom(AlignFrame alf, String format, + String suffix) + { + try + { + if (alf == null) + { + alf = Jalview.getCurrentAlignFrame(); + } + boolean seqlimits = (suffix == null + || suffix.equalsIgnoreCase("true")); + + FileFormatI theFormat = FileFormats.getInstance().forName(format); + String reply = new AppletFormatAdapter().formatSequences(theFormat, + alf.getViewport().getAlignment(), seqlimits); + return reply; + } catch (IllegalArgumentException ex) + { + ex.printStackTrace(); + return "Error retrieving alignment, possibly invalid format specifier: " + + format; } + } - /* - * try relative to codebase (if different to document base) - */ - URL codeBase = app.getCodeBase(); - String withCodeBase = resolveUrlForLocalOrAbsolute(path, codeBase); - if (!withCodeBase.equals(withDocBase) - && HttpUtils.isValidUrl(withCodeBase)) + @Override + public String getAlignmentOrder() + { + return getAlignmentFrom(Jalview.getCurrentAlignFrame(), null); + } + + @Override + public String getAlignmentOrderFrom(AlignFrame alf) + { + return getAlignmentFrom(alf, null); + } + + @Override + public String getAlignmentOrderFrom(AlignFrame alf, String sep) + { + if (alf == null) { - // if (debug) - // { - // System.err.println("Prepended codebase '" + codeBase - // + "' to make: '" + withCodeBase + "'"); - // } - retPath[0] = withCodeBase; - return DataSourceType.URL; + alf = Jalview.getCurrentAlignFrame(); + } + AlignmentI alorder = alf.getViewport().getAlignment(); + String[] order = new String[alorder.getHeight()]; + for (int i = 0; i < order.length; i++) + { + order[i] = alorder.getSequenceAt(i).getName(); } + return arrayToSeparatorList(order, sep); + } - /* - * try locating by classloader; try this last so files in the directory - * are resolved using document base - */ - if (inArchive(app.getClass(), path)) + @Override + public String getAnnotation() + { + return getAnnotationFrom(null); + } + + @Override + public String getAnnotationFrom(AlignFrame alf) + { + if (alf == null) { - return DataSourceType.CLASSLOADER; + alf = Jalview.getCurrentAlignFrame(); + } + String annotation = new AnnotationFile() + .printAnnotationsForView(alf.getViewport()); + return annotation; + } + + @Override + public String getFeatureGroups() + { + return getFeatureGroupsOn(null); + } + + @Override + public String getFeatureGroupsOfState(boolean visible) + { + return getFeatureGroupsOfStateOn(null, visible); + } + + @Override + public String getFeatureGroupsOfStateOn(AlignFrame alf, boolean visible) + { + if (alf == null) + { + alf = Jalview.getCurrentAlignFrame(); + } + return arrayToSeparatorList(alf.getFeatureGroupsOfState(visible)); + } + + @Override + public String getFeatureGroupsOn(AlignFrame alf) + { + if (alf == null) + { + alf = Jalview.getCurrentAlignFrame(); + } + return arrayToSeparatorList(alf.getFeatureGroups()); + } + + @Override + public String getFeatures(String format) + { + return getFeaturesFrom(null, format); + } + + /** + * JavaScript interface to print the alignment frame + * + * @param alf + * @param format + * "jalview" or "gff" with or without ";includeComplement" or + * ";includeNonpositional"; default with no ";" is + * ";includeNonpositional" + * @return + */ + @Override + public String getFeaturesFrom(AlignFrame alf, String format) + { + if (alf == null) + { + alf = Jalview.getCurrentAlignFrame(); + } + String features; + FeaturesFile formatter = new FeaturesFile(); + format = format.toLowerCase(); + if (format.indexOf(";") < 0) + format += ";includenonpositional"; + boolean nonpos = format.indexOf(";includenonpositional") > 0; + boolean compl = format.indexOf(";includecomplement") >= 0; + if (format.startsWith("jalview")) + { + features = formatter.printJalviewFormat( + alf.getViewport().getAlignment().getSequencesArray(), + alf.alignPanel.getFeatureRenderer(), nonpos, compl); + } + else + { + features = formatter.printGffFormat( + alf.getViewport().getAlignment().getSequencesArray(), + alf.alignPanel.getFeatureRenderer(), nonpos, compl); + } + + if (features == null) + { + features = ""; } + return features; + + } + + @Override + public String getJsMessage(String messageclass, String viewId) + { + // TODO Auto-generated method stub return null; } /** - * Discovers whether the given file is in the Applet Archive + * read sequence1...sequenceN as a raw alignment * - * @param f - * String - * @return boolean + * @param jalviewApp + * @return */ - private static boolean inArchive(Class c, String f) + public String getPastedSequence(JalviewJSApp jalviewApp) { - // This might throw a security exception in certain browsers - // Netscape Communicator for instance. + StringBuffer data = new StringBuffer("PASTE"); + int i = 1; + String file = null; + while ((file = (String) getAppletParameter("sequence" + i, + true)) != null) + { + data.append(file.toString() + "\n"); + i++; + } + if (data.length() > 5) + { + file = data.toString(); + } + return file; + } + + /** + * + * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequences() + */ + @Override + public String getSelectedSequences() + { + return getSelectedSequencesFrom(Jalview.getCurrentAlignFrame()); + } + + /** + * + * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequences(java.lang.String) + */ + @Override + public String getSelectedSequences(String sep) + { + return getSelectedSequencesFrom(Jalview.getCurrentAlignFrame(), sep); + } + + @Override + public String getSelectedSequencesAsAlignment(String format, + String suffix) + { + return getSelectedSequencesAsAlignmentFrom(null, format, suffix); + } + + @Override + public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf, + String format, String suffix) + { + + if (alf == null) + { + alf = Jalview.getCurrentAlignFrame(); + } + + boolean seqlimits = (suffix == null || suffix.equalsIgnoreCase("true")); try { - boolean rtn = (c.getResourceAsStream("/" + f) != null); - // if (debug) - // { - // System.err.println("Resource '" + f + "' was " - // + (rtn ? "" : "not ") + "located by classloader."); - // } - return rtn; - } catch (Exception ex) + AlignViewport vp = alf.getViewport(); + FileFormatI theFormat = FileFormats.getInstance().forName(format); + if (vp.getSelectionGroup() != null) + { + // JBPNote: getSelectionAsNewSequence behaviour has changed - this + // method now returns a full copy of sequence data + // TODO consider using getSequenceSelection instead here + String reply = new AppletFormatAdapter().formatSequences(theFormat, + new Alignment(vp.getSelectionAsNewSequence()), seqlimits); + return reply; + } + } catch (IllegalArgumentException ex) { - System.out.println("Exception checking resources: " + f + " " + ex); - return false; + ex.printStackTrace(); + return "Error retrieving alignment, possibly invalid format specifier: " + + format; + } + return ""; + } + + /** + * + * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui + * .AlignFrame) + */ + @Override + public String getSelectedSequencesFrom(AlignFrame alf) + { + return getSelectedSequencesFrom(alf, null); + } + + @Override + public String getSelectedSequencesFrom(AlignFrame alf, String sep) + { + if (alf == null) + { + alf = Jalview.getCurrentAlignFrame(); + } + StringBuffer result = new StringBuffer(""); + if (sep == null || sep.length() == 0) + { + sep = separator; // "+0x00AC; + } + AlignViewport v = alf.getViewport(); + if (v.getSelectionGroup() != null) + { + SequenceI[] seqs = v.getSelectionGroup() + .getSequencesInOrder(v.getAlignment()); + + for (int i = 0; i < seqs.length; i++) + { + result.append(seqs[i].getName()); + result.append(sep); + } + } + + return result.toString(); + } + + public Object[] getSelectionForListener(AlignFrame alf, + SequenceGroup seqsel, ColumnSelection colsel, + HiddenColumns hidden, SelectionSource source, Object alignFrame) + { + if (alf == null) + { + alf = Jalview.getCurrentAlignFrame(); + } + // System.err.println("Testing selection event relay to + // jsfunction:"+_listener); + String setid = ""; + AlignFrame src = (AlignFrame) alignFrame; + if (source != null) + { + if (source instanceof AlignViewport && alf.getViewport() == source) + { + // should be valid if it just generated an event! + src = alf; + + } + } + String[] seqs = new String[] {}; + String[] cols = new String[] {}; + int strt = 0, end = (src == null) ? -1 + : src.alignPanel.av.getAlignment().getWidth(); + if (seqsel != null && seqsel.getSize() > 0) + { + seqs = new String[seqsel.getSize()]; + for (int i = 0; i < seqs.length; i++) + { + seqs[i] = seqsel.getSequenceAt(i).getName(); + } + if (strt < seqsel.getStartRes()) + { + strt = seqsel.getStartRes(); + } + if (end == -1 || end > seqsel.getEndRes()) + { + end = seqsel.getEndRes(); + } + } + if (colsel != null && !colsel.isEmpty()) + { + if (end == -1) + { + end = colsel.getMax() + 1; + } + cols = new String[colsel.getSelected().size()]; + for (int i = 0; i < cols.length; i++) + { + cols[i] = "" + (1 + colsel.getSelected().get(i).intValue()); + } + } + else + { + if (seqsel != null && seqsel.getSize() > 0) + { + // send a valid range, otherwise we send the empty selection + cols = new String[2]; + cols[0] = "" + (1 + strt) + "-" + (1 + end); + } + } + return new Object[] { src, setid, arrayToSeparatorList(seqs), + arrayToSeparatorList(cols) }; + } + + @Override + public String getSeparator() + { + return separator; + } + + /** + * + * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui + * .AlignFrame, java.lang.String) + */ + @Override + public void highlight(String sequenceId, String position, + String alignedPosition) + { + highlightIn(null, sequenceId, position, alignedPosition); + } + + @Override + public void highlightIn(AlignFrame alf, final String sequenceId, + final String position, final String alignedPosition) + { + if (alf == null) + { + alf = Jalview.getCurrentAlignFrame(); + } + // TODO: could try to highlight in all alignments if alf==null + jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher( + alf.getViewport().getAlignment().getSequencesArray()); + final SequenceI sq = matcher.findIdMatch(sequenceId); + if (sq != null) + { + int apos = -1; + try + { + apos = Integer.valueOf(position).intValue(); + apos--; + } catch (NumberFormatException ex) + { + return; + } + final int pos = apos; + // use vamsas listener to broadcast to all listeners in scope + if (alignedPosition != null && (alignedPosition.trim().length() == 0 + || alignedPosition.toLowerCase().indexOf("false") > -1)) + { + java.awt.EventQueue.invokeLater(new Runnable() + { + @Override + public void run() + { + StructureSelectionManager + .getStructureSelectionManager(Desktop.getInstance()) + .mouseOverVamsasSequence(sq, sq.findIndex(pos), null); + } + }); + } + else + { + java.awt.EventQueue.invokeLater(new Runnable() + { + @Override + public void run() + { + StructureSelectionManager + .getStructureSelectionManager(Desktop.getInstance()) + .mouseOverVamsasSequence(sq, pos, null); + } + }); + } + } + } + + public AlignFrame loadAlignment(String text, int width, int height, + String title) + { + AlignmentI al = null; + + try + { + FileFormatI format = new IdentifyFile().identify(text, + DataSourceType.PASTE); + al = new AppletFormatAdapter().readFile(text, DataSourceType.PASTE, + format); + if (al.getHeight() > 0) + { + return new AlignFrame(al, width, height, title); + } + } catch (IOException ex) + { + ex.printStackTrace(); + } + return null; + } + + // public void setMouseoverListener(String listener) + // { + // appLoader.setMouseoverListener(listener); + // } + // + // + // public void setMouseoverListener(AlignFrame af, String listener) + // { + // } + // + + @Override + public AlignFrame loadAlignment(String text, String title) + { + return loadAlignment(text, AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT, title); + } + + @Override + public void loadAnnotation(String annotation) + { + loadAnnotationFrom(null, annotation); + } + + @Override + public void loadAnnotationFrom(AlignFrame alf, String annotation) + { + if (alf == null) + { + alf = Jalview.getCurrentAlignFrame(); + } + if (new AnnotationFile().annotateAlignmentView(alf.getViewport(), + annotation, DataSourceType.PASTE)) + { + alf.alignPanel.fontChanged(); + alf.alignPanel.setScrollValues(0, 0); + } + else + { + alf.parseFeaturesFile(annotation, DataSourceType.PASTE); + } + } + + /** + * Load annotations if specified by parameter. Returns true if loaded, else + * false. + * + * + * @param alignFrame + * @return + */ + protected boolean loadAnnotations(AlignFrame af) + { + boolean result = false; + String param = (String) getAppletParameter("annotations", true); + if (param != null) + { + ret[0] = param; + DataSourceType protocol = resolveFileProtocol(ret); + param = ret[0]; + if (new AnnotationFile().annotateAlignmentView(af.getViewport(), param, + protocol)) + { + updateForAnnotations(); + result = true; + } + else + { + System.err + .println("Annotations were not added from annotation file '" + + param + "'"); + } + } + return result; + } + + //// JalviewJSApi + + /** + * Load features file and view settings as specified by parameters. Returns + * true if features were loaded, else false. + * @param + * + * @param alignFrame + * @return + */ + protected boolean loadFeatures(AlignFrame af) + { + boolean result = false; + // /////////////////////////// + // modify display of features + // we do this before any features have been loaded, ensuring any hidden + // groups are hidden when features first displayed + // + // hide specific groups + // + String param = (String) getAppletParameter("hidefeaturegroups", true); + if (param != null) + { + setFeatureGroupState(af, separatorListToArray(param, separator), false); + // setFeatureGroupStateOn(newAlignFrame, param, false); + } + // show specific groups + param = (String) getAppletParameter("showfeaturegroups", true); + if (param != null) + { + setFeatureGroupState(af, separatorListToArray(param, separator), true); + // setFeatureGroupStateOn(newAlignFrame, param, true); + } + // and now load features + param = (String) getAppletParameter("features", true); + if (param != null) + { + ret[0] = param; + DataSourceType protocol = resolveFileProtocol(ret); + + result = parseFeaturesFile(af, ret[0], protocol); + } + + param = (String) getAppletParameter("showFeatureSettings", true); + if (param != null && param.equalsIgnoreCase("true")) + { + newFeatureSettings(); + } + return result; + } + + @Override + public void loadFeatures(String features, boolean autoenabledisplay) + { + loadFeaturesFrom(null, features, autoenabledisplay); + } + + @Override + public boolean loadFeaturesFrom(AlignFrame alf, String features, + boolean autoenabledisplay) + { + if (alf == null) + { + alf = Jalview.getCurrentAlignFrame(); + } + boolean ret = alf.parseFeaturesFile(features, DataSourceType.PASTE); + if (!ret) + { + return false; + } + if (autoenabledisplay) + { + alf.getViewport().setShowSequenceFeatures(true); + // this next was for a checkbox in JalviewLite + // ((AlignFrame) alf).getViewport().sequenceFeatures.setState(true); + } + return true; + } + + /** + * Load in a Jnetfile if specified by parameter. Returns true if loaded, else + * false. + * + * @param alignFrame + * @return + */ + protected boolean loadJnetFile(AlignFrame af) + { + boolean result = false; + String param = (String) getAppletParameter("jnetfile", true); + if (param == null) + { + // jnet became jpred around 2016 + param = (String) getAppletParameter("jpredfile", true); + } + if (param != null) + { + try + { + ret[0] = param; + DataSourceType protocol = resolveFileProtocol(ret); + JPredFile predictions = new JPredFile(ret[0], protocol); + JnetAnnotationMaker.add_annotation(predictions, + af.getViewport().getAlignment(), 0, false); + // false == do not add sequence profile from concise output + af.getViewport().getAlignment().setupJPredAlignment(); + updateForAnnotations(); + result = true; + } catch (Exception ex) + { + ex.printStackTrace(); + } + } + return result; + } + + /** + * Load PDBFiles if any specified by parameter(s). Returns true if loaded, + * else false. + * + * @param loaderFrame + * @return + */ + protected boolean loadPdbFiles(AlignFrame af) + { + boolean result = false; + /* + * Undocumented for 2.6 - + * related to JAL-434 + */ + + // not supported (as for JalviewLite) + // boolean doAlign = false;//"true".equalsIgnoreCase("" + + // getAppletParameter("alignpdbfiles", false)); + // setAlignPdbStructures(doAlign); + /* + * + * + * + * + * + */ + + // Accumulate pdbs here if they are heading for the same view (if + // alignPdbStructures is true) + // ArrayList pdbs = new ArrayList<>(); + // create a lazy matcher if we're asked to + boolean relaxed = "true".equalsIgnoreCase( + "" + getAppletParameter("relaxedidmatch", false)); + jalview.analysis.SequenceIdMatcher matcher = relaxed + ? new jalview.analysis.SequenceIdMatcher( + af.getViewport().getAlignment().getSequencesArray()) + : null; + + int pdbFileCount = 0; + String param; + do + { + if (pdbFileCount > 0) + { + param = (String) getAppletParameter("PDBFILE" + pdbFileCount, true); + } + else + { + param = (String) getAppletParameter("PDBFILE", true); + } + + if (param != null) + { + PDBEntry pdb = new PDBEntry(); + + String seqstring; + SequenceI[] seqs = null; + String[] chains = null; + + StringTokenizer st = new StringTokenizer(param, " "); + + if (st.countTokens() < 2) + { + String sequence = (String) getAppletParameter("PDBSEQ", true); + if (sequence != null) + { + seqs = new SequenceI[] { matcher == null + ? (Sequence) af.getViewport().getAlignment() + .findName(sequence) + : matcher.findIdMatch(sequence) }; + } + + } + else + { + param = st.nextToken(); + List tmp = new ArrayList<>(); + List tmp2 = new ArrayList<>(); + + while (st.hasMoreTokens()) + { + seqstring = st.nextToken(); + StringTokenizer st2 = new StringTokenizer(seqstring, "="); + if (st2.countTokens() > 1) + { + // This is the chain + tmp2.add(st2.nextToken()); + seqstring = st2.nextToken(); + } + tmp.add(matcher == null + ? (Sequence) af.getViewport().getAlignment() + .findName(seqstring) + : matcher.findIdMatch(seqstring)); + } + + seqs = tmp.toArray(new SequenceI[tmp.size()]); + if (tmp2.size() == tmp.size()) + { + chains = tmp2.toArray(new String[tmp2.size()]); + } + } + pdb.setId(param); + ret[0] = param; + DataSourceType protocol = resolveFileProtocol(ret); + // TODO check JAL-357 for files in a jar (CLASSLOADER) + pdb.setFile(ret[0]); + + if (seqs != null) + { + for (int i = 0; i < seqs.length; i++) + { + if (seqs[i] != null) + { + ((Sequence) seqs[i]).addPDBId(pdb); + StructureSelectionManager + .getStructureSelectionManager( + (StructureSelectionManagerProvider) this) + .registerPDBEntry(pdb); + } + else + { + if (debug) + { + // this may not really be a problem but we give a warning + // anyway + System.err.println( + "Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence " + + i + ")"); + } + } + } + + // if (doAlign) + // { + // pdbs.add(new Object[] { pdb, seqs, chains, protocol }); + // } + // else + { + newStructureView(af, pdb, seqs, chains, protocol); + } + } + } + + pdbFileCount++; + } while (param != null || pdbFileCount < 10); + // + // if (doAlign && pdbs.size() > 0) + // { + // SequenceI[][] seqs = new SequenceI[pdbs.size()][]; + // PDBEntry[] pdb = new PDBEntry[pdbs.size()]; + // String[][] chains = new String[pdbs.size()][]; + // String[] protocols = new String[pdbs.size()]; + // for (int pdbsi = 0, pdbsiSize = pdbs + // .size(); pdbsi < pdbsiSize; pdbsi++) + // { + // Object[] o = pdbs.get(pdbsi); + // pdb[pdbsi] = (PDBEntry) o[0]; + // seqs[pdbsi] = (SequenceI[]) o[1]; + // chains[pdbsi] = (String[]) o[2]; + // protocols[pdbsi] = (String) o[3]; + // } + //// alignedStructureView(pdb, seqs, chains, protocols); + // result = true; + // } + return result; + } + + /** + * Load a score file if specified by parameter. Returns true if file was + * loaded, else false. + * + * @param loaderFrame + */ + protected boolean loadScoreFile() + { + boolean result = false; + String sScoreFile = (String) getAppletParameter("scoreFile", true); + if (sScoreFile != null && !"".equals(sScoreFile)) + { + try + { + if (debug) + { + System.err.println( + "Attempting to load T-COFFEE score file from the scoreFile parameter"); + } + result = loadScoreFile(sScoreFile); + if (!result) + { + System.err.println( + "Failed to parse T-COFFEE parameter as a valid score file ('" + + sScoreFile + "')"); + } + } catch (Exception e) + { + System.err.printf("Cannot read score file: '%s'. Cause: %s \n", + sScoreFile, e.getMessage()); + } } + return result; } - public void callInitCallback() + /** + * Load a tree for the alignment if specified by parameter. Returns true if a + * tree was loaded, else false. + * + * @return + */ + protected boolean loadTree(AlignFrame af) { - String initjscallback = app.getParameter("oninit"); - if (initjscallback == null) + boolean result = false; + String treeFile = (String) getAppletParameter("tree", true); + if (treeFile == null) { - return; + treeFile = (String) getAppletParameter("treefile", true); } - initjscallback = initjscallback.trim(); - if (initjscallback.length() > 0) + + if (treeFile != null) { - // TODO + try + { + ret[0] = treeFile; + NewickFile fin = new NewickFile(treeFile, resolveFileProtocol(ret)); + fin.parse(); + + if (fin.getTree() != null) + { + loadTree(af, fin, ret[0]); + result = true; + if (debug) + { + System.out.println("Successfully imported tree."); + } + } + else + { + if (debug) + { + System.out.println( + "Tree parameter did not resolve to a valid tree."); + } + } + } catch (Exception ex) + { + ex.printStackTrace(); + } } + return result; } /** - * read sequence1...sequenceN as a raw alignment + * public static method for JalviewJS API to open a PCAPanel without + * necessarily using a dialog. * - * @param jalviewApp - * @return + * @param af + * @param modelName + * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences" + * if number of sequences selected is inappropriate */ - public String getPastedSequence(JalviewApp jalviewApp) + @Override + public Object openPcaPanel(AlignFrame af, String modelName) { - StringBuffer data = new StringBuffer("PASTE"); - int i = 1; - String file = null; - while ((file = app.getParameter("sequence" + i)) != null) + if (af == null) { - data.append(file.toString() + "\n"); - i++; - } - if (data.length() > 5) - { - file = data.toString(); + af = Jalview.getCurrentAlignFrame(); } - return file; + return CalculationChooser.openPcaPanel(af, modelName, null); } /** - * concatenate the list with separator + * Open a new Tree panel on the desktop statically. Params are standard (not + * set by Groovy). No dialog is opened. * - * @param list - * @param separator - * @return concatenated string + * @param af + * @param treeType + * @param modelName + * @return null, or the string "label.you_need_at_least_n_sequences" if number + * of sequences selected is inappropriate */ - public static String arrayToSeparatorList(String[] list, String separator) + @Override + public Object openTreePanel(AlignFrame af, String treeType, + String modelName) { - // TODO use StringUtils version - StringBuffer v = new StringBuffer(); - if (list != null && list.length > 0) + if (af == null) { - for (int i = 0, iSize = list.length; i < iSize; i++) - { - if (list[i] != null) - { - if (i > 0) - { - v.append(separator); - } - v.append(list[i]); - } - } - // if (debug) - // { - // System.err - // .println("Returning '" + separator + "' separated List:\n"); - // System.err.println(v); - // } - return v.toString(); + af = Jalview.getCurrentAlignFrame(); } - // if (debug) - // { - // System.err.println( - // "Returning empty '" + separator + "' separated List\n"); - // } - return "" + separator; - } - - public String arrayToSeparatorList(String[] array) - { - return arrayToSeparatorList(array, separator); + return CalculationChooser.openTreePanel(af, treeType, modelName, null); } - public String getSelectedSequencesFrom(AlignFrame alf, String sep) + @Override + public String orderAlignmentBy(AlignFrame alf, String order, + String undoName, String sep) { - StringBuffer result = new StringBuffer(""); if (sep == null || sep.length() == 0) { - sep = separator; // "+0x00AC; + sep = separator; } - AlignViewport v = alf.getViewport(); - if (v.getSelectionGroup() != null) + String[] ids = separatorListToArray(order, sep); + SequenceI[] sqs = null; + if (ids != null && ids.length > 0) { - SequenceI[] seqs = v.getSelectionGroup() - .getSequencesInOrder(v.getAlignment()); - - for (int i = 0; i < seqs.length; i++) + if (alf == null) { - result.append(seqs[i].getName()); - result.append(sep); + alf = Jalview.getCurrentAlignFrame(); + } + jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher( + alf.getViewport().getAlignment().getSequencesArray()); + int s = 0; + sqs = new SequenceI[ids.length]; + for (int i = 0; i < ids.length; i++) + { + if (ids[i].trim().length() == 0) + { + continue; + } + SequenceI sq = matcher.findIdMatch(ids[i]); + if (sq != null) + { + sqs[s++] = sq; + } + } + if (s > 0) + { + SequenceI[] sqq = new SequenceI[s]; + System.arraycopy(sqs, 0, sqq, 0, s); + sqs = sqq; + } + else + { + sqs = null; } } + if (sqs == null) + { + return ""; + } + ; + final AlignmentOrder aorder = new AlignmentOrder(sqs); - return result.toString(); + if (undoName != null && undoName.trim().length() == 0) + { + undoName = null; + } + final String _undoName = undoName; + // TODO: deal with synchronization here: cannot raise any events until after + // this has returned. + return alf.sortBy(aorder, _undoName) ? "true" : ""; } - public void setFeatureGroupStateOn(final AlignFrame alf, - final String groups, boolean state) + @Override + public String orderBy(String order, String undoName) { - java.awt.EventQueue.invokeLater(new Runnable() - { - @Override - public void run() - { - alf.setFeatureGroupState( - separatorListToArray(groups, separator), state); - } - }); + return orderBy(order, undoName, null); } - public String getFeatureGroupsOfStateOn(AlignFrame alf, boolean visible) + @Override + public String orderBy(String order, String undoName, String sep) { - return arrayToSeparatorList( - alf.getFeatureGroupsOfState(visible)); + return orderAlignmentBy(Jalview.getCurrentAlignFrame(), order, undoName, + sep); } - public void scrollViewToIn(final AlignFrame alf, final String topRow, - final String leftHandColumn) + /** + * Allow an outside entity to initiate the second half of argument parsing + * (only). + * + * @param args + * @return null is good + */ + @Override + public Object parseArguments(String[] args) { - // TODO test - java.awt.EventQueue.invokeLater(new Runnable() - { - @Override - public void run() - { - try - { - alf.scrollTo(Integer.valueOf(topRow).intValue(), - Integer.valueOf(leftHandColumn).intValue()); - } catch (Exception ex) - { - System.err.println("Couldn't parse integer arguments (topRow='" - + topRow + "' and leftHandColumn='" + leftHandColumn - + "')"); - ex.printStackTrace(); - } - } - }); + try + { + Jalview.getInstance().parseArguments(new ArgsParser(args), false); + return null; + } catch (Throwable t) + { + return t; + } } - public void scrollViewToRowIn(final AlignFrame alf, final String topRow) + @Override + public void removeSelectionListener(AlignFrame af, String listener) { - // TODO test - java.awt.EventQueue.invokeLater(new Runnable() + List listeners = Desktop + .getStructureSelectionManager().getListeners(); + for (int i = listeners.size(); --i >= 0;) { - @Override - public void run() + SelectionListener l = listeners.get(i); + if (l instanceof JsSelectionListener + && ((JsSelectionListener) l).isFor(af, listener)) { - try - { - alf.scrollToRow(Integer.valueOf(topRow).intValue()); - - } catch (Exception ex) - { - System.err.println("Couldn't parse integer arguments (topRow='" - + topRow + "')"); - ex.printStackTrace(); - } - + listeners.remove(i); + break; } - }); + } } + @Override public void scrollViewToColumnIn(final AlignFrame alf, final String leftHandColumn) { - // TODO test java.awt.EventQueue.invokeLater(new Runnable() { @@ -864,8 +1482,9 @@ public class JalviewAppLoader { try { - alf - .scrollToColumn(Integer.valueOf(leftHandColumn).intValue()); + (alf == null ? Jalview.getCurrentAlignFrame() : alf) + .scrollToColumn( + Integer.valueOf(leftHandColumn).intValue()); } catch (Exception ex) { @@ -875,145 +1494,115 @@ public class JalviewAppLoader ex.printStackTrace(); } } - }); - - } - - public boolean addPdbFile(AlignFrame alf, String sequenceId, - String pdbEntryString, String pdbFile) - { - AlignFrame alFrame = alf; - SequenceI toaddpdb = alFrame.getViewport().getAlignment() - .findName(sequenceId); - boolean needtoadd = false; - if (toaddpdb != null) - { - Vector pdbe = toaddpdb.getAllPDBEntries(); - PDBEntry pdbentry = null; - if (pdbe != null && pdbe.size() > 0) - { - for (int pe = 0, peSize = pdbe.size(); pe < peSize; pe++) - { - pdbentry = pdbe.elementAt(pe); - if (!pdbentry.getId().equals(pdbEntryString) - && !pdbentry.getFile().equals(pdbFile)) - { - pdbentry = null; - } - else - { - continue; - } - } - } - if (pdbentry == null) - { - pdbentry = new PDBEntry(); - pdbentry.setId(pdbEntryString); - pdbentry.setFile(pdbFile); - needtoadd = true; // add this new entry to sequence. - } - // resolve data source - // TODO: this code should be a refactored to an io package - DataSourceType protocol = AppletFormatAdapter.resolveProtocol(pdbFile, - FileFormat.PDB); - if (protocol == null) - { - return false; - } - if (needtoadd) - { - pdbentry.setProperty("protocol", protocol); - toaddpdb.addPDBId(pdbentry); - alFrame.alignPanel.getStructureSelectionManager() - .registerPDBEntry(pdbentry); - } - } - return true; + }); + } - public AlignFrame loadAlignment(String text, int width, int height, - String title) + @Override + public void scrollViewToIn(final AlignFrame alf, final String topRow, + final String leftHandColumn) { - AlignmentI al = null; - - try + // TODO test + java.awt.EventQueue.invokeLater(new Runnable() { - FileFormatI format = new IdentifyFile().identify(text, - DataSourceType.PASTE); - al = new AppletFormatAdapter().readFile(text, DataSourceType.PASTE, - format); - if (al.getHeight() > 0) + @Override + public void run() { - return new AlignFrame(al, width, height, title); + try + { + (alf == null ? Jalview.getCurrentAlignFrame() : alf).scrollTo( + Integer.valueOf(topRow).intValue(), + Integer.valueOf(leftHandColumn).intValue()); + + } catch (Exception ex) + { + System.err.println("Couldn't parse integer arguments (topRow='" + + topRow + "' and leftHandColumn='" + leftHandColumn + + "')"); + ex.printStackTrace(); + } } - } catch (IOException ex) - { - ex.printStackTrace(); - } - return null; + }); } - public String getFeatureGroupsOn(AlignFrame alf) + @Override + public void scrollViewToRowIn(final AlignFrame alf, final String topRow) { - return arrayToSeparatorList( - alf.getFeatureGroups()); - } + // TODO test - public void highlightIn(final AlignFrame alf, final String sequenceId, - final String position, final String alignedPosition) - { - // TODO: could try to highlight in all alignments if alf==null - jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher( - alf.getViewport().getAlignment() - .getSequencesArray()); - final SequenceI sq = matcher.findIdMatch(sequenceId); - if (sq != null) + java.awt.EventQueue.invokeLater(new Runnable() { - int apos = -1; - try - { - apos = Integer.valueOf(position).intValue(); - apos--; - } catch (NumberFormatException ex) - { - return; - } - final int pos = apos; - // use vamsas listener to broadcast to all listeners in scope - if (alignedPosition != null && (alignedPosition.trim().length() == 0 - || alignedPosition.toLowerCase().indexOf("false") > -1)) + @Override + public void run() { - java.awt.EventQueue.invokeLater(new Runnable() + try { - @Override - public void run() - { - StructureSelectionManager - .getStructureSelectionManager(Desktop.getInstance()) - .mouseOverVamsasSequence(sq, sq.findIndex(pos), null); - } - }); - } - else - { - java.awt.EventQueue.invokeLater(new Runnable() + (alf == null ? Jalview.getCurrentAlignFrame() : alf) + .scrollToRow(Integer.valueOf(topRow).intValue()); + + } catch (Exception ex) { - @Override - public void run() - { - StructureSelectionManager - .getStructureSelectionManager(Desktop.getInstance()) - .mouseOverVamsasSequence(sq, pos, null); - } - }); + System.err.println("Couldn't parse integer arguments (topRow='" + + topRow + "')"); + ex.printStackTrace(); + } + } - } + }); + } + + @Override + public void select(String sequenceIds, String columns) + { + selectIn(Jalview.getCurrentAlignFrame(), sequenceIds, columns, null); } - public void selectIn(final AlignFrame alf, String sequenceIds, - String columns, String sep) + @Override + public void select(String sequenceIds, String columns, String sep) { + selectIn(null, sequenceIds, columns, sep); + } + + // @Override + // public AlignFrame newView() + // { + // return newViewFrom(null, null); + // } + // + // @Override + // public AlignFrame newView(String name) + // { + // return newViewFrom(null, name); + // } + // + // @Override + // public AlignFrame newViewFrom(AlignFrame alf) + // { + // return newViewFrom(alf, null); + // } + // + // @Override + // public AlignFrame newViewFrom(AlignFrame alf, String name) + // { + // if (alf == null) + // { + // alf = Jalview.getCurrentAlignFrame(); + // } + // return appLoader.newViewFrom(alf, name); + // } + + @Override + public void selectIn(AlignFrame alf, String sequenceIds, String columns) + { + selectIn(alf, sequenceIds, columns, null); + } + + @Override + public void selectIn(AlignFrame af, String sequenceIds, String columns, + String sep) + { + AlignFrame alf = (af == null ? Jalview.getCurrentAlignFrame() : af); + if (sep == null || sep.length() == 0) { sep = separator; @@ -1027,14 +1616,13 @@ public class JalviewAppLoader } } // deparse fields - String[] ids = JalviewAppLoader.separatorListToArray(sequenceIds, sep); - String[] cols = JalviewAppLoader.separatorListToArray(columns, sep); + String[] ids = separatorListToArray(sequenceIds, sep); + String[] cols = separatorListToArray(columns, sep); final SequenceGroup sel = new SequenceGroup(); final ColumnSelection csel = new ColumnSelection(); AlignmentI al = alf.getViewport().getAlignment(); jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher( - alf.getViewport().getAlignment() - .getSequencesArray()); + alf.getViewport().getAlignment().getSequencesArray()); int start = 0, end = al.getWidth(), alw = al.getWidth(); boolean seqsfound = true; if (ids != null && ids.length > 0) @@ -1218,283 +1806,411 @@ public class JalviewAppLoader @Override public void run() { - alf.select(sel, csel, alf - .getCurrentView().getAlignment().getHiddenColumns()); + alf.select(sel, csel, + alf.getCurrentView().getAlignment().getHiddenColumns()); } }); } } - public String getAlignmentOrderFrom(AlignFrame alf, String sep) + // public AlignFrame newViewFrom(AlignFrame alf, String name) + // { + // return (AlignFrame) alf.newView(name, true); + // } + // + @Override + public String[] separatorListToArray(String list) { - AlignmentI alorder = alf.getViewport().getAlignment(); - String[] order = new String[alorder.getHeight()]; - for (int i = 0; i < order.length; i++) - { - order[i] = alorder.getSequenceAt(i).getName(); - } - return arrayToSeparatorList(order, sep); + return separatorListToArray(list, separator); } - public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf, - String format, String suffix) + @Override + public void setFeatureGroupState(String groups, boolean state) + { // JalviewLite API + setFeatureGroupStateOn(null, groups, state); + } + + @Override + public void setFeatureGroupStateOn(final AlignFrame alf, + final String groups, boolean state) { - try + + java.awt.EventQueue.invokeLater(new Runnable() { - AlignViewport vp = alf.getViewport(); - FileFormatI theFormat = FileFormats.getInstance().forName(format); - boolean seqlimits = (suffix == null - || suffix.equalsIgnoreCase("true")); - if (vp.getSelectionGroup() != null) + @Override + public void run() { - // JBPNote: getSelectionAsNewSequence behaviour has changed - this - // method now returns a full copy of sequence data - // TODO consider using getSequenceSelection instead here - String reply = new AppletFormatAdapter().formatSequences(theFormat, - new Alignment(vp.getSelectionAsNewSequence()), - seqlimits); - return reply; + (alf == null ? Jalview.getCurrentAlignFrame() : alf) + .setFeatureGroupState( + separatorListToArray(groups, separator), state); } - } catch (IllegalArgumentException ex) + }); + } + + @Override + public void setSelectionListener(AlignFrame af, String listener) + { + Desktop.getStructureSelectionManager() + .addSelectionListener(new JsSelectionListener(af, listener)); + } + + @Override + public void setSelectionListener(String listener) + { + Desktop.getStructureSelectionManager() + .addSelectionListener(new JsSelectionListener(null, listener)); + } + + @Override + public void setSeparator(String separator) + { + this.separator = separator; + } + + @Override + public void showOverview() + { + Jalview.getCurrentAlignFrame().overviewMenuItem_actionPerformed(null); + } + + /** + * Allowing for a JavaScript function here. + */ + public void callInitCallback() + { + Object initjscallback = getAppletParameter("oninit", false); + if (initjscallback != null) { - ex.printStackTrace(); - return "Error retrieving alignment, possibly invalid format specifier: " - + format; + try + { + doSendCallback(initjscallback, new Object[0]); + } catch (Exception e) + { + System.err.println("Exception when executing _oninit callback '" + + initjscallback + "'."); + e.printStackTrace(); + } + } + } + + /** + * Pass the provided array prepended with Jalview.this + * + * Appropriated from org.jmol.appletjs.Jmol + * + * @param callback + * a window function or "alert" + * @param data + * @return String return from the callback method. + */ + public String doSendCallback(Object callback, Object[] data) + { + Jalview me = Jalview.getInstance(); + + if (me != null && callback != null) + { + /** + * @j2sNative + * + * try{ + * + * if (callback == "alert") { alert(data[0]); return ""; } var + * o; if (typeof callback == "function") { o = callback; } else + * { if (!callback)return; var tokens = callback.split("."); o + * = window[tokens[0]]; for (var i = 1; i < tokens.length; i++) + * o = o[tokens[i]]; } var a = [me]; for (var i = 0; i < + * data.length; i++) a.push(data[i] ? data[i].booleanValue && + * (data[i] = data[i].booleanValue()) : data[i]); return + * o.apply(null,a) } catch (e) { System.out.println(callback + + * " failed " + e); } + */ } return ""; } - public String orderAlignmentBy(AlignFrame alf, String order, - String undoName, String sep) + private DataSourceType resolveFileProtocol(String[] retPath) { - if (sep == null || sep.length() == 0) + String path = retPath[0]; + /* + * is it paste data? + */ + if (path.startsWith("PASTE")) { - sep = separator; + retPath[0] = path.substring(5); + return DataSourceType.PASTE; } - String[] ids = JalviewAppLoader.separatorListToArray(order, sep); - SequenceI[] sqs = null; - if (ids != null && ids.length > 0) + + /* + * is it a URL? + */ + if (path.indexOf("://") >= 0) { - jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher( - alf.getViewport().getAlignment() - .getSequencesArray()); - int s = 0; - sqs = new SequenceI[ids.length]; - for (int i = 0; i < ids.length; i++) - { - if (ids[i].trim().length() == 0) - { - continue; - } - SequenceI sq = matcher.findIdMatch(ids[i]); - if (sq != null) - { - sqs[s++] = sq; - } - } - if (s > 0) - { - SequenceI[] sqq = new SequenceI[s]; - System.arraycopy(sqs, 0, sqq, 0, s); - sqs = sqq; - } - else - { - sqs = null; - } + return DataSourceType.URL; } - if (sqs == null) + + /* + * try relative to document root + */ + URL documentBase = getDocumentBase(); + String withDocBase = resolveUrlForLocalOrAbsolute(path, documentBase); + if (HttpUtils.isValidUrl(withDocBase)) + { + // if (debug) + // { + // System.err.println("Prepended document base '" + documentBase + // + "' to make: '" + withDocBase + "'"); + // } + retPath[0] = withDocBase; + return DataSourceType.URL; + } + + /* + * try relative to codebase (if different to document base) + */ + URL codeBase = getCodeBase(); + String withCodeBase = resolveUrlForLocalOrAbsolute(path, codeBase); + if (!withCodeBase.equals(withDocBase) + && HttpUtils.isValidUrl(withCodeBase)) { - return ""; + // if (debug) + // { + // System.err.println("Prepended codebase '" + codeBase + // + "' to make: '" + withCodeBase + "'"); + // } + retPath[0] = withCodeBase; + return DataSourceType.URL; } - ; - final AlignmentOrder aorder = new AlignmentOrder(sqs); - if (undoName != null && undoName.trim().length() == 0) + /* + * try locating by classloader; try this last so files in the directory + * are resolved using document base + */ + if (inArchive(getClass(), path)) { - undoName = null; + return DataSourceType.CLASSLOADER; } - final String _undoName = undoName; - // TODO: deal with synchronization here: cannot raise any events until after - // this has returned. - return alf.sortBy(aorder, _undoName) ? "true" : ""; + return null; } - public String getAlignmentFrom(AlignFrame alf, String format, - String suffix) + /** + * Discovers whether the given file is in the Applet Archive + * + * @param f + * String + * @return boolean + */ + private static boolean inArchive(Class c, String f) { + // This might throw a security exception in certain browsers + // Netscape Communicator for instance. try { - boolean seqlimits = (suffix == null - || suffix.equalsIgnoreCase("true")); - - FileFormatI theFormat = FileFormats.getInstance().forName(format); - String reply = new AppletFormatAdapter().formatSequences(theFormat, - alf.getViewport().getAlignment(), seqlimits); - return reply; - } catch (IllegalArgumentException ex) + boolean rtn = (c.getResourceAsStream("/" + f) != null); + return rtn; + } catch (Exception ex) { - ex.printStackTrace(); - return "Error retrieving alignment, possibly invalid format specifier: " - + format; + System.out.println("Exception checking resources: " + f + " " + ex); + return false; } } - public void loadAnnotationFrom(AlignFrame alf, String annotation) + /** + * form a complete URL given a path to a resource and a reference location on + * the same server + * + * @param targetPath + * - an absolute path on the same server as localref or a document + * located relative to localref + * @param localref + * - a URL on the same server as url + * @return a complete URL for the resource located by url + */ + public static String resolveUrlForLocalOrAbsolute(String targetPath, + URL localref) { - if (new AnnotationFile().annotateAlignmentView( - alf.getViewport(), annotation, - DataSourceType.PASTE)) + String resolvedPath = ""; + if (targetPath.startsWith("/")) { - alf.alignPanel.fontChanged(); - alf.alignPanel.setScrollValues(0, 0); + String codebase = localref.toString(); + String localfile = localref.getFile(); + resolvedPath = codebase.substring(0, + codebase.length() - localfile.length()) + targetPath; + return resolvedPath; } - else + + /* + * get URL path and strip off any trailing file e.g. + * www.jalview.org/examples/index.html#applets?a=b is trimmed to + * www.jalview.org/examples/ + */ + String urlPath = localref.toString(); + String directoryPath = urlPath; + int lastSeparator = directoryPath.lastIndexOf("/"); + if (lastSeparator > 0) { - alf.parseFeaturesFile(annotation, - DataSourceType.PASTE); + directoryPath = directoryPath.substring(0, lastSeparator + 1); } - } - public boolean loadFeaturesFrom(AlignFrame alf, String features, - boolean autoenabledisplay) - { - boolean ret = alf.parseFeaturesFile(features, - DataSourceType.PASTE); - if (!ret) + if (targetPath.startsWith("/")) { - return false; + /* + * construct absolute URL to a file on the server - this is not allowed? + */ + // String localfile = localref.getFile(); + // resolvedPath = urlPath.substring(0, + // urlPath.length() - localfile.length()) + // + targetPath; + resolvedPath = directoryPath + targetPath.substring(1); } - if (autoenabledisplay) + else { - alf.getViewport().setShowSequenceFeatures(true); - // this next was for a checkbox in JalviewLite - // ((AlignFrame) alf).getViewport().sequenceFeatures.setState(true); + resolvedPath = directoryPath + targetPath; } - return true; + // if (debug) + // { + // System.err.println( + // "resolveUrlForLocalOrAbsolute returning " + resolvedPath); + // } + return resolvedPath; } /** - * JavaScript interface to print the alignment frame + * parse the string into a list * - * @param alf - * @param format - * "jalview" or "gff" with or without ";includeComplement" or - * ";includeNonpositional"; default with no ";" is - * ";includeNonpositional" - * @return + * @param list + * @param separator + * @return elements separated by separator */ - public String getFeaturesFrom(AlignFrame alf, String format) + public static String[] separatorListToArray(String list, String separator) { - AlignFrame f = (alf); - - String features; - FeaturesFile formatter = new FeaturesFile(); - format = format.toLowerCase(); - if (format.indexOf(";") < 0) - format += ";includenonpositional"; - boolean nonpos = format.indexOf(";includenonpositional") > 0; - boolean compl = format.indexOf(";includecomplement") >= 0; - if (format.startsWith("jalview")) + // TODO use StringUtils version (slightly different...) + int seplen = separator.length(); + if (list == null || list.equals("") || list.equals(separator)) { - features = formatter.printJalviewFormat( - f.getViewport().getAlignment().getSequencesArray(), - f.alignPanel.getFeatureRenderer(), nonpos, compl); + return null; } - else + Vector jv = new Vector<>(); + int cp = 0, pos; + while ((pos = list.indexOf(separator, cp)) > cp) { - features = formatter.printGffFormat( - f.getViewport().getAlignment().getSequencesArray(), - f.alignPanel.getFeatureRenderer(), nonpos, compl); + jv.addElement(list.substring(cp, pos)); + cp = pos + seplen; } - - if (features == null) + if (cp < list.length()) { - features = ""; + String c = list.substring(cp); + if (!c.equals(separator)) + { + jv.addElement(c); + } } - return features; - + if (jv.size() > 0) + { + String[] v = new String[jv.size()]; + for (int i = 0; i < v.length; i++) + { + v[i] = jv.elementAt(i); + } + jv.removeAllElements(); + return v; + } + return null; } - public String getAnnotationFrom(AlignFrame alf) + public class JsSelectionListener + implements jalview.structure.SelectionListener { - AlignFrame f = alf; - String annotation = new AnnotationFile() - .printAnnotationsForView(f.getViewport()); - return annotation; - } - // public AlignFrame newViewFrom(AlignFrame alf, String name) - // { - // return (AlignFrame) alf.newView(name, true); - // } - // - public String[] separatorListToArray(String list) - { - return separatorListToArray(list, separator); - } + AlignFrame _af; - public Object[] getSelectionForListener(AlignFrame currentFrame, - SequenceGroup seqsel, ColumnSelection colsel, - HiddenColumns hidden, SelectionSource source, Object alignFrame) - { - // System.err.println("Testing selection event relay to - // jsfunction:"+_listener); - String setid = ""; - AlignFrame src = (AlignFrame) alignFrame; - if (source != null) - { - if (source instanceof AlignViewport - && currentFrame.getViewport() == source) - { - // should be valid if it just generated an event! - src = currentFrame; + String _listener; - } + public JsSelectionListener(AlignFrame af, String listener) + { + _af = af; + _listener = listener; } - String[] seqs = new String[] {}; - String[] cols = new String[] {}; - int strt = 0, end = (src == null) ? -1 - : src.alignPanel.av.getAlignment().getWidth(); - if (seqsel != null && seqsel.getSize() > 0) + + @Override + public void selection(SequenceGroup seqsel, ColumnSelection colsel, + HiddenColumns hidden, SelectionSource source) { - seqs = new String[seqsel.getSize()]; - for (int i = 0; i < seqs.length; i++) + // System.err.println("Testing selection event relay to + // jsfunction:"+_listener); + String setid = ""; + AlignFrame src = _af; + if (source != null) { - seqs[i] = seqsel.getSequenceAt(i).getName(); - } - if (strt < seqsel.getStartRes()) - { - strt = seqsel.getStartRes(); + if (source instanceof AlignViewport + && Jalview.getCurrentAlignFrame().getViewport() == source) + { + src = Jalview.getCurrentAlignFrame(); + if (src != _af) + return; + } } - if (end == -1 || end > seqsel.getEndRes()) + String[] seqs = new String[] {}; + String[] cols = new String[] {}; + int strt = 0, end = (src == null) ? -1 + : src.alignPanel.av.getAlignment().getWidth(); + if (seqsel != null && seqsel.getSize() > 0) { - end = seqsel.getEndRes(); + seqs = new String[seqsel.getSize()]; + for (int i = 0; i < seqs.length; i++) + { + seqs[i] = seqsel.getSequenceAt(i).getName(); + } + if (strt < seqsel.getStartRes()) + { + strt = seqsel.getStartRes(); + } + if (end == -1 || end > seqsel.getEndRes()) + { + end = seqsel.getEndRes(); + } } - } - if (colsel != null && !colsel.isEmpty()) - { - if (end == -1) + if (colsel != null && !colsel.isEmpty()) { - end = colsel.getMax() + 1; + if (end == -1) + { + end = colsel.getMax() + 1; + } + cols = new String[colsel.getSelected().size()]; + for (int i = 0; i < cols.length; i++) + { + cols[i] = "" + (1 + colsel.getSelected().get(i).intValue()); + } } - cols = new String[colsel.getSelected().size()]; - for (int i = 0; i < cols.length; i++) + else { - cols[i] = "" + (1 + colsel.getSelected().get(i).intValue()); + if (seqsel != null && seqsel.getSize() > 0) + { + // send a valid range, otherwise we send the empty selection + cols = new String[2]; + cols[0] = "" + (1 + strt) + "-" + (1 + end); + } + ; + } + + Jalview jalview = Jalview.getInstance(); + jalview.doSendCallback(_listener, + new Object[] + { src, setid, jalview.arrayToSeparatorList(seqs), + jalview.arrayToSeparatorList(cols) }); } - else + + public boolean isFor(AlignFrame af, String listener) { - if (seqsel != null && seqsel.getSize() > 0) - { - // send a valid range, otherwise we send the empty selection - cols = new String[2]; - cols[0] = "" + (1 + strt) + "-" + (1 + end); - } + return _af == af && _listener.contentEquals(listener); } - return new Object[] { src, setid, arrayToSeparatorList(seqs), - arrayToSeparatorList(cols) }; + + } + + @Override + public AlignViewportI getViewport() + { + return Jalview.getCurrentAlignFrame().getViewport(); } -} \ No newline at end of file +} diff --git a/src/jalview/javascript/JSFunctionExec.java b/src/jalview/appletgui/js/JSFunctionExec.java similarity index 99% rename from src/jalview/javascript/JSFunctionExec.java rename to src/jalview/appletgui/js/JSFunctionExec.java index 29f3fa9..247552b 100644 --- a/src/jalview/javascript/JSFunctionExec.java +++ b/src/jalview/appletgui/js/JSFunctionExec.java @@ -18,7 +18,7 @@ * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ -package jalview.javascript; +package jalview.appletgui.js; import jalview.bin.JalviewLite; diff --git a/src/jalview/javascript/JalviewLiteJsApi.java b/src/jalview/appletgui/js/JalviewLiteJsApi.java similarity index 99% rename from src/jalview/javascript/JalviewLiteJsApi.java rename to src/jalview/appletgui/js/JalviewLiteJsApi.java index b5811aa..f62beeb 100644 --- a/src/jalview/javascript/JalviewLiteJsApi.java +++ b/src/jalview/appletgui/js/JalviewLiteJsApi.java @@ -18,7 +18,7 @@ * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ -package jalview.javascript; +package jalview.appletgui.js; import jalview.appletgui.AlignFrame; @@ -455,7 +455,7 @@ public interface JalviewLiteJsApi * - separator separated list of PDB file URIs that this viewer is * handling. These files must be in the same order they appear in * Jmol (e.g. first one is frame 1, second is frame 2, etc). - * @see jalview.javascript.MouseOverStructureListener + * @see jalview.appletgui.js.MouseOverStructureListener */ public abstract void setStructureListener(String listener, String modelSet); diff --git a/src/jalview/javascript/JsCallBack.java b/src/jalview/appletgui/js/JsCallBack.java similarity index 97% rename from src/jalview/javascript/JsCallBack.java rename to src/jalview/appletgui/js/JsCallBack.java index 76d6e8d..2fe4dac 100644 --- a/src/jalview/javascript/JsCallBack.java +++ b/src/jalview/appletgui/js/JsCallBack.java @@ -18,7 +18,7 @@ * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ -package jalview.javascript; +package jalview.appletgui.js; public interface JsCallBack { diff --git a/src/jalview/javascript/JsSelectionSender.java b/src/jalview/appletgui/js/JsSelectionSender.java similarity index 99% rename from src/jalview/javascript/JsSelectionSender.java rename to src/jalview/appletgui/js/JsSelectionSender.java index c2a963e..b774813 100644 --- a/src/jalview/javascript/JsSelectionSender.java +++ b/src/jalview/appletgui/js/JsSelectionSender.java @@ -18,7 +18,7 @@ * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ -package jalview.javascript; +package jalview.appletgui.js; import jalview.appletgui.AlignFrame; import jalview.bin.JalviewLite; diff --git a/src/jalview/javascript/MouseOverListener.java b/src/jalview/appletgui/js/MouseOverListener.java similarity index 99% rename from src/jalview/javascript/MouseOverListener.java rename to src/jalview/appletgui/js/MouseOverListener.java index 6a4d0f8..59c13eb 100644 --- a/src/jalview/javascript/MouseOverListener.java +++ b/src/jalview/appletgui/js/MouseOverListener.java @@ -18,7 +18,7 @@ * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ -package jalview.javascript; +package jalview.appletgui.js; import jalview.appletgui.AlignFrame; import jalview.bin.JalviewLite; diff --git a/src/jalview/javascript/MouseOverStructureListener.java b/src/jalview/appletgui/js/MouseOverStructureListener.java similarity index 99% rename from src/jalview/javascript/MouseOverStructureListener.java rename to src/jalview/appletgui/js/MouseOverStructureListener.java index 6071933..7a16009 100644 --- a/src/jalview/javascript/MouseOverStructureListener.java +++ b/src/jalview/appletgui/js/MouseOverStructureListener.java @@ -18,12 +18,13 @@ * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ -package jalview.javascript; +package jalview.appletgui.js; import jalview.api.AlignmentViewPanel; import jalview.api.FeatureRenderer; import jalview.api.SequenceRenderer; import jalview.appletgui.AlignFrame; +import jalview.appletgui.js.JsCallBack; import jalview.bin.JalviewLite; import jalview.datamodel.SequenceI; import jalview.ext.jmol.JmolCommands; diff --git a/src/jalview/bin/AppletParams.java b/src/jalview/bin/AppletParams.java index 6a23c39..a6c87b1 100644 --- a/src/jalview/bin/AppletParams.java +++ b/src/jalview/bin/AppletParams.java @@ -1,10 +1,11 @@ -package jalview.bin; -import jalview.gui.Preferences; +package jalview.bin; import java.util.HashMap; +import java.util.List; import java.util.Map; -import java.util.Vector; + +import jalview.gui.Preferences; /** * Collection of all known applet tags from JalviewLite @@ -13,7 +14,7 @@ import java.util.Vector; * */ @SuppressWarnings("serial") -public class AppletParams extends HashMap +public class AppletParams extends HashMap { private final static String[] params = { "alignpdbfiles", @@ -37,18 +38,10 @@ public class AppletParams extends HashMap "userDefinedColour", "widthScale", "windowHeight", "windowWidth", "wrap", }; - public AppletParams(Map info) - { - for (int i = params.length; --i >= 0;) - { - put(params[i], info.get(params[i])); - } - } - public String getParam(String param, String def) { - String val = get(param); - return (val != null ? val : def); + Object val = get(param); + return (val != null ? val.toString() : def); } // public AppletParams() { - // TODO Auto-generated constructor stub + } + + public static AppletParams getAppletParams(Map map, + List vargs) + { + AppletParams appletParams = new AppletParams(); + String resourcePath = getString(map, "resourcePath"); + if (resourcePath == null) + resourcePath = ""; + if (resourcePath.length() > 0 && !resourcePath.endsWith("/")) + { + resourcePath += "/"; + } + for (int i = params.length; --i >= 0;) + { + String prefName = params[i]; + Object value = map.get(prefName); + if (value != null) + addParam(vargs, prefName, value, appletParams, resourcePath); + } + return appletParams; + } + + private static String getString(Map map, String key) + { + Object o = map.get(key); + return (o == null ? null : o.toString()); } public static AppletParams getAppletParams(String[] args, - Vector vargs) + List vargs) { AppletParams appletParams = new AppletParams(); - String resourcePath = null; + String resourcePath = ""; for (int i = args.length; --i > 0;) // > 0 is correct, not >=0 { if (args[i].startsWith("name=\"Info.resourcePath\"")) @@ -129,265 +148,271 @@ public class AppletParams extends HashMap if (arg.startsWith("name=")) { String prefName = getAttr(arg, "name"); - String appletName = prefName.toLowerCase(); - String argName = prefName; String value = getAttr(arg, "value"); + addParam(vargs, prefName, value, appletParams, resourcePath); + } + } + return appletParams; + } - // note that Application arguments ARE case-sensitive, but - // Applet.getParameter() is not. + private static void addParam(List vargs, String prefName, + Object value, AppletParams appletParams, String resourcePath) + { - switch (appletName) - { + // note that Application arguments ARE case-sensitive, but + // Applet.getParameter() is not. - case "file": - argName = "open"; - appletName = null; - value = resourcePath + value; - break; - case "file2": - argName = "open2"; - prefName = null; - value = resourcePath + value; - break; - case "features": - case "jnetfile": - case "jpredfile": - case "pdbfile": - case "scorefile": - case "sequence": - // setting argName to null indicates that we want - // JalviewAppLoader to take care of this. - prefName = argName = null; - value = resourcePath + value; - break; - case "tree": - case "treefile": - // setting appletName to null indicates that we want - // Jalview.doMain to taken care of this as Jalview args - argName = "tree"; - appletName = null; - value = resourcePath + value; - break; + String appletName = prefName.toLowerCase(); + String argName = prefName; + switch (appletName) + { - // non-loading preferences + case "file": + argName = "open"; + appletName = null; + value = resourcePath + value; + break; + case "file2": + argName = "open2"; + prefName = null; + value = resourcePath + value; + break; + case "features": + case "jnetfile": + case "jpredfile": + case "pdbfile": + case "scorefile": + case "sequence": + // setting argName to null indicates that we want + // JalviewAppLoader to take care of this. + prefName = argName = null; + value = resourcePath + value; + break; + case "tree": + case "treefile": + // setting appletName to null indicates that we want + // Jalview.doMain to taken care of this as Jalview args + argName = "tree"; + appletName = null; + value = resourcePath + value; + break; - case "defaultcolour": - prefName = Preferences.DEFAULT_COLOUR; - break; - case "defaultcolournuc": - prefName = Preferences.DEFAULT_COLOUR_NUC; - break; - case "defaultcolourprot": - prefName = Preferences.DEFAULT_COLOUR_PROT; - break; - case "annotationcolour_max": - prefName = Preferences.ANNOTATIONCOLOUR_MAX; - break; - case "annotationcolour_min": - prefName = Preferences.ANNOTATIONCOLOUR_MIN; - break; - case "enablesplitframe": - prefName = Preferences.ENABLE_SPLIT_FRAME; - break; - case "centrecolumnlabels": - prefName = Preferences.CENTRE_COLUMN_LABELS; - break; - case "sortby": - prefName = Preferences.SORT_ALIGNMENT; // id, etc. - break; - case "normalisesequencelogo": - prefName = Preferences.NORMALISE_CONSENSUS_LOGO; - break; - case "relaxedidmatch": - prefName = Preferences.RELAXEDSEQIDMATCHING; - break; - case "scaleproteinascdna": - prefName = Preferences.SCALE_PROTEIN_TO_CDNA; - break; - case "userdefinedcolour": - argName = "colour"; - prefName = Preferences.USER_DEFINED_COLOURS; - break; - case "wrap": - prefName = Preferences.WRAP_ALIGNMENT; - break; + // non-loading preferences - // implemented; not tested: + case "defaultcolour": + prefName = Preferences.DEFAULT_COLOUR; + break; + case "defaultcolournuc": + prefName = Preferences.DEFAULT_COLOUR_NUC; + break; + case "defaultcolourprot": + prefName = Preferences.DEFAULT_COLOUR_PROT; + break; + case "annotationcolour_max": + prefName = Preferences.ANNOTATIONCOLOUR_MAX; + break; + case "annotationcolour_min": + prefName = Preferences.ANNOTATIONCOLOUR_MIN; + break; + case "enablesplitframe": + prefName = Preferences.ENABLE_SPLIT_FRAME; + break; + case "centrecolumnlabels": + prefName = Preferences.CENTRE_COLUMN_LABELS; + break; + case "sortby": + prefName = Preferences.SORT_ALIGNMENT; // id, etc. + break; + case "normalisesequencelogo": + prefName = Preferences.NORMALISE_CONSENSUS_LOGO; + break; + case "relaxedidmatch": + prefName = Preferences.RELAXEDSEQIDMATCHING; + break; + case "scaleproteinascdna": + prefName = Preferences.SCALE_PROTEIN_TO_CDNA; + break; + case "userdefinedcolour": + argName = "colour"; + prefName = Preferences.USER_DEFINED_COLOURS; + break; + case "wrap": + prefName = Preferences.WRAP_ALIGNMENT; + break; - case "oninit": - prefName = null; - break; - case "annotations": - value = resourcePath + value; - argName = null; - break; - case "hidefeaturegroups": - // TODO - break; - case "pdbseq": - argName = prefName = null; - break; - case "sortbytree": - prefName = Preferences.SORT_BY_TREE; - value = checkTF(value); - appletName = null; // taken care of by Jalview - break; - case "format": - break; - case "alignpdbfiles": - argName = prefName = null; - break; - case "separator": - break; + // implemented; not tested: - // TODO: probably not relevant? + case "oninit": + prefName = null; + break; + case "annotations": + value = resourcePath + value; + argName = null; + break; + case "hidefeaturegroups": + // TODO + break; + case "pdbseq": + argName = prefName = null; + break; + case "sortbytree": + prefName = Preferences.SORT_BY_TREE; + value = checkTF(value); + appletName = null; // taken care of by Jalview + break; + case "format": + break; + case "alignpdbfiles": + argName = prefName = null; + break; + case "separator": + break; - case "rgb": - prefName = null; // TODO no background for application? - break; - case "externalstructureviewer": - break; - case "application_url": - break; - case "automaticscrolling": - break; - case "heightscale": - break; - case "jalviewhelpurl": - break; - case "label": - break; - case "linklabel_": - prefName = "linkLabel_"; - break; - case "linklabel_1": - prefName = "linkLabel_1"; - break; - case "linkurl_": - prefName = "linkURL_"; - break; + // TODO: probably not relevant? - // unknown: + case "rgb": + prefName = null; // TODO no background for application? + break; + case "externalstructureviewer": + break; + case "application_url": + break; + case "automaticscrolling": + break; + case "heightscale": + break; + case "jalviewhelpurl": + break; + case "label": + break; + case "linklabel_": + prefName = "linkLabel_"; + break; + case "linklabel_1": + prefName = "linkLabel_1"; + break; + case "linkurl_": + prefName = "linkURL_"; + break; - case "nojmol": - case "normaliselogo": - case "resolvetocodebase": - case "uppercase": - case "widthscale": - case "windowheight": - case "windowwidth": - argName = prefName = null; - break; + // unknown: - // TRUE/FALSE + case "nojmol": + case "normaliselogo": + case "resolvetocodebase": + case "uppercase": + case "widthscale": + case "windowheight": + case "windowwidth": + argName = prefName = null; + break; - case "debug": - value = checkTF(value); - break; - case "embedded": - value = checkTF(value); - break; - case "showbutton": - value = checkTF(value); - break; - case "showannotation": - prefName = Preferences.SHOW_ANNOTATIONS; - value = checkTF(value); - break; - case "showconsensus": - prefName = Preferences.SHOW_CONSENSUS_LOGO; - value = checkTF(value); - break; - case "showconsensushistogram": - prefName = Preferences.SHOW_CONSENSUS_HISTOGRAM; - value = checkTF(value); - break; - case "showconservation": - prefName = Preferences.SHOW_CONSERVATION; - value = checkTF(value); - break; - case "showgroupconsensus": - prefName = Preferences.SHOW_GROUP_CONSENSUS; - value = checkTF(value); - break; - case "showgroupconservation": - prefName = Preferences.SHOW_GROUP_CONSERVATION; - value = checkTF(value); - break; - case "showoccupancy": - prefName = Preferences.SHOW_OCCUPANCY; - value = checkTF(value); - break; - case "showquality": - prefName = Preferences.SHOW_QUALITY; - value = checkTF(value); - break; - case "showsequencelogo": - prefName = Preferences.SHOW_CONSENSUS_LOGO; - value = checkTF(value); - break; - case "showfeaturegroups": - value = checkTF(value); - break; - case "showfeaturesettings": - value = checkTF(value); - break; - case "showfullid": - value = checkTF(value); - break; - case "showtreebootstraps": - value = checkTF(value); - break; - case "showtreedistances": - value = checkTF(value); - break; - case "showunconserved": - prefName = Preferences.SHOW_UNCONSERVED; - value = checkTF(value); - break; - case "showunlinkedtreenodes": - value = checkTF(value); - break; - default: - if (appletName.startsWith("pdbfile") - || appletName.startsWith("sequence") && Character.isDigit( - appletName.charAt(appletName.length() - 1))) - { - // could be pdbFile2, for example - prefName = argName = null; - value = resourcePath + value; - break; - } - // or one of the app preference names - break; - } - // put name and value into application args - if (value != null && argName != null) - { - vargs.add(argName); - if (value != "true") - { - vargs.add(value); - } - } - if (value == null) - { - value = "false"; - } - System.out.println("AppletParams propName=" + prefName + " argName=" - + argName + " appletName=" - + appletName + " value=" + value); - if (appletName != null) - { - appletParams.put(appletName, value); - } - if (prefName != null) - { - Cache.setPropertyNoSave(prefName, value); - } + // TRUE/FALSE + + case "debug": + value = checkTF(value); + break; + case "embedded": + value = checkTF(value); + break; + case "showbutton": + value = checkTF(value); + break; + case "showannotation": + prefName = Preferences.SHOW_ANNOTATIONS; + value = checkTF(value); + break; + case "showconsensus": + prefName = Preferences.SHOW_CONSENSUS_LOGO; + value = checkTF(value); + break; + case "showconsensushistogram": + prefName = Preferences.SHOW_CONSENSUS_HISTOGRAM; + value = checkTF(value); + break; + case "showconservation": + prefName = Preferences.SHOW_CONSERVATION; + value = checkTF(value); + break; + case "showgroupconsensus": + prefName = Preferences.SHOW_GROUP_CONSENSUS; + value = checkTF(value); + break; + case "showgroupconservation": + prefName = Preferences.SHOW_GROUP_CONSERVATION; + value = checkTF(value); + break; + case "showoccupancy": + prefName = Preferences.SHOW_OCCUPANCY; + value = checkTF(value); + break; + case "showquality": + prefName = Preferences.SHOW_QUALITY; + value = checkTF(value); + break; + case "showsequencelogo": + prefName = Preferences.SHOW_CONSENSUS_LOGO; + value = checkTF(value); + break; + case "showfeaturegroups": + value = checkTF(value); + break; + case "showfeaturesettings": + value = checkTF(value); + break; + case "showfullid": + value = checkTF(value); + break; + case "showtreebootstraps": + value = checkTF(value); + break; + case "showtreedistances": + value = checkTF(value); + break; + case "showunconserved": + prefName = Preferences.SHOW_UNCONSERVED; + value = checkTF(value); + break; + case "showunlinkedtreenodes": + value = checkTF(value); + break; + default: + if (appletName.startsWith("pdbfile") + || appletName.startsWith("sequence") && Character + .isDigit(appletName.charAt(appletName.length() - 1))) + { + // could be pdbFile2, for example + prefName = argName = null; + value = resourcePath + value; + break; } + // or one of the app preference names + break; + } + + // put name and value into application args + if (value != null && argName != null) + { + vargs.add(argName); + if (value != "true") + { + vargs.add(value.toString()); + } + } + if (value == null) + { + value = "false"; + } + System.out.println("AppletParams propName=" + prefName + " argName=" + + argName + " appletName=" + appletName + " value=" + value); + if (appletName != null) + { + appletParams.put(appletName, value); + } + if (prefName != null) + { + Cache.setPropertyNoSave(prefName, value.toString()); } - return appletParams; } /** @@ -396,9 +421,9 @@ public class AppletParams extends HashMap * @param value * @return "true" or null */ - private static String checkTF(String value) + private static String checkTF(Object value) { - return (value.toLowerCase() == "true" ? "true" : null); + return (("" + value).toLowerCase() == "true" ? "true" : null); } /** diff --git a/src/jalview/bin/ArgsParser.java b/src/jalview/bin/ArgsParser.java index 91c8838..55e760f 100644 --- a/src/jalview/bin/ArgsParser.java +++ b/src/jalview/bin/ArgsParser.java @@ -20,8 +20,11 @@ */ package jalview.bin; +import jalview.util.Platform; + import java.net.URLDecoder; -import java.util.Vector; +import java.util.ArrayList; +import java.util.List; /** * Notes: this argParser does not distinguish between parameter switches, @@ -96,7 +99,7 @@ public class ArgsParser public static final String VSESS = "vsess"; - private Vector vargs = null; + private List vargs = null; private boolean isApplet; @@ -109,12 +112,18 @@ public class ArgsParser public ArgsParser(String[] args) { - vargs = new Vector<>(); + vargs = new ArrayList<>(); isApplet = (args.length > 0 && args[0].startsWith(" @@ -106,7 +90,7 @@ import netscape.javascript.JSObject; * @author $author$ * @version $Revision$ */ -public class Jalview implements ApplicationSingletonI, JalviewJSApi +public class Jalview implements ApplicationSingletonI { // for testing those nasty messages you cannot ever find. @@ -144,16 +128,12 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi private Desktop desktop; - public static AlignFrame currentAlignFrame; - - public boolean isJavaAppletTag; + public AlignFrame currentAlignFrame; public String appletResourcePath; - JalviewAppLoader appLoader; - - protected JSFunctionExec jsFunctionExec; - + JalviewJSApp app; // JalviewJS-specific JavaScript interface + private boolean noCalculation, noMenuBar, noStatus; private boolean noAnnotation; @@ -289,11 +269,7 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi { boolean isJS = Platform.isJS(); - if (isJS) - { - Platform.setAppClass(this); - } - else + if (!isJS) { System.setSecurityManager(null); } @@ -332,16 +308,11 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi if (isJS) { - isJavaAppletTag = aparser.isApplet(); - if (isJavaAppletTag) - { + app = new JalviewJSApp(aparser); Preferences.setAppletDefaults(); Cache.loadProperties(usrPropsFile); // again, because we // might be changing defaults here? - } - System.out.println( - " found: " + aparser.getValue("Info.j2sAppletID")); - appletResourcePath = aparser.getValue("Info.resourcePath"); + appletResourcePath = (String) aparser.getAppletValue("resourcepath", null, true); } else /** @@ -560,27 +531,7 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi } parseArguments(aparser, true); - } - - /** - * Allow an outside entity to initiate the second half of argument parsing - * (only). - * - * @param args - * @return null is good - */ - @Override - public Object parseArguments(String[] args) - { - - try - { - parseArguments(new ArgsParser(args), false); - return null; - } catch (Throwable t) - { - return t; - } + } /** @@ -588,7 +539,7 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi * @param aparser * @param isStartup */ - private void parseArguments(ArgsParser aparser, boolean isStartup) + public void parseArguments(ArgsParser aparser, boolean isStartup) { String groovyscript = null; // script to execute after all loading is @@ -665,20 +616,18 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi } } } - String fileFormat = (isJavaAppletTag - ? aparser.getAppletValue("format", null) + String fileFormat = (isJS ? (String) aparser.getAppletValue("format", null, true) : null); protocol = AppletFormatAdapter.checkProtocol(file); try { - format = (isJavaAppletTag && fileFormat != null + format = (fileFormat != null ? FileFormats.getInstance().forName(fileFormat) : null); if (format == null) { format = new IdentifyFile().identify(file, protocol); } - format = new IdentifyFile().identify(file, protocol); } catch (FileFormatException e1) { // TODO ? @@ -855,12 +804,12 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi { try { - System.out.println( - "CMD [-tree " + data + "] executed successfully!"); NewickFile nf = new NewickFile(data, AppletFormatAdapter.checkProtocol(data)); af.getViewport() .setCurrentTree(af.showNewickTree(nf, data).getTree()); + System.out.println( + "CMD [-tree " + data + "] executed successfully!"); } catch (IOException ex) { System.err.println("Couldn't add tree " + data); @@ -870,11 +819,12 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi // TODO - load PDB structure(s) to alignment JAL-629 // (associate with identical sequence in alignment, or a specified // sequence) - if (isJavaAppletTag) + + if (isJS) { - loadAppletParams(aparser, af); + app.load(af); } - else if (!isJS) + else /** * Java only * @@ -892,11 +842,7 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi + "] executed successfully!"); groovyscript = null; } - } - createOutputFiles(aparser, af, format); - while (aparser.getSize() > 0) - { - System.out.println("Unknown arg: " + aparser.nextValue()); + createOutputFiles(aparser, af, format); } } } @@ -979,7 +925,13 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi } desktop.setInBatchMode(false); } + + if (isJS && isStartup) + { + app.callInitCallback(); + } } + /** * Writes an output file for each format (if any) specified in the @@ -1003,43 +955,33 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi private void createOutputFiles(ArgsParser aparser, AlignFrame af, FileFormatI format) { - String imageName = "unnamed.png"; - while (aparser.getSize() > 1) + while (aparser.getSize() >= 2) { String outputFormat = aparser.nextValue(); - String file = aparser.nextValue(); - - if (outputFormat.equalsIgnoreCase("png")) + File imageFile; + String fname; + switch (outputFormat.toLowerCase()) { - af.createPNG(new File(file)); - imageName = (new File(file)).getName(); - System.out.println("Creating PNG image: " + file); + case "png": + imageFile = new File(aparser.nextValue()); + af.createPNG(imageFile); + System.out.println( + "Creating PNG image: " + imageFile.getAbsolutePath()); continue; - } - else if (outputFormat.equalsIgnoreCase("svg")) - { - File imageFile = new File(file); - imageName = imageFile.getName(); + case "svg": + imageFile = new File(aparser.nextValue()); af.createSVG(imageFile); - System.out.println("Creating SVG image: " + file); + System.out.println( + "Creating SVG image: " + imageFile.getAbsolutePath()); continue; - } - else if (outputFormat.equalsIgnoreCase("html")) - { - File imageFile = new File(file); - imageName = imageFile.getName(); - HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel); - htmlSVG.exportHTML(file); - System.out.println("Creating HTML image: " + file); + case "eps": + imageFile = new File(aparser.nextValue()); + System.out.println( + "Creating EPS file: " + imageFile.getAbsolutePath()); + af.createEPS(imageFile); continue; - } - else if (outputFormat.equalsIgnoreCase("biojsmsa")) - { - if (file == null) - { - System.err.println("The output html file must not be null"); - return; - } + case "biojsmsa": + fname = new File(aparser.nextValue()).getAbsolutePath(); try { BioJsHTMLOutput.refreshVersionInfo( @@ -1049,37 +991,44 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi e.printStackTrace(); } BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel); - bjs.exportHTML(file); - System.out.println("Creating BioJS MSA Viwer HTML file: " + file); + bjs.exportHTML(fname); + System.out.println("Creating BioJS MSA Viwer HTML file: " + fname); continue; - } - else if (outputFormat.equalsIgnoreCase("imgMap")) - { - af.createImageMap(new File(file), imageName); - System.out.println("Creating image map: " + file); + case "html": + fname = new File(aparser.nextValue()).getAbsolutePath(); + HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel); + htmlSVG.exportHTML(fname); + System.out.println("Creating HTML image: " + fname); continue; - } - else if (outputFormat.equalsIgnoreCase("eps")) - { - File outputFile = new File(file); + case "imgmap": + imageFile = new File(aparser.nextValue()); + af.alignPanel.makePNGImageMap(imageFile, "unnamed.png"); System.out.println( - "Creating EPS file: " + outputFile.getAbsolutePath()); - af.createEPS(outputFile); + "Creating image map: " + imageFile.getAbsolutePath()); continue; } - - af.saveAlignment(file, format); - if (af.isSaveAlignmentSuccessful()) + if (!Platform.isJS()) { - System.out.println( - "Written alignment in " + format + " format to " + file); + // skipping outputFormat? + System.out.println("Unknown arg: " + outputFormat); + fname = new File(aparser.nextValue()).getAbsolutePath(); + af.saveAlignment(fname, format); + if (af.isSaveAlignmentSuccessful()) + { + System.out.println( + "Written alignment in " + format + " format to " + fname); + } + else + { + System.out.println("Error writing file " + fname + " in " + format + + " format!!"); + } } - else + while (aparser.getSize() > 0) { - System.out.println("Error writing file " + file + " in " + format - + " format!!"); + System.out.println("Unknown arg: " + aparser.nextValue()); } - + break; } } @@ -1309,14 +1258,15 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi public static AlignFrame getCurrentAlignFrame() { - return Jalview.currentAlignFrame; + return Jalview.getInstance().currentAlignFrame; } public static void setCurrentAlignFrame(AlignFrame currentAlignFrame) { - Jalview.currentAlignFrame = currentAlignFrame; + Jalview.getInstance().currentAlignFrame = currentAlignFrame; } + /** * Get the SwingJS applet ID and combine that with the frameType * @@ -1326,790 +1276,11 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi */ public static String getAppID(String frameType) { - String id = Cache.getProperty("Info.j2sAppletID"); - if (id == null) - { - id = "jalview"; - } - return id + (frameType == null ? "" : "-" + frameType); - } - - /** - * Handle all JalviewLite applet parameters - * - * @param aparser - * @param af - */ - private void loadAppletParams(ArgsParser aparser, AlignFrame af) - { - JalviewApp app = new JalviewApp() - { - - // TODO BH 2019 - // - // These are methods that are in JalviewLite that various classes call - // but are not in JalviewLiteJsApi. Or, even if they are, other classes - // call - // them to JalviewLite directly. Some may not be necessary, but they have - // to - // be at least mentioned here, or the classes calling them should - // reference - // JalviewLite itself. - - private boolean alignPDBStructures; // From JalviewLite; not implemented - - private Hashtable> jsmessages; - - private Hashtable jshashes; - - @Override - public String getParameter(String name) - { - return aparser.getAppletValue(name, null); - } - - @Override - public boolean getDefaultParameter(String name, boolean def) - { - String stn; - return ((stn = getParameter(name)) == null ? def - : "true".equalsIgnoreCase(stn)); - } - - /** - * Get the applet-like document base even though this is an application. - */ - @Override - public URL getDocumentBase() - { - return Platform.getDocumentBase(); - } - - /** - * Get the applet-like code base even though this is an application. - */ - @Override - public URL getCodeBase() - { - return Platform.getCodeBase(); - } - - @Override - public AlignViewportI getViewport() - { - return af.getViewport(); - } - - /** - * features - * - */ - @Override - public boolean parseFeaturesFile(String filename, - DataSourceType protocol) - { - return af.parseFeaturesFile(filename, protocol); - } - - /** - * scorefile - * - */ - @Override - public boolean loadScoreFile(String sScoreFile) throws IOException - { - af.loadJalviewDataFile(sScoreFile, null, null, null); - return true; - } - - /** - * annotations, jpredfile, jnetfile - * - */ - @Override - public void updateForAnnotations() - { - af.updateForAnnotations(); - } - - @Override - public void loadTree(NewickFile fin, String treeFile) - throws IOException - { - // n/a -- already done by standard Jalview command line processing - } - - @Override - public void setAlignPdbStructures(boolean defaultParameter) - { - alignPDBStructures = true; - } - - @Override - public void newStructureView(PDBEntry pdb, SequenceI[] seqs, - String[] chains, DataSourceType protocol) - { - StructureViewer.launchStructureViewer(af.alignPanel, pdb, seqs); - } - - @Override - public void setFeatureGroupState(String[] groups, boolean state) - { - af.setFeatureGroupState(groups, state); - } - - @Override - public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs, - String[][] chains, String[] protocols) - { - System.err.println( - "Jalview applet interface alignedStructureView not implemented"); - } - - @Override - public void newFeatureSettings() - { - System.err.println( - "Jalview applet interface newFeatureSettings not implemented"); - } - - private Vector jsExecQueue; - - @Override - public Vector getJsExecQueue(JSFunctionExec exec) - { - jsFunctionExec = exec; - return (jsExecQueue == null ? (jsExecQueue = new Vector<>()) - : jsExecQueue); - } - - // AppletContext deprecated - // - // @Override - // public AppletContext getAppletContext() - // { - // // TODO Auto-generated method stub - // return null; - // } - // - @Override - public boolean isJsfallbackEnabled() - { - // TODO Auto-generated method stub - return false; - } - - @Override - public JSObject getJSObject() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public StructureSelectionManagerProvider getStructureSelectionManagerProvider() - { - // TODO Q: what exactly is this? BH - return null; - } - - @Override - public void updateColoursFromMouseOver(Object source, - MouseOverStructureListener mouseOverStructureListener) - { - // TODO Auto-generated method stub - - } - - @Override - public Object[] getSelectionForListener(SequenceGroup seqsel, - ColumnSelection colsel, HiddenColumns hidden, - SelectionSource source, Object alignFrame) - { - return appLoader.getSelectionForListener(getCurrentAlignFrame(), - seqsel, colsel, hidden, source, alignFrame); - } - - @Override - public String arrayToSeparatorList(String[] array) - { - return appLoader.arrayToSeparatorList(array); - } - - @Override - public Hashtable getJSHashes() - { - return (jshashes == null ? (jshashes = new Hashtable<>()) - : jshashes); - } - - @Override - public Hashtable> getJSMessages() - { - return (jsmessages == null ? (jsmessages = new Hashtable<>()) - : jsmessages); - } - - @Override - public Object getFrameForSource(VamsasSource source) - { - if (source != null) - { - AlignFrame af; - if (source instanceof jalview.gui.AlignViewport - && source == (af = getCurrentAlignFrame()).getViewport()) - { - // should be valid if it just generated an event! - return af; - } - // TODO: ensure that if '_af' is specified along with a handler - // function, then only events from that alignFrame are sent to that - // function - } - return null; - } - - @Override - public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp) - { - return new jalview.gui.FeatureRenderer((AlignmentPanel) vp); - } - - }; - - appLoader = new JalviewAppLoader(true); - appLoader.load(app); - } - - /** - * - * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences() - */ - @Override - public String getSelectedSequences() - { - return getSelectedSequencesFrom(getCurrentAlignFrame()); + return (Platform.isJS() ? getInstance().app.getAppID(frameType) : null); } - /** - * - * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String) - */ - @Override - public String getSelectedSequences(String sep) - { - return getSelectedSequencesFrom(getCurrentAlignFrame(), sep); - } - - /** - * - * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui - * .AlignFrame) - */ - @Override - public String getSelectedSequencesFrom(AlignFrame alf) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return getSelectedSequencesFrom(alf, null); - } - - /** - * - * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui - * .AlignFrame, java.lang.String) - */ - @Override - public String getSelectedSequencesFrom(AlignFrame alf, String sep) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return appLoader.getSelectedSequencesFrom(alf, sep); - } - - /** - * - * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui - * .AlignFrame, java.lang.String) - */ - @Override - public void highlight(String sequenceId, String position, - String alignedPosition) - { - highlightIn(null, sequenceId, position, alignedPosition); - } - - @Override - public void highlightIn(AlignFrame alf, String sequenceId, - String position, String alignedPosition) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - appLoader.highlightIn(alf, sequenceId, position, alignedPosition); - } - - @Override - public void select(String sequenceIds, String columns) - { - selectIn(getCurrentAlignFrame(), sequenceIds, columns, null); - } - - @Override - public void select(String sequenceIds, String columns, String sep) - { - selectIn(null, sequenceIds, columns, sep); - } - - @Override - public void selectIn(AlignFrame alf, String sequenceIds, String columns) - { - selectIn(alf, sequenceIds, columns, null); - } - - @Override - public void selectIn(AlignFrame alf, String sequenceIds, String columns, - String sep) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - appLoader.selectIn(alf, sequenceIds, columns, sep); - } - - @Override - public String getSelectedSequencesAsAlignment(String format, - String suffix) - { - return getSelectedSequencesAsAlignmentFrom(null, format, suffix); - } - - @Override - public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf, - String format, String sep) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, sep); - } - - @Override - public String getAlignmentOrder() - { - return getAlignmentFrom(getCurrentAlignFrame(), null); - } - - @Override - public String getAlignmentOrderFrom(AlignFrame alf) - { - return getAlignmentFrom(alf, null); - } - - @Override - public String getAlignmentOrderFrom(AlignFrame alf, String sep) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return appLoader.getAlignmentOrderFrom(alf, sep); - } - - @Override - public String orderBy(String order, String undoName) - { - return orderBy(order, undoName, null); - } - - @Override - public String orderBy(String order, String undoName, String sep) - { - return orderAlignmentBy(getCurrentAlignFrame(), order, undoName, sep); - } - - @Override - public String orderAlignmentBy(AlignFrame alf, String order, - String undoName, String sep) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return appLoader.orderAlignmentBy(alf, order, undoName, sep); - } - - @Override - public String getAlignment(String format) - { - return getAlignmentFrom(null, format, null); - } - - @Override - public String getAlignmentFrom(AlignFrame alf, String format) - { - return getAlignmentFrom(alf, format, null); - } - - @Override - public String getAlignment(String format, String suffix) - { - return getAlignmentFrom(getCurrentAlignFrame(), format, suffix); - } - - @Override - public String getAlignmentFrom(AlignFrame alf, String format, - String suffix) - { - return appLoader.getAlignmentFrom(alf, format, suffix); - } - - @Override - public void loadAnnotation(String annotation) - { - loadAnnotationFrom(getCurrentAlignFrame(), annotation); - } - - @Override - public void loadAnnotationFrom(AlignFrame alf, String annotation) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - appLoader.loadAnnotationFrom(alf, annotation); - } - - @Override - public void loadFeatures(String features, boolean autoenabledisplay) - { - loadFeaturesFrom(currentAlignFrame, features, autoenabledisplay); - } - - @Override - public boolean loadFeaturesFrom(AlignFrame alf, String features, - boolean autoenabledisplay) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return appLoader.loadFeaturesFrom(alf, features, autoenabledisplay); - } - - @Override - public String getFeatures(String format) - { - return getFeaturesFrom(null, format); - } - - @Override - public String getFeaturesFrom(AlignFrame alf, String format) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return appLoader.getFeaturesFrom(alf, format); - } - - @Override - public String getAnnotation() - { - return getAnnotationFrom(null); - } - - @Override - public String getAnnotationFrom(AlignFrame alf) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return appLoader.getAnnotationFrom(alf); - } - - // @Override - // public AlignFrame newView() - // { - // return newViewFrom(null, null); - // } - // - // @Override - // public AlignFrame newView(String name) - // { - // return newViewFrom(null, name); - // } - // - // @Override - // public AlignFrame newViewFrom(AlignFrame alf) - // { - // return newViewFrom(alf, null); - // } - // - // @Override - // public AlignFrame newViewFrom(AlignFrame alf, String name) - // { - // if (alf == null) - // { - // alf = getCurrentAlignFrame(); - // } - // return appLoader.newViewFrom(alf, name); - // } - - @Override - public AlignFrame loadAlignment(String text, String title) - { - return appLoader.loadAlignment(text, AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT, title); - } - - @Override - public boolean addPdbFile(AlignFrame alFrame, String sequenceId, - String pdbEntryString, String pdbFile) - { - if (alFrame == null) - { - alFrame = getCurrentAlignFrame(); - } - return appLoader.addPdbFile(alFrame, sequenceId, pdbEntryString, - pdbFile); - } - - @Override - public void scrollViewToIn(AlignFrame alf, String topRow, - String leftHandColumn) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - appLoader.scrollViewToIn(alf, topRow, leftHandColumn); - } - - @Override - public void scrollViewToRowIn(AlignFrame alf, String topRow) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - appLoader.scrollViewToRowIn(alf, topRow); - } - - @Override - public void scrollViewToColumnIn(AlignFrame alf, String leftHandColumn) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - appLoader.scrollViewToColumnIn(alf, leftHandColumn); - } - - @Override - public String getFeatureGroups() - { - return getFeatureGroupsOn(null); - } - - @Override - public String getFeatureGroupsOn(AlignFrame alf) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return appLoader.getFeatureGroupsOn(alf); - } - - @Override - public String getFeatureGroupsOfState(boolean visible) - { - return getFeatureGroupsOfStateOn(null, visible); - } - - @Override - public String getFeatureGroupsOfStateOn(AlignFrame alf, boolean visible) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return appLoader.getFeatureGroupsOfStateOn(alf, visible); - } - - @Override - public void setFeatureGroupState(String groups, boolean state) - { // JalviewLite API - setFeatureGroupStateOn(null, groups, state); - } - - @Override - public void setFeatureGroupStateOn(AlignFrame alf, String groups, - boolean state) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - appLoader.setFeatureGroupStateOn(alf, groups, state); - } - - @Override - public String getSeparator() - { - return appLoader.getSeparator(); - } - - @Override - public void setSeparator(String separator) - { - appLoader.setSeparator(separator); - } - - @Override - public String getJsMessage(String messageclass, String viewId) - { - // see http://www.jalview.org/examples/jalviewLiteJs.html - return null; - } - - /** - * Open a new Tree panel on the desktop statically. Params are standard (not - * set by Groovy). No dialog is opened. - * - * @param af - * @param treeType - * @param modelName - * @return null, or the string "label.you_need_at_least_n_sequences" if number - * of sequences selected is inappropriate - */ - @Override - public Object openTreePanel(AlignFrame af, String treeType, - String modelName) - { // JalviewJS api - if (af == null) - { - af = getCurrentAlignFrame(); - } - return CalculationChooser.openTreePanel(af, treeType, modelName, null); - } - - /** - * public static method for JalviewJS API to open a PCAPanel without - * necessarily using a dialog. - * - * @param af - * @param modelName - * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences" - * if number of sequences selected is inappropriate - */ - @Override - public Object openPcaPanel(AlignFrame af, String modelName) - { - if (af == null) - { - af = getCurrentAlignFrame(); - } - return CalculationChooser.openPcaPanel(af, modelName, null); - } - - @Override - public String getSelectedSequencesAsAlignment(String format, - boolean suffix) - { - return getSelectedSequencesAsAlignmentFrom(null, format, suffix); - } - - @Override - public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf, - String format, boolean suffix) - { - if (alf == null) - { - alf = getCurrentAlignFrame(); - } - return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, - "" + suffix); - } - - @Override - public String arrayToSeparatorList(String[] array) - { - return appLoader.arrayToSeparatorList(array); - } - - @Override - public String[] separatorListToArray(String list) - { - return appLoader.separatorListToArray(list); - } - - //// probably not needed in JalviewJS -- From when Jmol and Jalview did not - //// have a direct connection? - - @Override - public void setMouseoverListener(String listener) - { - // TODO Auto-generated method stub - - } - - @Override - public void setMouseoverListener(AlignFrame af, String listener) - { - // TODO Auto-generated method stub - - } - - @Override - public void setSelectionListener(String listener) - { - // TODO Auto-generated method stub - - } - - @Override - public void setSelectionListener(AlignFrame af, String listener) - { - // TODO Auto-generated method stub - - } - - @Override - public void setStructureListener(String listener, String modelSet) - { - // TODO Auto-generated method stub - - } - - @Override - public void removeJavascriptListener(AlignFrame af, String listener) - { - // TODO Auto-generated method stub - - } - - @Override - public void mouseOverStructure(String pdbResNum, String chain, - String pdbfile) - { - // TODO Auto-generated method stub - - } - - @Override - public void showOverview() - { - currentAlignFrame.overviewMenuItem_actionPerformed(null); + public String doSendCallback(Object callback, Object[] data) { + return (Platform.isJS() ? app.doSendCallback(callback, data) : null); } public void notifyWorker(AlignCalcWorkerI worker, String status) @@ -2118,4 +1289,10 @@ public class Jalview implements ApplicationSingletonI, JalviewJSApi // + " " + status); } + public Object arrayToSeparatorList(String[] seqs) + { + return (Platform.isJS() ? app.arrayToSeparatorList(seqs) : null); + } + + } diff --git a/src/jalview/bin/JalviewJS2.java b/src/jalview/bin/JalviewJS2.java index 26110f8..544f5d7 100644 --- a/src/jalview/bin/JalviewJS2.java +++ b/src/jalview/bin/JalviewJS2.java @@ -20,16 +20,37 @@ public class JalviewJS2 static { /** - * @j2sNative + * @ could do it this way: * - * J2S.thisApplet.__Info.args = - * ["open","examples/uniref50.fa","features", - * "examples/exampleFeatures.txt"]; + * j2sNative + * + * J2S.thisApplet.__Info.args = [ "open","examples/uniref50.fa", + * "features","examples/exampleFeatures.txt", "noannotation" ]; */ } public static void main(String[] args) throws Exception { + if (args.length == 0) + { + args = new String[] { + // "headless", + "open", "examples/uniref50.fa", + "features", + "examples/exampleFeatures.txt" + , "noannotation" + //, "showoverview" + //, "png", "test-bh.png" + }; + } + + // String cmds = "nodisplay -open examples/uniref50.fa -sortbytree -props + // test/jalview/io/testProps.jvprops -colour zappo " + // + "-jabaws http://www.compbio.dundee.ac.uk/jabaws -nosortbytree " + // + "-features examples/testdata/plantfdx.features -annotations + // examples/testdata/plantfdx.annotations -tree + // examples/testdata/uniref50_test_tree"; + // args = cmds.split(" "); Jalview.main(args); //showFocusTimer(); } diff --git a/src/jalview/bin/JalviewJSApi.java b/src/jalview/bin/JalviewJSApi.java index a21bebe..7c9dee8 100644 --- a/src/jalview/bin/JalviewJSApi.java +++ b/src/jalview/bin/JalviewJSApi.java @@ -1,6 +1,20 @@ package jalview.bin; +import java.io.IOException; +import java.net.URL; +import java.util.Hashtable; + +import jalview.api.AlignViewportI; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.HiddenColumns; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; +import jalview.io.DataSourceType; +import jalview.io.NewickFile; +import jalview.structure.SelectionSource; +import jalview.structure.VamsasSource; /** * JAL-3369 JalviewJS API BH 2019.07.17 @@ -11,42 +25,29 @@ import jalview.gui.AlignFrame; public interface JalviewJSApi { - void showOverview(); + // debug flag - controls output to standard out + public static boolean debug = false; /** - * process commandline arguments after the JavaScript application has started + * bind a pdb file to a sequence in the given AlignFrame. * - * @param args - * @return + * @param alFrame + * - null or specific AlignFrame. This specifies the dataset that + * will be searched for a seuqence called sequenceId + * @param sequenceId + * - sequenceId within the dataset. + * @param pdbEntryString + * - the short name for the PDB file + * @param pdbFile + * - pdb file - either a URL or a valid PDB file. + * @return true if binding was as success TODO: consider making an exception + * structure for indicating when PDB parsing or sequenceId location + * fails. */ - Object parseArguments(String[] args); - - - /** - * Open a new Tree panel on the desktop statically. Params are standard (not - * set by Groovy). No dialog is opened. - * - * @param af - * may be null - * @param treeType - * @param modelName - * @return null, or the string "label.you_need_at_least_n_sequences" if number - * of sequences selected is inappropriate - */ - public Object openTreePanel(AlignFrame af, String treeType, - String modelName); + public abstract boolean addPdbFile(AlignFrame alFrame, String sequenceId, + String pdbEntryString, String pdbFile); - /** - * public static method for JalviewJS API to open a PCAPanel without - * necessarily using a dialog. - * - * @param af - * may be null - * @param modelName - * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences" - * if number of sequences selected is inappropriate - */ - public Object openPcaPanel(AlignFrame af, String modelName); + public String arrayToSeparatorList(String[] array); /** * The following public methods may be called externally, eg via javascript in @@ -71,348 +72,230 @@ public interface JalviewJSApi // public interface JalviewLiteJsApi // { - /** - * @return String list of selected sequence IDs, each terminated by the - * 'boolean not' character (""+0x00AC); or (¬); - */ - - public abstract String getSelectedSequences(); - - /** - * @param sep - * separator string or null for default - * @return String list of selected sequence IDs, each terminated by given - * separator string - */ - - public abstract String getSelectedSequences(String sep); - - /** - * @param alf - * AlignFrame containing selection - * @return String list of selected sequence IDs, each terminated by current - * default separator sequence - * - */ - public abstract String getSelectedSequencesFrom(AlignFrame alf); - - /** - * get list of selected sequence IDs separated by given separator - * - * @param alf - * window containing selection - * @param sep - * separator string to use - default is 'boolean not' - * @return String list of selected sequence IDs, each terminated by the given - * separator - */ - public abstract String getSelectedSequencesFrom(AlignFrame alf, - String sep); - - /** - * - * @param sequenceId - * id of sequence to highlight - * @param position - * integer position [ tobe implemented or range ] on sequence - * @param alignedPosition - * true/false/empty string - indicate if position is an alignment - * column or unaligned sequence position - */ - - public abstract void highlight(String sequenceId, String position, - String alignedPosition); - - /** - * - * @param sequenceId - * id of sequence to highlight - * @param position - * integer position [ tobe implemented or range ] on sequence - * @param alignedPosition - * false, blank or something else - indicate if position is an - * alignment column or unaligned sequence position - */ - public abstract void highlightIn(AlignFrame alf, String sequenceId, - String position, String alignedPosition); - - /** - * select regions of the currrent alignment frame - * - * @param sequenceIds - * String separated list of sequence ids or empty string - * @param columns - * String separated list { column range or column, ..} or empty - * string - */ - - public abstract void select(String sequenceIds, String columns); - - /** - * select regions of the currrent alignment frame - * - * @param toselect - * String separated list { column range, seq1...seqn sequence ids } - * @param sep - * separator between toselect fields - */ - - public abstract void select(String sequenceIds, String columns, - String sep); - - /** - * select regions of the given alignment frame - * - * @param alf - * @param toselect - * String separated list { column range, seq1...seqn sequence ids } - * @param sep - * separator between toselect fields - */ - public abstract void selectIn(AlignFrame alf, String sequenceIds, - String columns); - - /** - * select regions of the given alignment frame - * - * @param alf - * @param toselect - * String separated list { column range, seq1...seqn sequence ids } - * @param sep - * separator between toselect fields - */ - public abstract void selectIn(AlignFrame alf, String sequenceIds, - String columns, String sep); - - /** - * get sequences selected in current AlignFrame and return their alignment in - * format 'format' either with or without suffix - * - * @param alf - * - where selection is - * @param format - * - format of alignment file - * @param suffix - * - "true" to append /start-end string to each sequence ID - * @return selected sequences as flat file or empty string if there was no - * current selection - */ - - public abstract String getSelectedSequencesAsAlignment(String format, - String suffix); - - /** - * get sequences selected in alf and return their alignment in format 'format' - * either with or without suffix - * - * @param alf - * - where selection is - * @param format - * - format of alignment file - * @param suffix - * - "true" to append /start-end string to each sequence ID - * @return selected sequences as flat file or empty string if there was no - * current selection - */ - public abstract String getSelectedSequencesAsAlignmentFrom( - AlignFrame alf, - String format, String suffix); - - /** - * get a separator separated list of sequence IDs reflecting the order of the - * current alignment - * - * @return - */ - - public abstract String getAlignmentOrder(); - - /** - * get a separator separated list of sequence IDs reflecting the order of the - * alignment in alf - * - * @param alf - * @return - */ - public abstract String getAlignmentOrderFrom(AlignFrame alf); - - /** - * get a sep separated list of sequence IDs reflecting the order of the - * alignment in alf - * - * @param alf - * @param sep - * - separator to use - * @return - */ - public abstract String getAlignmentOrderFrom(AlignFrame alf, - String sep); - - /** - * re-order the current alignment using the given list of sequence IDs - * - * @param order - * - sep separated list - * @param undoName - * - string to use when referring to ordering action in undo buffer - * @return 'true' if alignment was actually reordered. empty string if - * alignment did not contain sequences. - */ - - public abstract String orderBy(String order, String undoName); - - /** - * re-order the current alignment using the given list of sequence IDs - * separated by sep - * - * @param order - * - sep separated list - * @param undoName - * - string to use when referring to ordering action in undo buffer - * @param sep - * @return 'true' if alignment was actually reordered. empty string if - * alignment did not contain sequences. - */ - - public abstract String orderBy(String order, String undoName, - String sep); - - /** - * re-order the given alignment using the given list of sequence IDs separated - * by sep - * - * @param alf - * @param order - * - sep separated list - * @param undoName - * - string to use when referring to ordering action in undo buffer - * @param sep - * @return 'true' if alignment was actually reordered. empty string if - * alignment did not contain sequences. - */ - public abstract String orderAlignmentBy(AlignFrame alf, String order, - String undoName, String sep); - - /** - * get alignment as format (format names FASTA, BLC, CLUSTAL, MSF, PILEUP, - * PFAM - see jalview.io.AppletFormatAdapter for full list); - * - * @param format - * @return - */ - - public abstract String getAlignment(String format); - - /** - * get alignment displayed in alf as format - * - * @param alf - * @param format - * @return - */ - public abstract String getAlignmentFrom(AlignFrame alf, String format); - - /** - * get alignment as format with jalview start-end sequence suffix appended - * - * @param format - * @param suffix - * @return - */ - - public abstract String getAlignment(String format, String suffix); - - /** - * get alignment displayed in alf as format with or without the jalview - * start-end sequence suffix appended - * - * @param alf - * @param format - * @param suffix - * @return - */ - public abstract String getAlignmentFrom(AlignFrame alf, String format, - String suffix); - - /** - * add the given features or annotation to the current alignment - * - * @param annotation - */ - - public abstract void loadAnnotation(String annotation); - - /** - * add the given features or annotation to the given alignment view - * - * @param alf - * @param annotation - */ - public abstract void loadAnnotationFrom(AlignFrame alf, - String annotation); - - /** - * parse the given string as a jalview feature or GFF annotation file and - * optionally enable feature display on the current AlignFrame - * - * @param features - * - gff or features file - * @param autoenabledisplay - * - when true, feature display will be enabled if any features can - * be parsed from the string. - */ - - public abstract void loadFeatures(String features, - boolean autoenabledisplay); - - /** - * parse the given string as a jalview feature or GFF annotation file and - * optionally enable feature display on the given AlignFrame. - * - * @param alf - * @param features - * - gff or features file - * @param autoenabledisplay - * - when true, feature display will be enabled if any features can - * be parsed from the string. - * @return true if data parsed as features - */ - public abstract boolean loadFeaturesFrom(AlignFrame alf, String features, - boolean autoenabledisplay); - - /** - * get the sequence features in the given format (Jalview or GFF); - * - * @param format - * @return - */ - - public abstract String getFeatures(String format); - - /** - * get the sequence features in alf in the given format (Jalview or GFF); - * - * @param alf - * @param format - * @return - */ - public abstract String getFeaturesFrom(AlignFrame alf, String format); - - /** - * get current alignment's annotation as an annotation file - * - * @return - */ - - public abstract String getAnnotation(); - - /** - * get alignment view alf's annotation as an annotation file - * - * @param alf - * @return - */ - public abstract String getAnnotationFrom(AlignFrame alf); + /** + * get alignment as format (format names FASTA, BLC, CLUSTAL, MSF, PILEUP, + * PFAM - see jalview.io.AppletFormatAdapter for full list); + * + * @param format + * @return + */ + + public abstract String getAlignment(String format); + + /** + * get alignment as format with jalview start-end sequence suffix appended + * + * @param format + * @param suffix + * @return + */ + + public abstract String getAlignment(String format, String suffix); + + /** + * get alignment displayed in alf as format + * + * @param alf + * @param format + * @return + */ + public abstract String getAlignmentFrom(AlignFrame alf, String format); + + /** + * get alignment displayed in alf as format with or without the jalview + * start-end sequence suffix appended + * + * @param alf + * @param format + * @param suffix + * @return + */ + public abstract String getAlignmentFrom(AlignFrame alf, String format, + String suffix); + + /** + * get a separator separated list of sequence IDs reflecting the order of the + * current alignment + * + * @return + */ + + public abstract String getAlignmentOrder(); + + /** + * get a separator separated list of sequence IDs reflecting the order of the + * alignment in alf + * + * @param alf + * @return + */ + public abstract String getAlignmentOrderFrom(AlignFrame alf); + + /** + * get a sep separated list of sequence IDs reflecting the order of the + * alignment in alf + * + * @param alf + * @param sep + * - separator to use + * @return + */ + public abstract String getAlignmentOrderFrom(AlignFrame alf, String sep); + + /** + * get current alignment's annotation as an annotation file + * + * @return + */ + + public abstract String getAnnotation(); + + /** + * get alignment view alf's annotation as an annotation file + * + * @param alf + * @return + */ + public abstract String getAnnotationFrom(AlignFrame alf); + + public Object getAppletParameter(String name, boolean asString); + + public URL getCodeBase(); + + public URL getDocumentBase(); + + /** + * + * @return + * @see jalview.appletgui.AlignFrame#getFeatureGroups(); + */ + + public abstract String getFeatureGroups(); + + /** + * @param visible + * @return + * @see jalview.appletgui.AlignFrame#getFeatureGroupsOfState(boolean); + */ + + public abstract String getFeatureGroupsOfState(boolean visible); + + /** + * @param alf + * align frame to get groups of state visible + * @param visible + * @return + * @see jalview.appletgui.AlignFrame#getFeatureGroupsOfState(boolean); + */ + public abstract String getFeatureGroupsOfStateOn(AlignFrame alf, + boolean visible); + + /** + * @param alf + * AlignFrame to get feature groups on + * @return + * @see jalview.appletgui.AlignFrame#getFeatureGroups(); + */ + public abstract String getFeatureGroupsOn(AlignFrame alf); + + /** + * get the sequence features in the given format (Jalview or GFF); + * + * @param format + * @return + */ + + public abstract String getFeatures(String format); + + /** + * get the sequence features in alf in the given format (Jalview or GFF); + * + * @param alf + * @param format + * @return + */ + public abstract String getFeaturesFrom(AlignFrame alf, String format); + + public Object getFrameForSource(VamsasSource source); + + public Hashtable getJSHashes(); + + /** + * Retrieve fragments of a large packet of data made available by JalviewLite. + * + * @param messageclass + * @param viewId + * @return next chunk of message + */ + + public abstract String getJsMessage(String messageclass, String viewId); + + Hashtable> getJSMessages(); + + public Object getJSObject(); + + public jalview.renderer.seqfeatures.FeatureRenderer getNewFeatureRenderer( + AlignViewportI vp); + + public String getParameter(String name); + + /** + * @return String list of selected sequence IDs, each terminated by the + * 'boolean not' character (""+0x00AC); or (¬); + */ + + public abstract String getSelectedSequences(); + + /** + * @param sep + * separator string or null for default + * @return String list of selected sequence IDs, each terminated by given + * separator string + */ + + public abstract String getSelectedSequences(String sep); + + /** + * get sequences selected in current AlignFrame and return their alignment in + * format 'format' either with or without suffix + * + * @param alf + * - where selection is + * @param format + * - format of alignment file + * @param suffix + * - "true" to append /start-end string to each sequence ID + * @return selected sequences as flat file or empty string if there was no + * current selection + */ + + public abstract String getSelectedSequencesAsAlignment(String format, + String suffix); + + /** + * get sequences selected in alf and return their alignment in format 'format' + * either with or without suffix + * + * @param alf + * - where selection is + * @param format + * - format of alignment file + * @param suffix + * - "true" to append /start-end string to each sequence ID + * @return selected sequences as flat file or empty string if there was no + * current selection + */ + public abstract String getSelectedSequencesAsAlignmentFrom(AlignFrame alf, + String format, String suffix); + + /** + * @param alf + * AlignFrame containing selection + * @return String list of selected sequence IDs, each terminated by current + * default separator sequence + * + */ + public abstract String getSelectedSequencesFrom(AlignFrame alf); // BH incompatibility here -- JalviewLite created an AlignFrame; Jalview // creates an AlignmentPanel @@ -450,244 +333,352 @@ public interface JalviewJSApi // */ // public abstract AlignFrame newViewFrom(AlignFrame alf, String name); - /** - * - * @param text - * alignment file as a string - * @param title - * window title - * @return null or new alignment frame - */ - - public abstract AlignFrame loadAlignment(String text, String title); - - /** - * register a javascript function to handle any alignment mouseover events - * - * @param listener - * name of javascript function (called with arguments - * [jalview.appletgui.AlignFrame,String(sequence id);,String(column - * in alignment);, String(position in sequence);] - */ - - public abstract void setMouseoverListener(String listener); - - /** - * register a javascript function to handle mouseover events - * - * @param af - * (null or specific AlignFrame for which events are to be listened - * for); - * @param listener - * name of javascript function - */ - public abstract void setMouseoverListener(AlignFrame af, - String listener); - - /** - * register a javascript function to handle any alignment selection events. - * Events are generated when the user completes a selection event, or when the - * user deselects all selected regions. - * - * @param listener - * name of javascript function (called with arguments - * [jalview.appletgui.AlignFrame, String(sequence set id);, - * String(separator separated list of sequences which were - * selected);, String(separator separated list of column ranges (i.e. - * single number or hyphenated range); that were selected);] - */ - - public abstract void setSelectionListener(String listener); - - public abstract void setSelectionListener(AlignFrame af, - String listener); - - /** - * register a javascript function to handle events normally routed to a Jmol - * structure viewer. - * - * @param listener - * - javascript function (arguments are variable, see - * jalview.javascript.MouseOverStructureListener for full details); - * @param modelSet - * - separator separated list of PDB file URIs that this viewer is - * handling. These files must be in the same order they appear in - * Jmol (e.g. first one is frame 1, second is frame 2, etc);. - * @see jalview.javascript.MouseOverStructureListener - */ - - public abstract void setStructureListener(String listener, - String modelSet); - - /** - * remove any callback using the given listener function and associated with - * the given AlignFrame (or null for all callbacks); - * - * @param af - * (may be null); - * @param listener - * (may be null); - */ - public abstract void removeJavascriptListener(AlignFrame af, - String listener); - - /** - * send a mouseover message to all the alignment windows associated with the - * given residue in the pdbfile - * - * @param pdbResNum - * @param chain - * @param pdbfile - */ - - public abstract void mouseOverStructure(String pdbResNum, String chain, - String pdbfile); - - /** - * bind a pdb file to a sequence in the given AlignFrame. - * - * @param alFrame - * - null or specific AlignFrame. This specifies the dataset that - * will be searched for a seuqence called sequenceId - * @param sequenceId - * - sequenceId within the dataset. - * @param pdbEntryString - * - the short name for the PDB file - * @param pdbFile - * - pdb file - either a URL or a valid PDB file. - * @return true if binding was as success TODO: consider making an exception - * structure for indicating when PDB parsing or sequenceId location - * fails. - */ - public abstract boolean addPdbFile(AlignFrame alFrame, String sequenceId, - String pdbEntryString, String pdbFile); - - /** - * adjust horizontal/vertical scroll to make the given location the top left - * hand corner for the given view - * - * @param alf - * @param topRow - * @param leftHandColumn - */ - public abstract void scrollViewToIn(AlignFrame alf, String topRow, - String leftHandColumn); - - /** - * adjust vertical scroll to make the given row the top one for given view - * - * @param alf - * @param topRow - */ - public abstract void scrollViewToRowIn(AlignFrame alf, String topRow); - - /** - * adjust horizontal scroll to make the given column the left one in the given - * view - * - * @param alf - * @param leftHandColumn - */ - public abstract void scrollViewToColumnIn(AlignFrame alf, - String leftHandColumn); - - /** - * - * @return - * @see jalview.appletgui.AlignFrame#getFeatureGroups(); - */ - - public abstract String getFeatureGroups(); - - /** - * @param alf - * AlignFrame to get feature groups on - * @return - * @see jalview.appletgui.AlignFrame#getFeatureGroups(); - */ - public abstract String getFeatureGroupsOn(AlignFrame alf); - - /** - * @param visible - * @return - * @see jalview.appletgui.AlignFrame#getFeatureGroupsOfState(boolean); - */ - - public abstract String getFeatureGroupsOfState(boolean visible); - - /** - * @param alf - * align frame to get groups of state visible - * @param visible - * @return - * @see jalview.appletgui.AlignFrame#getFeatureGroupsOfState(boolean); - */ - public abstract String getFeatureGroupsOfStateOn(AlignFrame alf, - boolean visible); - - /** - * @param groups - * tab separated list of group names - * @param state - * true or false - * @see jalview.appletgui.AlignFrame#setFeatureGroupState(java.lang.String[], - * boolean); - */ - public abstract void setFeatureGroupStateOn(AlignFrame alf, - String groups, - boolean state); - - - public abstract void setFeatureGroupState(String groups, boolean state); - - /** - * List separator string - * - * @return the separator - */ - - public abstract String getSeparator(); - - /** - * List separator string - * - * @param separator - * the separator to set. empty string will reset separator to default - */ - - public abstract void setSeparator(String separator); - - /** - * Retrieve fragments of a large packet of data made available by JalviewLite. - * - * @param messageclass - * @param viewId - * @return next chunk of message - */ - - public abstract String getJsMessage(String messageclass, String viewId); - - /// in http://www.jalview.org/examples/jalviewLiteJs.html but missing here - - // get selected sequences as alignment as format with or without start-end - // suffix - - public String getSelectedSequencesAsAlignment(String format, - boolean suffix); - - // get selected sequences as alignment from given view as format with or - // without start-end suffix - public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf, - String format, boolean suffix); - - - public String arrayToSeparatorList(String[] array); - - // get a string array from a list - - public String[] separatorListToArray(String list); - - // debug flag - controls output to standard out - public static boolean debug = false; + /** + * get list of selected sequence IDs separated by given separator + * + * @param alf + * window containing selection + * @param sep + * separator string to use - default is 'boolean not' + * @return String list of selected sequence IDs, each terminated by the given + * separator + */ + public abstract String getSelectedSequencesFrom(AlignFrame alf, + String sep); + + public Object[] getSelectionForListener(SequenceGroup seqsel, + ColumnSelection colsel, HiddenColumns hidden, + SelectionSource source, Object alignFrame); + + /** + * List separator string + * + * @return the separator + */ + + public abstract String getSeparator(); + + public AlignViewportI getViewport(); + + /** + * + * @param sequenceId + * id of sequence to highlight + * @param position + * integer position [ tobe implemented or range ] on sequence + * @param alignedPosition + * true/false/empty string - indicate if position is an alignment + * column or unaligned sequence position + */ + + public abstract void highlight(String sequenceId, String position, + String alignedPosition); + + /** + * + * @param sequenceId + * id of sequence to highlight + * @param position + * integer position [ tobe implemented or range ] on sequence + * @param alignedPosition + * false, blank or something else - indicate if position is an + * alignment column or unaligned sequence position + */ + public abstract void highlightIn(AlignFrame alf, String sequenceId, + String position, String alignedPosition); + + /** + * + * @param text + * alignment file as a string + * @param title + * window title + * @return null or new alignment frame + */ + + public abstract AlignFrame loadAlignment(String text, String title); + + /** + * add the given features or annotation to the current alignment + * + * @param annotation + */ + + public abstract void loadAnnotation(String annotation); + + /** + * add the given features or annotation to the given alignment view + * + * @param alf + * @param annotation + */ + public abstract void loadAnnotationFrom(AlignFrame alf, + String annotation); + + /** + * parse the given string as a jalview feature or GFF annotation file and + * optionally enable feature display on the current AlignFrame + * + * @param features + * - gff or features file + * @param autoenabledisplay + * - when true, feature display will be enabled if any features can + * be parsed from the string. + */ + + public abstract void loadFeatures(String features, + boolean autoenabledisplay); + + /** + * parse the given string as a jalview feature or GFF annotation file and + * optionally enable feature display on the given AlignFrame. + * + * @param alf + * @param features + * - gff or features file + * @param autoenabledisplay + * - when true, feature display will be enabled if any features can + * be parsed from the string. + * @return true if data parsed as features + */ + public abstract boolean loadFeaturesFrom(AlignFrame alf, String features, + boolean autoenabledisplay); + + public boolean loadScoreFile(String sScoreFile) throws IOException; + + public void newFeatureSettings(); + + public void newStructureView(PDBEntry pdb, SequenceI[] seqs, + String[] chains, DataSourceType protocol); + + /** + * public static method for JalviewJS API to open a PCAPanel without + * necessarily using a dialog. + * + * @param af + * may be null + * @param modelName + * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences" + * if number of sequences selected is inappropriate + */ + public Object openPcaPanel(AlignFrame af, String modelName); + + /** + * Open a new Tree panel on the desktop statically. Params are standard (not + * set by Groovy). No dialog is opened. + * + * @param af + * may be null + * @param treeType + * @param modelName + * @return null, or the string "label.you_need_at_least_n_sequences" if number + * of sequences selected is inappropriate + */ + public Object openTreePanel(AlignFrame af, String treeType, + String modelName); + + /// in http://www.jalview.org/examples/jalviewLiteJs.html but missing here + + // get selected sequences as alignment as format with or without start-end + // suffix + + /** + * re-order the given alignment using the given list of sequence IDs separated + * by sep + * + * @param alf + * @param order + * - sep separated list + * @param undoName + * - string to use when referring to ordering action in undo buffer + * @param sep + * @return 'true' if alignment was actually reordered. empty string if + * alignment did not contain sequences. + */ + public abstract String orderAlignmentBy(AlignFrame alf, String order, + String undoName, String sep); + + // get a string array from a list + + /** + * re-order the current alignment using the given list of sequence IDs + * + * @param order + * - sep separated list + * @param undoName + * - string to use when referring to ordering action in undo buffer + * @return 'true' if alignment was actually reordered. empty string if + * alignment did not contain sequences. + */ + + public abstract String orderBy(String order, String undoName); + + /** + * re-order the current alignment using the given list of sequence IDs + * separated by sep + * + * @param order + * - sep separated list + * @param undoName + * - string to use when referring to ordering action in undo buffer + * @param sep + * @return 'true' if alignment was actually reordered. empty string if + * alignment did not contain sequences. + */ + + public abstract String orderBy(String order, String undoName, String sep); + + /** + * process commandline arguments after the JavaScript application has started + * + * @param args + * @return + */ + Object parseArguments(String[] args); + + // public boolean getDefaultParameter(String name, boolean def); + + public boolean parseFeaturesFile(String param, DataSourceType protocol); + + /** + * remove any callback using the given listener function and associated with + * the given AlignFrame (or null for all callbacks); + * + * @param af + * (may be null); + * @param listener + * (may be null); + */ + public abstract void removeSelectionListener(AlignFrame af, + String listener); + + // public void setAlignPdbStructures(boolean defaultParameter); + + /** + * adjust horizontal scroll to make the given column the left one in the given + * view + * + * @param alf + * @param leftHandColumn + */ + public abstract void scrollViewToColumnIn(AlignFrame alf, + String leftHandColumn); + + /** + * adjust horizontal/vertical scroll to make the given location the top left + * hand corner for the given view + * + * @param alf + * @param topRow + * @param leftHandColumn + */ + public abstract void scrollViewToIn(AlignFrame alf, String topRow, + String leftHandColumn); + + /** + * adjust vertical scroll to make the given row the top one for given view + * + * @param alf + * @param topRow + */ + public abstract void scrollViewToRowIn(AlignFrame alf, String topRow); + + /** + * select regions of the currrent alignment frame + * + * @param sequenceIds + * String separated list of sequence ids or empty string + * @param columns + * String separated list { column range or column, ..} or empty + * string + */ + + public abstract void select(String sequenceIds, String columns); + + /** + * select regions of the currrent alignment frame + * + * @param toselect + * String separated list { column range, seq1...seqn sequence ids } + * @param sep + * separator between toselect fields + */ + + public abstract void select(String sequenceIds, String columns, + String sep); + + /** + * select regions of the given alignment frame + * + * @param alf + * @param toselect + * String separated list { column range, seq1...seqn sequence ids } + * @param sep + * separator between toselect fields + */ + public abstract void selectIn(AlignFrame alf, String sequenceIds, + String columns); + + /** + * select regions of the given alignment frame + * + * @param alf + * @param toselect + * String separated list { column range, seq1...seqn sequence ids } + * @param sep + * separator between toselect fields + */ + public abstract void selectIn(AlignFrame alf, String sequenceIds, + String columns, String sep); + + public String[] separatorListToArray(String list); + + public abstract void setFeatureGroupState(String groups, boolean state); + + public void setFeatureGroupState(String[] groups, boolean state); + + // public StructureSelectionManagerProvider + // getStructureSelectionManagerProvider(); + + /** + * @param groups + * tab separated list of group names + * @param state + * true or false + * @see jalview.appletgui.AlignFrame#setFeatureGroupState(java.lang.String[], + * boolean); + */ + public abstract void setFeatureGroupStateOn(AlignFrame alf, String groups, + boolean state); + + public abstract void setSelectionListener(AlignFrame af, String listener); + + /** + * register a javascript function to handle any alignment selection events. + * Events are generated when the user completes a selection event, or when the + * user deselects all selected regions. + * + * @param listener + * name of javascript function (called with arguments + * [jalview.appletgui.AlignFrame, String(sequence set id);, + * String(separator separated list of sequences which were + * selected);, String(separator separated list of column ranges (i.e. + * single number or hyphenated range); that were selected);] + */ + + public abstract void setSelectionListener(String listener); + + /** + * List separator string + * + * @param separator + * the separator to set. empty string will reset separator to default + */ + + public abstract void setSeparator(String separator); + + void showOverview(); + + public void updateForAnnotations(); } diff --git a/src/jalview/bin/JalviewLite.java b/src/jalview/bin/JalviewLite.java index e7f2a53..6a8db59 100644 --- a/src/jalview/bin/JalviewLite.java +++ b/src/jalview/bin/JalviewLite.java @@ -45,10 +45,12 @@ import jalview.io.IdentifyFile; import jalview.io.JPredFile; import jalview.io.JnetAnnotationMaker; import jalview.io.NewickFile; -import jalview.javascript.JSFunctionExec; -import jalview.javascript.JalviewLiteJsApi; -import jalview.javascript.JsCallBack; -import jalview.javascript.MouseOverStructureListener; +import jalview.appletgui.js.JSFunctionExec; +import jalview.appletgui.js.JalviewLiteJsApi; +import jalview.appletgui.js.JsCallBack; +import jalview.appletgui.js.JsSelectionSender; +import jalview.appletgui.js.MouseOverListener; +import jalview.appletgui.js.MouseOverStructureListener; import jalview.structure.SelectionListener; import jalview.structure.StructureSelectionManager; import jalview.util.ColorUtils; @@ -920,7 +922,7 @@ public class JalviewLite extends Applet setMouseoverListener(currentAlignFrame, listener); } - private Vector javascriptListeners = new Vector<>(); + private Vector javascriptListeners = new Vector<>(); /* * (non-Javadoc) @@ -942,7 +944,7 @@ public class JalviewLite extends Applet return; } } - jalview.javascript.MouseOverListener mol = new jalview.javascript.MouseOverListener( + MouseOverListener mol = new MouseOverListener( this, af, listener); javascriptListeners.addElement(mol); StructureSelectionManager.getStructureSelectionManager(this) @@ -989,7 +991,7 @@ public class JalviewLite extends Applet return; } } - jalview.javascript.JsSelectionSender mol = new jalview.javascript.JsSelectionSender( + JsSelectionSender mol = new JsSelectionSender( this, af, listener); javascriptListeners.addElement(mol); StructureSelectionManager.getStructureSelectionManager(this) @@ -1128,7 +1130,7 @@ public class JalviewLite extends Applet { while (javascriptListeners.size() > 0) { - jalview.javascript.JSFunctionExec mol = javascriptListeners + JSFunctionExec mol = javascriptListeners .elementAt(0); javascriptListeners.removeElement(mol); if (mol instanceof SelectionListener) @@ -1155,7 +1157,7 @@ public class JalviewLite extends Applet StructureSelectionManager.release(this); } - private jalview.javascript.JSFunctionExec jsFunctionExec; + private JSFunctionExec jsFunctionExec; /* * (non-Javadoc) @@ -1230,7 +1232,7 @@ public class JalviewLite extends Applet * (non-Javadoc) * * @see - * jalview.javascript.JalviewLiteJsApi#scrollViewToRowIn(jalview.appletgui + * JalviewLiteJsApi#scrollViewToRowIn(jalview.appletgui * .AlignFrame, java.lang.String) */ @Override @@ -1261,7 +1263,7 @@ public class JalviewLite extends Applet * (non-Javadoc) * * @see - * jalview.javascript.JalviewLiteJsApi#scrollViewToColumnIn(jalview.appletgui + * JalviewLiteJsApi#scrollViewToColumnIn(jalview.appletgui * .AlignFrame, java.lang.String) */ @Override diff --git a/src/jalview/ext/jmol/JalviewJmolBinding.java b/src/jalview/ext/jmol/JalviewJmolBinding.java index 453152e..cfb30b3 100644 --- a/src/jalview/ext/jmol/JalviewJmolBinding.java +++ b/src/jalview/ext/jmol/JalviewJmolBinding.java @@ -1368,7 +1368,9 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel htmlName + ((Object) this).toString(), documentBase, codeBase, commandOptions, this); - viewer.setJmolStatusListener(this); // extends JmolCallbackListener + viewer.setJmolStatusListener(this); + + // BH how about extending Jmol's status listener? try { diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 815b5ef..6eb2dfe 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -1412,11 +1412,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, bjs.exportHTML(null); } - public void createImageMap(File file, String image) - { - alignPanel.makePNGImageMap(file, image); - } - /** * Creates a PNG image of the alignment and writes it to the given file. If * the file is null, the user is prompted to choose a file. diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 68313e1..423c62a 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -2324,7 +2324,7 @@ public class Desktop extends GDesktop { if (Jalview.isHeadlessMode()) { - return new AlignFrame[] { Jalview.currentAlignFrame }; + return new AlignFrame[] { Jalview.getInstance().currentAlignFrame }; } JInternalFrame[] frames = getDesktopPane().getAllFrames(); diff --git a/src/jalview/project/Jalview2XML.java b/src/jalview/project/Jalview2XML.java index 84fda34..9303aed 100644 --- a/src/jalview/project/Jalview2XML.java +++ b/src/jalview/project/Jalview2XML.java @@ -4326,6 +4326,12 @@ public class Jalview2XML tree.getTitle(), safeInt(tree.getWidth()), safeInt(tree.getHeight()), safeInt(tree.getXpos()), safeInt(tree.getYpos())); + if (tp == null) + { + warn("There was a problem recovering stored Newick tree: \n" + + tree.getNewick()); + continue; + } if (tree.getId() != null) { // perhaps bind the tree id to something ? @@ -4346,13 +4352,6 @@ public class Jalview2XML tp.getTreeCanvas().setAssociatedPanel(ap); // af.alignPanel; } tp.getTreeCanvas().setApplyToAllViews(tree.isLinkToAllViews()); - if (tp == null) - { - warn("There was a problem recovering stored Newick tree: \n" - + tree.getNewick()); - continue; - } - tp.fitToWindow.setState(safeBoolean(tree.isFitToWindow())); tp.fitToWindow_actionPerformed(null); diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index bb1bb94..636a460 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -1307,7 +1307,11 @@ public class StructureSelectionManager implements ApplicationSingletonI } } - public void addSelectionListener(SelectionListener selecter) + public List getListeners() { + return sel_listeners; + } + + public void addSelectionListener(SelectionListener selecter) { if (!sel_listeners.contains(selecter)) { diff --git a/src/jalview/util/Platform.java b/src/jalview/util/Platform.java index cd24432..f4ac16f 100644 --- a/src/jalview/util/Platform.java +++ b/src/jalview/util/Platform.java @@ -37,6 +37,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.util.Date; +import java.util.Map; import java.util.Properties; import java.util.logging.ConsoleHandler; import java.util.logging.Level; @@ -905,5 +906,9 @@ public class Platform return failValue; } + public static Map getAppletInfoAsMap() + { + return (isJS ? jsutil.getAppletInfoAsMap() : null); + } } diff --git a/src/swingjs/api/JSUtilI.java b/src/swingjs/api/JSUtilI.java index 1b6ff9b..cc4f8d4 100644 --- a/src/swingjs/api/JSUtilI.java +++ b/src/swingjs/api/JSUtilI.java @@ -7,6 +7,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.util.HashMap; +import java.util.Map; import java.util.Properties; import java.util.function.Function; import java.util.zip.ZipEntry; @@ -91,10 +92,10 @@ public interface JSUtilI { /** - * Get an attribute of applet's Info map for the applet found using - * getApplet(null). That is, applet.__Info[InfoKey]. + * Get the applet's __Info map or an attribute of that map for the applet found using + * getApplet(null). That is, applet.__Info or applet.__Info[InfoKey]. * - * @param infoKey + * @param infoKey if null, return the full __Info map */ Object getAppletInfo(String infoKey); @@ -329,4 +330,22 @@ public interface JSUtilI { */ void setUIEnabled(JComponent jc, boolean enabled); + + /** + * Play an audio + * @param buffer + * @param format a javax.sound.sampled.AudioFormat + * @throws Exception + */ + void playAudio(byte[] buffer, Object format) throws Exception; + + /** + * For either an applet or an application, get the ORIGINAL __Info as a Map that + * has a full set up lower-case keys along with whatever non-all-lower-case keys + * provided at start-up. + * + * @return + */ + Map getAppletInfoAsMap(); + } diff --git a/unused/JalviewAppLoader.java b/unused/JalviewAppLoader.java new file mode 100644 index 0000000..0f4833c --- /dev/null +++ b/unused/JalviewAppLoader.java @@ -0,0 +1,27 @@ +package jalview.bin; + +import java.io.File; +import java.net.URISyntaxException; + +import jalview.gui.AlignFrame; +import jalview.io.BioJsHTMLOutput; +import jalview.io.FileFormatI; +import jalview.io.HtmlSvgOutput; +import jalview.util.Platform; + +/** + * Abandoned -- see JalviewApp + * + * A class to load parameters for either JalviewLite or Jalview + * + * @author hansonr + * + */ +public class JalviewAppLoader +{ + + public JalviewAppLoader() + { + } + +} \ No newline at end of file diff --git a/unused/JalviewJSApp.java b/unused/JalviewJSApp.java new file mode 100644 index 0000000..654569d --- /dev/null +++ b/unused/JalviewJSApp.java @@ -0,0 +1,12 @@ +package jalview.bin; + +import java.util.List; + +import jalview.appletgui.js.JSFunctionExec; + +public interface JalviewJSApp +{ + + + +} -- 1.7.10.2