fix for no access-control-origin on jalview site
[jalview.git] / src / jalview / bin / JalviewJS.java
index 4e24354..a26e182 100644 (file)
@@ -1,21 +1,23 @@
 package jalview.bin;
 
+import jalview.analysis.AlignmentUtils;
+import jalview.datamodel.AlignmentI;
 import jalview.gui.AlignFrame;
-import jalview.gui.Desktop;
-import jalview.io.AppletFormatAdapter;
+import jalview.gui.SplitFrame;
 import jalview.io.DataSourceType;
 import jalview.io.FileFormatException;
 import jalview.io.FileFormatI;
 import jalview.io.FileLoader;
 import jalview.io.IdentifyFile;
+import jalview.structure.StructureSelectionManager;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 
 import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
 
 /**
  * Entry point for Jalview as Javascript. Expects parameter names as for the
@@ -31,6 +33,20 @@ import javax.swing.JFrame;
 // TODO or format as file=/examples/uniref50.fa (etc)?
 public class JalviewJS
 {
+
+  static
+  {
+    /**
+     * @j2sNative
+     * 
+     *            thisApplet.__Info.args =
+     *            ["file","examples/uniref50.fa","features",
+     *            "examples/exampleFeatures.txt",
+     *            "props","/Users/gmcarstairs/.jalview_properties"];
+     */
+
+  }
+
   private static final String PARAM_FILE = "file";
 
   private static final String PARAM_FILE2 = "file2";
@@ -51,15 +67,9 @@ public class JalviewJS
 
   private List<String> pdbFileParams;
 
-  public static void main(String[] args)
+  public static void main(String[] args) throws Exception
   {
-    try
-    {
-      new JalviewJS().doMain(args);
-    } catch (FileFormatException e)
-    {
-      e.printStackTrace();
-    }
+    new JalviewJS().doMain(args);
   }
 
   /**
@@ -96,7 +106,8 @@ public class JalviewJS
    */
   private void usage()
   {
-    System.err.println("Usage: JalviewJS file <alignmentFile>");
+    System.err.println(
+            "Usage: JalviewJS file <alignmentFile> [features <featuresFile>]");
     System.err.println("See documentation for full parameter list");
   }
 
@@ -179,17 +190,36 @@ public class JalviewJS
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
     /*
-     * construct an AlignFrame and extract its contents and menu bar
+     * construct an AlignFrame (optionally with features)
+     */
+    AlignFrame alignFrame = createAlignFrame(PARAM_FILE);
+    loadFeatures(alignFrame, getParameter(PARAM_FEATURES));
+
+    JInternalFrame internalFrame = alignFrame;
+
+    /*
+     * convert to SplitFrame if a valid file2 is supplied
+     */
+    AlignFrame alignFrame2 = createAlignFrame(PARAM_FILE2);
+    if (alignFrame2 != null)
+    {
+      SplitFrame splitFrame = loadSplitFrame(alignFrame, alignFrame2);
+      if (splitFrame != null)
+      {
+        internalFrame = splitFrame;
+      }
+    }
+
+    /*
+     * move AlignFrame (or SplitFrame) menu bar and content pane to our frame
      * TODO there may be a less obscure way to do this
      */
-    AlignFrame alignFrame = createAlignFrame();
-    frame.setContentPane(alignFrame.getContentPane());
-    frame.setJMenuBar(alignFrame.getJMenuBar());
+    frame.setContentPane(internalFrame.getContentPane());
+    frame.setJMenuBar(internalFrame.getJMenuBar());
 
     // fudge so that dialogs can be opened with this frame as parent
-    Desktop.parent = frame.getContentPane();
-
-    loadFeatures(alignFrame, getParameter(PARAM_FEATURES));
+    // todo JAL-3031 also override Desktop.addInternalFrame etc
+    // Desktop.parent = frame.getContentPane();
 
     frame.pack();
     frame.setSize(AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
@@ -197,10 +227,57 @@ public class JalviewJS
   }
 
   /**
-   * Load on a features file if one was specified as a parameter
+   * Constructs a SplitFrame if cdna-protein mappings can be made between the
+   * given alignment frames, else returns null. Any mappings made are registered
+   * with StructureSelectionManager to enable broadcast to listeners.
    * 
    * @param alignFrame
+   * @param alignFrame2
+   * @return
+   */
+  protected SplitFrame loadSplitFrame(AlignFrame alignFrame,
+          AlignFrame alignFrame2)
+  {
+    // code borrowed from AlignViewport.openLinkedAlignment
+    AlignmentI al1 = alignFrame.getViewport().getAlignment();
+    AlignmentI al2 = alignFrame2.getViewport().getAlignment();
+    boolean al1Nuc = al1.isNucleotide();
+    if (al1Nuc == al2.isNucleotide())
+    {
+      System.err.println("Can't make split frame as alignments are both "
+              + (al1Nuc ? "nucleotide" : "protein"));
+      return null;
+    }
+    AlignmentI protein = al1Nuc ? al2 : al1;
+    AlignmentI cdna = al1Nuc ? al1 : al2;
+    boolean mapped = AlignmentUtils.mapProteinAlignmentToCdna(protein,
+            cdna);
+    if (!mapped)
+    {
+      System.err.println("Can't make any mappings for split frame");
+      return null;
+    }
+
+    /*
+     * register sequence mappings
+     */
+    StructureSelectionManager ssm = StructureSelectionManager
+            .getStructureSelectionManager(null);
+    ssm.registerMappings(protein.getCodonFrames());
+
+    cdna.alignAs(protein);
+
+    SplitFrame splitFrame = new SplitFrame(
+            al1Nuc ? alignFrame : alignFrame2,
+            al1Nuc ? alignFrame2 : alignFrame);
+
+    return splitFrame;
+  }
+
+  /**
+   * Loads on a features file if one was specified as a parameter
    * 
+   * @param alignFrame
    * @param featureFile
    */
   protected void loadFeatures(AlignFrame alignFrame, String featureFile)
@@ -210,28 +287,33 @@ public class JalviewJS
       // todo extract helper for protocol resolution from JalviewLite
       DataSourceType sourceType = featureFile.startsWith("http")
               ? DataSourceType.URL
-              : DataSourceType.FILE;
+              : DataSourceType.LOCALURL;
       alignFrame.parseFeaturesFile(featureFile, sourceType);
     }
   }
 
   /**
    * Constructs and returns the frame containing the alignment and its
-   * annotations
+   * annotations. Returns null if the specified parameter value is not set.
+   * 
+   * @param fileParam
    * 
    * @return
    * @throws FileFormatException
    */
-  AlignFrame createAlignFrame() throws FileFormatException
+  AlignFrame createAlignFrame(String fileParam) throws FileFormatException
   {
-    String file = getParameter(PARAM_FILE);
-    Objects.requireNonNull(file);
-
-    DataSourceType protocol = AppletFormatAdapter.checkProtocol(file);
-    FileFormatI format = new IdentifyFile().identify(file, protocol);
-    FileLoader fileLoader = new FileLoader(false);
-    AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
-            format);
+    AlignFrame af = null;
+    String file = getParameter(fileParam);
+    if (file != null)
+    {
+      DataSourceType protocol = file.startsWith("http") ? DataSourceType.URL
+              : DataSourceType.LOCALURL;
+      // DataSourceType protocol = AppletFormatAdapter.checkProtocol(file);
+      FileFormatI format = new IdentifyFile().identify(file, protocol);
+      FileLoader fileLoader = new FileLoader(false);
+      af = fileLoader.LoadFileWaitTillLoaded(file, protocol, format);
+    }
 
     return af;
   }