JalviewAppLoader for moving code from JalviewLite relating to applet
authorhansonr <hansonr@STO24954W.ad.stolaf.edu>
Mon, 13 May 2019 02:17:12 +0000 (21:17 -0500)
committerhansonr <hansonr@STO24954W.ad.stolaf.edu>
Mon, 13 May 2019 02:17:12 +0000 (21:17 -0500)
parameters

src/jalview/api/JalviewApp.java [new file with mode: 0644]
src/jalview/bin/Cache.java
src/jalview/bin/Jalview.java
src/jalview/bin/JalviewAppLoader.java [new file with mode: 0644]
src/jalview/bin/JalviewLite.java
test/jalview/bin/JalviewLiteTest.java

diff --git a/src/jalview/api/JalviewApp.java b/src/jalview/api/JalviewApp.java
new file mode 100644 (file)
index 0000000..1d67bc2
--- /dev/null
@@ -0,0 +1,43 @@
+package jalview.api;
+
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.NewickFile;
+
+import java.io.IOException;
+import java.net.URL;
+
+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 updateForLoader();
+
+  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;
+
+}
index fd382b3..086419b 100755 (executable)
@@ -297,8 +297,7 @@ public class Cache
   };
 
   /** Default file is ~/.jalview_properties */
-  // BH 2019.05.07 note: Instances of Jalview will share this file.
-  static String propertiesFile;
+  private String propertiesFile;
 
   /**
    * flag to possibly allow properties to be written to a property file
@@ -624,18 +623,7 @@ public class Cache
    */
   public static String getProperty(String key)
   {
-    return getInstance().getPropertyImpl(key);
-  }
-
-  private String getPropertyImpl(String key)
-  {
-    String prop = applicationProperties.getProperty(key);
-    if (prop == null && Platform.isJS())
-    {
-      prop = applicationProperties.getProperty(Platform.getUniqueAppletID()
-              + "_" + JS_PROPERTY_PREFIX + key);
-    }
-    return prop;
+    return getInstance().applicationProperties.getProperty(key);
   }
 
   /**
index 4167753..cb2b469 100755 (executable)
  */
 package jalview.bin;
 
+import jalview.api.AlignViewportI;
+import jalview.api.JalviewApp;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
 import jalview.ext.so.SequenceOntology;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
+import jalview.gui.Preferences;
 import jalview.gui.PromptUserConfig;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.BioJsHTMLOutput;
@@ -115,6 +120,10 @@ public class Jalview
 
   private AlignFrame currentAlignFrame;
 
+  public boolean isJavaAppletTag;
+
+  public String appletResourcePath;
+
   public static AlignFrame getCurrentAlignFrame()
   {
     return getInstance().currentAlignFrame;
@@ -285,19 +294,32 @@ public class Jalview
 
     String usrPropsFile = aparser.getValue(ArgsParser.PROPS);
     Cache.loadProperties(usrPropsFile);
-    if (usrPropsFile != null)
+    if (Platform.isJS())
     {
+      isJavaAppletTag = aparser.isApplet();
+      if (isJavaAppletTag)
+      {
+        Preferences.setAppletDefaults();
+        Cache.loadProperties(usrPropsFile); // again, because we
+        // might be changing defaults here?
+      }
       System.out.println(
-              "CMD [-props " + usrPropsFile + "] executed successfully!");
+              "<Applet> found: " + aparser.getValue("Info.j2sAppletID"));
+      appletResourcePath = aparser.getValue("Info.resourcePath");
     }
-
-    if (!Platform.isJS())
+    else
     /**
      * Java only
      * 
      * @j2sIgnore
      */
     {
+      if (usrPropsFile != null)
+      {
+        System.out.println(
+                "CMD [-props " + usrPropsFile + "] executed successfully!");
+      }
+
       if (aparser.contains("help") || aparser.contains("h"))
       {
         showUsage();
@@ -740,94 +762,103 @@ public class Jalview
                   + "] executed successfully!");
           groovyscript = null;
         }
-        String imageName = "unnamed.png";
-        while (aparser.getSize() > 1)
+
+        if (isJavaAppletTag)
+        {
+          loadAppletParams(aparser, af);
+        }
+        else
         {
-          // PNG filename
-          // SVG filename
-          // HTML filename
-          // biojsmsa filename
-          String outputFormat = aparser.nextValue();
-          file = aparser.nextValue();
-
-          if (outputFormat.equalsIgnoreCase("png"))
-          {
-            af.createPNG(new File(file));
-            imageName = (new File(file)).getName();
-            System.out.println("Creating PNG image: " + file);
-            continue;
-          }
-          else if (outputFormat.equalsIgnoreCase("svg"))
-          {
-            File imageFile = new File(file);
-            imageName = imageFile.getName();
-            af.createSVG(imageFile);
-            System.out.println("Creating SVG image: " + file);
-            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);
-            continue;
-          }
-          else if (outputFormat.equalsIgnoreCase("biojsmsa"))
+          String imageName = "unnamed.png";
+          while (aparser.getSize() > 1)
           {
-            if (file == null)
+            // PNG filename
+            // SVG filename
+            // HTML filename
+            // biojsmsa filename
+            String outputFormat = aparser.nextValue();
+            file = aparser.nextValue();
+
+            if (outputFormat.equalsIgnoreCase("png"))
             {
-              System.err.println("The output html file must not be null");
-              return;
+              af.createPNG(new File(file));
+              imageName = (new File(file)).getName();
+              System.out.println("Creating PNG image: " + file);
+              continue;
             }
-            try
+            else if (outputFormat.equalsIgnoreCase("svg"))
             {
-              BioJsHTMLOutput.refreshVersionInfo(
-                      BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
-            } catch (URISyntaxException e)
+              File imageFile = new File(file);
+              imageName = imageFile.getName();
+              af.createSVG(imageFile);
+              System.out.println("Creating SVG image: " + file);
+              continue;
+            }
+            else if (outputFormat.equalsIgnoreCase("html"))
             {
-              e.printStackTrace();
+              File imageFile = new File(file);
+              imageName = imageFile.getName();
+              HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
+              htmlSVG.exportHTML(file);
+
+              System.out.println("Creating HTML image: " + file);
+              continue;
+            }
+            else if (outputFormat.equalsIgnoreCase("biojsmsa"))
+            {
+              if (file == null)
+              {
+                System.err.println("The output html file must not be null");
+                return;
+              }
+              try
+              {
+                BioJsHTMLOutput.refreshVersionInfo(
+                        BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
+              } catch (URISyntaxException e)
+              {
+                e.printStackTrace();
+              }
+              BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
+              bjs.exportHTML(file);
+              System.out.println(
+                      "Creating BioJS MSA Viwer HTML file: " + file);
+              continue;
+            }
+            else if (outputFormat.equalsIgnoreCase("imgMap"))
+            {
+              af.createImageMap(new File(file), imageName);
+              System.out.println("Creating image map: " + file);
+              continue;
+            }
+            else if (outputFormat.equalsIgnoreCase("eps"))
+            {
+              File outputFile = new File(file);
+              System.out.println(
+                      "Creating EPS file: " + outputFile.getAbsolutePath());
+              af.createEPS(outputFile);
+              continue;
+            }
+
+            af.saveAlignment(file, format);
+            if (af.isSaveAlignmentSuccessful())
+            {
+              System.out.println("Written alignment in " + format
+                      + " format to " + file);
+            }
+            else
+            {
+              System.out.println("Error writing file " + file + " in "
+                      + format + " format!!");
             }
-            BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
-            bjs.exportHTML(file);
-            System.out
-                    .println("Creating BioJS MSA Viwer HTML file: " + file);
-            continue;
-          }
-          else if (outputFormat.equalsIgnoreCase("imgMap"))
-          {
-            af.createImageMap(new File(file), imageName);
-            System.out.println("Creating image map: " + file);
-            continue;
-          }
-          else if (outputFormat.equalsIgnoreCase("eps"))
-          {
-            File outputFile = new File(file);
-            System.out.println(
-                    "Creating EPS file: " + outputFile.getAbsolutePath());
-            af.createEPS(outputFile);
-            continue;
-          }
 
-          af.saveAlignment(file, format);
-          if (af.isSaveAlignmentSuccessful())
-          {
-            System.out.println("Written alignment in " + format
-                    + " format to " + file);
           }
-          else
+
+          while (aparser.getSize() > 0)
           {
-            System.out.println("Error writing file " + file + " in "
-                    + format + " format!!");
+            System.out.println("Unknown arg: " + aparser.nextValue());
           }
-
-        }
-
-        while (aparser.getSize() > 0)
-        {
-          System.out.println("Unknown arg: " + aparser.nextValue());
         }
       }
     }
@@ -1129,4 +1160,132 @@ public class Jalview
     }
   }
 
+  /**
+   * Get the SwingJS applet ID and combine that with the frameType
+   * 
+   * @param frameType
+   *          "alignment", "desktop", etc., or null
+   * @return
+   */
+  public static String getAppID(String frameType)
+  {
+    String id = Cache.getProperty("Info.j2sAppletID");
+    if (id == null)
+    {
+      id = "jalview";
+    }
+    return id + (frameType == null ? "" : "-" + frameType);
+  }
+
+  private void loadAppletParams(ArgsParser aparser, AlignFrame af)
+  {
+    Jalview me = this;
+    JalviewApp app = new JalviewApp()
+    {
+
+
+      @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));
+      }
+
+      @Override
+      public URL getDocumentBase()
+      {
+        return Platform.getDocumentBase();
+      }
+
+      @Override
+      public URL getCodeBase()
+      {
+        return Platform.getCodeBase();
+      }
+
+      @Override
+      public AlignViewportI getViewport()
+      {
+        return Jalview.getCurrentAlignFrame().getViewport();
+      }
+
+      @Override
+      public boolean loadScoreFile(String sScoreFile) throws IOException
+      {
+        Jalview.getCurrentAlignFrame().loadJalviewDataFile(sScoreFile, null,
+                null, null);
+        return true;
+      }
+
+      @Override
+      public boolean parseFeaturesFile(String filename,
+              DataSourceType protocol)
+      {
+        return af.parseFeaturesFile(filename, protocol);
+      }
+
+      @Override
+      public void loadTree(NewickFile fin, String treeFile)
+              throws IOException
+      {
+        // n/a -- already done
+      }
+
+      @Override
+      public void setAlignPdbStructures(boolean defaultParameter)
+      {
+        // TODO Auto-generated method stub
+
+      }
+
+      @Override
+      public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
+              String[] chains, DataSourceType protocol)
+      {
+        // TODO Auto-generated method stub
+
+      }
+
+      @Override
+      public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
+              String[][] chains, String[] protocols)
+      {
+        // TODO Auto-generated method stub
+
+      }
+
+      @Override
+      public void updateForLoader()
+      {
+        // TODO Auto-generated method stub
+
+      }
+
+      @Override
+      public void setFeatureGroupState(String[] groups, boolean state)
+      {
+        // TODO Auto-generated method stub
+
+      }
+
+      @Override
+      public void newFeatureSettings()
+      {
+        // TODO Auto-generated method stub
+
+      }
+
+    };
+
+    new JalviewAppLoader(true).load(app);
+
+  }
+
 }
diff --git a/src/jalview/bin/JalviewAppLoader.java b/src/jalview/bin/JalviewAppLoader.java
new file mode 100644 (file)
index 0000000..5d60cf9
--- /dev/null
@@ -0,0 +1,653 @@
+package jalview.bin;
+
+import jalview.api.JalviewApp;
+import jalview.api.StructureSelectionManagerProvider;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.io.AnnotationFile;
+import jalview.io.DataSourceType;
+import jalview.io.JPredFile;
+import jalview.io.JnetAnnotationMaker;
+import jalview.io.NewickFile;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.HttpUtils;
+import jalview.util.MessageManager;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * A class to load parameters for either JalviewLite or Jalview
+ * 
+ * @author hansonr
+ *
+ */
+public class JalviewAppLoader
+{
+
+  private JalviewApp app;
+
+  private boolean debug;
+
+  private String separator;
+
+  public JalviewAppLoader(boolean debug)
+  {
+    this.debug = debug;
+  }
+
+  public void load(JalviewApp app)
+  {
+
+    this.app = app;
+
+    String sep = app.getParameter("separator");
+    if (sep != null)
+    {
+      if (sep.length() > 0)
+      {
+        separator = sep;
+      }
+      else
+      {
+        throw new Error(MessageManager
+                .getString("error.invalid_separator_parameter"));
+      }
+    }
+
+    loadTree();
+    loadScoreFile();
+    loadFeatures();
+    loadAnnotations();
+    loadJnetFile();
+    loadPdbFiles();
+  }
+
+  /**
+   * Load PDBFiles if any specified by parameter(s). Returns true if loaded,
+   * else false.
+   * 
+   * @param loaderFrame
+   * @return
+   */
+  protected boolean loadPdbFiles()
+  {
+    boolean result = false;
+    /*
+     * <param name="alignpdbfiles" value="false/true"/> Undocumented for 2.6 -
+     * related to JAL-434
+     */
+
+    boolean doAlign = app.getDefaultParameter("alignpdbfiles", false);
+    app.setAlignPdbStructures(doAlign);
+    /*
+     * <param name="PDBfile" value="1gaq.txt PDB|1GAQ|1GAQ|A PDB|1GAQ|1GAQ|B
+     * PDB|1GAQ|1GAQ|C">
+     * 
+     * <param name="PDBfile2" value="1gaq.txt A=SEQA B=SEQB C=SEQB">
+     * 
+     * <param name="PDBfile3" value="1q0o Q45135_9MICO">
+     */
+
+    int pdbFileCount = 0;
+    // Accumulate pdbs here if they are heading for the same view (if
+    // alignPdbStructures is true)
+    Vector<Object[]> 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;
+
+    String param;
+    do
+    {
+      if (pdbFileCount > 0)
+      {
+        param = app.getParameter("PDBFILE" + pdbFileCount);
+      }
+      else
+      {
+        param = app.getParameter("PDBFILE");
+      }
+
+      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 = app.getParameter("PDBSEQ");
+          if (sequence != null)
+          {
+            seqs = new SequenceI[] { matcher == null
+                    ? (Sequence) app.getViewport().getAlignment()
+                            .findName(sequence)
+                    : matcher.findIdMatch(sequence) };
+          }
+
+        }
+        else
+        {
+          param = st.nextToken();
+          List<SequenceI> tmp = new ArrayList<>();
+          List<String> 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) app.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()]);
+          }
+        }
+        ret[0] = param;
+        DataSourceType protocol = resolveFileProtocol(app,
+                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) 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 + ")");
+              }
+            }
+          }
+
+          if (doAlign)
+          {
+            pdbs.addElement(new Object[] { pdb, seqs, chains, protocol });
+          }
+          else
+          {
+            app.newStructureView(pdb, seqs, chains, protocol);
+          }
+        }
+      }
+
+      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;
+  }
+
+  /**
+   * Load in a Jnetfile if specified by parameter. Returns true if loaded, else
+   * false.
+   * 
+   * @param alignFrame
+   * @return
+   */
+  protected boolean loadJnetFile()
+  {
+    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.updateForLoader();
+        result = true;
+      } catch (Exception ex)
+      {
+        ex.printStackTrace();
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Load annotations if specified by parameter. Returns true if loaded, else
+   * false.
+   * 
+   * @param alignFrame
+   * @return
+   */
+  protected boolean loadAnnotations()
+  {
+    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.updateForLoader();
+        result = true;
+      }
+      else
+      {
+        System.err
+                .println("Annotations were not added from annotation file '"
+                        + param + "'");
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Load features file and view settings as specified by parameters. Returns
+   * true if features were loaded, else false.
+   * 
+   * @param alignFrame
+   * @return
+   */
+  protected boolean loadFeatures()
+  {
+    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(param, protocol);
+    }
+
+    param = app.getParameter("showFeatureSettings");
+    if (param != null && param.equalsIgnoreCase("true"))
+    {
+      app.newFeatureSettings();
+    }
+    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 = 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;
+  }
+
+  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()
+  {
+    boolean result = false;
+    String treeFile = app.getParameter("tree");
+    if (treeFile == null)
+    {
+      treeFile = app.getParameter("treeFile");
+    }
+
+    if (treeFile != null)
+    {
+      try
+      {
+        ret[0] = treeFile;
+        NewickFile fin = new NewickFile(treeFile,
+                resolveFileProtocol(app, ret));
+        fin.parse();
+
+        if (fin.getTree() != null)
+        {
+          app.loadTree(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;
+  }
+
+  /**
+   * 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)
+  {
+    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 (JalviewLite.debug)
+    {
+      System.err.println(
+              "resolveUrlForLocalOrAbsolute returning " + resolvedPath);
+    }
+    return resolvedPath;
+  }
+
+  /**
+   * parse the string into a list
+   * 
+   * @param list
+   * @param separator
+   * @return elements separated by separator
+   */
+  public static String[] separatorListToArray(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<String> 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)
+    {
+      String[] v = new String[jv.size()];
+      for (int i = 0; i < v.length; i++)
+      {
+        v[i] = jv.elementAt(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] + "'");
+      // }
+      // }
+      return v;
+    }
+    // if (debug)
+    // {
+    // System.err.println(
+    // "Empty Array from '" + separator + "' separated List");
+    // }
+    return null;
+  }
+
+  public static DataSourceType resolveFileProtocol(JalviewApp app,
+          String[] retPath)
+  {
+    String path = retPath[0];
+    /*
+     * is it paste data?
+     */
+    if (path.startsWith("PASTE"))
+    {
+      retPath[0] = path.substring(5);
+      return DataSourceType.PASTE;
+    }
+  
+    /*
+     * is it a URL?
+     */
+    if (path.indexOf("://") >= 0)
+    {
+      return DataSourceType.URL;
+    }
+  
+    /*
+     * 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;
+    }
+  
+    /*
+     * 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))
+    {
+      // if (debug)
+      // {
+      // System.err.println("Prepended codebase '" + codeBase
+      // + "' to make: '" + withCodeBase + "'");
+      // }
+      retPath[0] = withCodeBase;
+      return DataSourceType.URL;
+    }
+
+    /*
+     * try locating by classloader; try this last so files in the directory
+     * are resolved using document base
+     */
+    if (inArchive(app.getClass(), path))
+    {
+      return DataSourceType.CLASSLOADER;
+    }
+    return null;
+  }
+
+  /**
+   * 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 rtn = (c.getResourceAsStream("/" + f) != null);
+      // if (debug)
+      // {
+      // System.err.println("Resource '" + f + "' was "
+      // + (rtn ? "" : "not ") + "located by classloader.");
+      // }
+      return rtn;
+    } catch (Exception ex)
+    {
+      System.out.println("Exception checking resources: " + f + " " + ex);
+      return false;
+    }
+  }
+
+}
index e483fce..5cb599f 100644 (file)
@@ -21,6 +21,8 @@
 package jalview.bin;
 
 import jalview.analysis.AlignmentUtils;
+import jalview.api.AlignViewportI;
+import jalview.api.JalviewApp;
 import jalview.api.StructureSelectionManagerProvider;
 import jalview.appletgui.AlignFrame;
 import jalview.appletgui.AlignViewport;
@@ -32,7 +34,6 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentOrder;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.PDBEntry;
-import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.io.AnnotationFile;
@@ -42,8 +43,6 @@ import jalview.io.FileFormatI;
 import jalview.io.FileFormats;
 import jalview.io.FileParse;
 import jalview.io.IdentifyFile;
-import jalview.io.JPredFile;
-import jalview.io.JnetAnnotationMaker;
 import jalview.io.NewickFile;
 import jalview.javascript.JSFunctionExec;
 import jalview.javascript.JalviewLiteJsApi;
@@ -52,7 +51,6 @@ import jalview.javascript.MouseOverStructureListener;
 import jalview.structure.SelectionListener;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.ColorUtils;
-import jalview.util.HttpUtils;
 import jalview.util.MessageManager;
 
 import java.applet.Applet;
@@ -73,7 +71,6 @@ 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 netscape.javascript.JSObject;
@@ -85,9 +82,14 @@ import netscape.javascript.JSObject;
  * @version $Revision: 1.92 $
  */
 public class JalviewLite extends Applet
-        implements StructureSelectionManagerProvider, JalviewLiteJsApi
+        implements StructureSelectionManagerProvider, JalviewLiteJsApi,
+        JalviewApp
 {
 
+  public JalviewLite()
+  {
+    appLoader = new JalviewAppLoader(debug);
+  }
   private static final String TRUE = "true";
 
   private static final String FALSE = "false";
@@ -294,8 +296,8 @@ public class JalviewLite extends Applet
       }
     }
     // deparse fields
-    String[] ids = separatorListToArray(sequenceIds, sep);
-    String[] cols = separatorListToArray(columns, sep);
+    String[] ids = JalviewAppLoader.separatorListToArray(sequenceIds, sep);
+    String[] cols = JalviewAppLoader.separatorListToArray(columns, sep);
     final SequenceGroup sel = new SequenceGroup();
     final ColumnSelection csel = new ColumnSelection();
     AlignmentI al = alf.viewport.getAlignment();
@@ -618,7 +620,7 @@ public class JalviewLite extends Applet
   public String orderAlignmentBy(AlignFrame alf, String order,
           String undoName, String sep)
   {
-    String[] ids = separatorListToArray(order, sep);
+    String[] ids = JalviewAppLoader.separatorListToArray(order, sep);
     SequenceI[] sqs = null;
     if (ids != null && ids.length > 0)
     {
@@ -1338,6 +1340,10 @@ public class JalviewLite extends Applet
    */
   public boolean useXtrnalSviewer = false;
 
+  public JalviewAppLoader appLoader;
+
+  public AlignFrame loaderFrame;
+
   public static boolean debug = false;
 
   static String builddate = null, version = null, installation = null;
@@ -1836,7 +1842,7 @@ public class JalviewLite extends Applet
 
     JalviewLite applet;
 
-    private void dbgMsg(String msg)
+    public void dbgMsg(String msg)
     {
       if (JalviewLite.debug)
       {
@@ -1853,67 +1859,10 @@ public class JalviewLite extends Applet
      */
     public String resolveFileProtocol(String path)
     {
-      /*
-       * is it paste data?
-       */
-      if (path.startsWith("PASTE"))
-      {
-        protocol = DataSourceType.PASTE;
-        return path.substring(5);
-      }
-
-      /*
-       * is it a URL?
-       */
-      if (path.indexOf("://") != -1)
-      {
-        protocol = DataSourceType.URL;
-        return path;
-      }
-
-      /*
-       * 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 + "'");
-        }
-        protocol = DataSourceType.URL;
-        return withDocBase;
-      }
-
-      /*
-       * try relative to codebase (if different to document base)
-       */
-      URL codeBase = getCodeBase();
-      String withCodeBase = applet.resolveUrlForLocalOrAbsolute(path,
-              codeBase);
-      if (!withCodeBase.equals(withDocBase)
-              && HttpUtils.isValidUrl(withCodeBase))
-      {
-        protocol = DataSourceType.URL;
-        if (debug)
-        {
-          System.err.println("Prepended codebase '" + codeBase
-                  + "' to make: '" + withCodeBase + "'");
-        }
-        return withCodeBase;
-      }
 
-      /*
-       * try locating by classloader; try this last so files in the directory
-       * are resolved using document base
-       */
-      if (inArchive(path))
-      {
-        protocol = DataSourceType.CLASSLOADER;
-      }
-      return path;
+      String[] ret = new String[] { path };
+      protocol = JalviewAppLoader.resolveFileProtocol(applet, ret);
+      return ret[0];
     }
 
     public LoadingThread(String file, String file2, JalviewLite _applet)
@@ -1958,17 +1907,8 @@ public class JalviewLite extends Applet
       if (newAlignFrame != null)
       {
         addToDisplay(newAlignFrame, newAlignFrame2);
-        loadTree(newAlignFrame);
-
-        loadScoreFile(newAlignFrame);
-
-        loadFeatures(newAlignFrame);
-
-        loadAnnotations(newAlignFrame);
-
-        loadJnetFile(newAlignFrame);
-
-        loadPdbFiles(newAlignFrame);
+        applet.loaderFrame = newAlignFrame;
+        appLoader.load(applet);
       }
       else
       {
@@ -2089,392 +2029,6 @@ public class JalviewLite extends Applet
       return null;
     }
 
-    /**
-     * Load PDBFiles if any specified by parameter(s). Returns true if loaded,
-     * else false.
-     * 
-     * @param alignFrame
-     * @return
-     */
-    protected boolean loadPdbFiles(AlignFrame alignFrame)
-    {
-      boolean result = false;
-      /*
-       * <param name="alignpdbfiles" value="false/true"/> Undocumented for 2.6 -
-       * related to JAL-434
-       */
-
-      applet.setAlignPdbStructures(
-              getDefaultParameter("alignpdbfiles", false));
-      /*
-       * <param name="PDBfile" value="1gaq.txt PDB|1GAQ|1GAQ|A PDB|1GAQ|1GAQ|B
-       * PDB|1GAQ|1GAQ|C">
-       * 
-       * <param name="PDBfile2" value="1gaq.txt A=SEQA B=SEQB C=SEQB">
-       * 
-       * <param name="PDBfile3" value="1q0o Q45135_9MICO">
-       */
-
-      int pdbFileCount = 0;
-      // 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 = (applet
-              .getDefaultParameter("relaxedidmatch", false))
-                      ? new jalview.analysis.SequenceIdMatcher(
-                              alignFrame.getAlignViewport().getAlignment()
-                                      .getSequencesArray())
-                      : null;
-
-      String param;
-      do
-      {
-        if (pdbFileCount > 0)
-        {
-          param = applet.getParameter("PDBFILE" + pdbFileCount);
-        }
-        else
-        {
-          param = applet.getParameter("PDBFILE");
-        }
-
-        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 = applet.getParameter("PDBSEQ");
-            if (sequence != null)
-            {
-              seqs = new SequenceI[] { matcher == null
-                      ? (Sequence) alignFrame.getAlignViewport()
-                              .getAlignment().findName(sequence)
-                      : matcher.findIdMatch(sequence) };
-            }
-
-          }
-          else
-          {
-            param = st.nextToken();
-            List<SequenceI> tmp = new ArrayList<>();
-            List<String> 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) alignFrame.getAlignViewport()
-                              .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()]);
-            }
-          }
-          param = resolveFileProtocol(param);
-          // TODO check JAL-357 for files in a jar (CLASSLOADER)
-          pdb.setFile(param);
-
-          if (seqs != null)
-          {
-            for (int i = 0; i < seqs.length; i++)
-            {
-              if (seqs[i] != null)
-              {
-                ((Sequence) seqs[i]).addPDBId(pdb);
-                StructureSelectionManager
-                        .getStructureSelectionManager(applet)
-                        .registerPDBEntry(pdb);
-              }
-              else
-              {
-                if (JalviewLite.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 (!alignPdbStructures)
-            {
-              alignFrame.newStructureView(applet, pdb, seqs, chains,
-                      protocol);
-            }
-            else
-            {
-              pdbs.addElement(new Object[] { pdb, seqs, chains, protocol });
-            }
-          }
-        }
-
-        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 = (Object[]) pdbs.elementAt(pdbsi);
-          pdb[pdbsi] = (PDBEntry) o[0];
-          seqs[pdbsi] = (SequenceI[]) o[1];
-          chains[pdbsi] = (String[]) o[2];
-          protocols[pdbsi] = (String) o[3];
-        }
-        alignFrame.alignedStructureView(applet, pdb, seqs, chains,
-                protocols);
-        result = true;
-      }
-      return result;
-    }
-
-    /**
-     * Load in a Jnetfile if specified by parameter. Returns true if loaded,
-     * else false.
-     * 
-     * @param alignFrame
-     * @return
-     */
-    protected boolean loadJnetFile(AlignFrame alignFrame)
-    {
-      boolean result = false;
-      String param = applet.getParameter("jnetfile");
-      if (param == null)
-      {
-        // jnet became jpred around 2016
-        param = applet.getParameter("jpredfile");
-      }
-      if (param != null)
-      {
-        try
-        {
-          param = resolveFileProtocol(param);
-          JPredFile predictions = new JPredFile(param, protocol);
-          JnetAnnotationMaker.add_annotation(predictions,
-                  alignFrame.viewport.getAlignment(), 0, false);
-          // false == do not add sequence profile from concise output
-
-          alignFrame.viewport.getAlignment().setupJPredAlignment();
-
-          alignFrame.alignPanel.fontChanged();
-          alignFrame.alignPanel.setScrollValues(0, 0);
-          result = true;
-        } catch (Exception ex)
-        {
-          ex.printStackTrace();
-        }
-      }
-      return result;
-    }
-
-    /**
-     * Load annotations if specified by parameter. Returns true if loaded, else
-     * false.
-     * 
-     * @param alignFrame
-     * @return
-     */
-    protected boolean loadAnnotations(AlignFrame alignFrame)
-    {
-      boolean result = false;
-      String param = applet.getParameter("annotations");
-      if (param != null)
-      {
-        param = resolveFileProtocol(param);
-
-        if (new AnnotationFile().annotateAlignmentView(alignFrame.viewport,
-                param, protocol))
-        {
-          alignFrame.alignPanel.fontChanged();
-          alignFrame.alignPanel.setScrollValues(0, 0);
-          result = true;
-        }
-        else
-        {
-          System.err.println(
-                  "Annotations were not added from annotation file '"
-                          + param + "'");
-        }
-      }
-      return result;
-    }
-
-    /**
-     * Load features file and view settings as specified by parameters. Returns
-     * true if features were loaded, else false.
-     * 
-     * @param alignFrame
-     * @return
-     */
-    protected boolean loadFeatures(AlignFrame alignFrame)
-    {
-      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 = applet.getParameter("hidefeaturegroups");
-      if (param != null)
-      {
-        alignFrame.setFeatureGroupState(separatorListToArray(param), false);
-        // applet.setFeatureGroupStateOn(newAlignFrame, param, false);
-      }
-      // show specific groups
-      param = applet.getParameter("showfeaturegroups");
-      if (param != null)
-      {
-        alignFrame.setFeatureGroupState(separatorListToArray(param), true);
-        // applet.setFeatureGroupStateOn(newAlignFrame, param, true);
-      }
-      // and now load features
-      param = applet.getParameter("features");
-      if (param != null)
-      {
-        param = resolveFileProtocol(param);
-
-        result = alignFrame.parseFeaturesFile(param, protocol);
-      }
-
-      param = applet.getParameter("showFeatureSettings");
-      if (param != null && param.equalsIgnoreCase(TRUE))
-      {
-        alignFrame.viewport.setShowSequenceFeatures(true);
-        new FeatureSettings(alignFrame.alignPanel);
-      }
-      return result;
-    }
-
-    /**
-     * Load a score file if specified by parameter. Returns true if file was
-     * loaded, else false.
-     * 
-     * @param alignFrame
-     */
-    protected boolean loadScoreFile(AlignFrame alignFrame)
-    {
-      boolean result = false;
-      String sScoreFile = applet.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 = alignFrame.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;
-    }
-
-    /**
-     * Load a tree for the alignment if specified by parameter. Returns true if
-     * a tree was loaded, else false.
-     * 
-     * @param alignFrame
-     * @return
-     */
-    protected boolean loadTree(AlignFrame alignFrame)
-    {
-      boolean result = false;
-      String treeFile = applet.getParameter("tree");
-      if (treeFile == null)
-      {
-        treeFile = applet.getParameter("treeFile");
-      }
-
-      if (treeFile != null)
-      {
-        try
-        {
-          treeFile = resolveFileProtocol(treeFile);
-          NewickFile fin = new NewickFile(treeFile, protocol);
-          fin.parse();
-
-          if (fin.getTree() != null)
-          {
-            alignFrame.loadTree(fin, treeFile);
-            result = true;
-            dbgMsg("Successfully imported tree.");
-          }
-          else
-          {
-            dbgMsg("Tree parameter did not resolve to a valid tree.");
-          }
-        } catch (Exception ex)
-        {
-          ex.printStackTrace();
-        }
-      }
-      return result;
-    }
-
-    /**
-     * Discovers whether the given file is in the Applet Archive
-     * 
-     * @param f
-     *          String
-     * @return boolean
-     */
-    boolean inArchive(String f)
-    {
-      // This might throw a security exception in certain browsers
-      // Netscape Communicator for instance.
-      try
-      {
-        boolean rtn = (getClass().getResourceAsStream("/" + f) != null);
-        if (debug)
-        {
-          System.err.println("Resource '" + f + "' was "
-                  + (rtn ? "" : "not ") + "located by classloader.");
-        }
-        return rtn;
-      } catch (Exception ex)
-      {
-        System.out.println("Exception checking resources: " + f + " " + ex);
-        return false;
-      }
-    }
   }
 
   /**
@@ -2517,64 +2071,7 @@ public class JalviewLite extends Applet
    */
   public String[] separatorListToArray(String list)
   {
-    return separatorListToArray(list, separator);
-  }
-
-  /**
-   * parse the string into a list
-   * 
-   * @param list
-   * @param separator
-   * @return elements separated by separator
-   */
-  public static String[] separatorListToArray(String list, String separator)
-  {
-    // TODO use StringUtils version (slightly different...)
-    int seplen = separator.length();
-    if (list == null || list.equals("") || list.equals(separator))
-    {
-      return null;
-    }
-    java.util.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)
-    {
-      String[] v = new String[jv.size()];
-      for (int i = 0; i < v.length; i++)
-      {
-        v[i] = (String) jv.elementAt(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] + "'");
-        }
-      }
-      return v;
-    }
-    if (debug)
-    {
-      System.err.println(
-              "Empty Array from '" + separator + "' separated List");
-    }
-    return null;
+    return JalviewAppLoader.separatorListToArray(list, separator);
   }
 
   /**
@@ -2755,6 +2252,7 @@ public class JalviewLite extends Applet
    *          the value to return otherwise
    * @return true or false
    */
+  @Override
   public boolean getDefaultParameter(String name, boolean def)
   {
     String stn;
@@ -2782,7 +2280,8 @@ public class JalviewLite extends Applet
     return alFrame.addPdbFile(sequenceId, pdbEntryString, pdbFile);
   }
 
-  protected void setAlignPdbStructures(boolean alignPdbStructures)
+  @Override
+  public void setAlignPdbStructures(boolean alignPdbStructures)
   {
     this.alignPdbStructures = alignPdbStructures;
   }
@@ -2914,66 +2413,6 @@ public class JalviewLite extends Applet
   }
 
   /**
-   * 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
-   */
-  private String resolveUrlForLocalOrAbsolute(String targetPath,
-          URL localref)
-  {
-    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;
-  }
-
-  /**
    * open a URL in the browser - resolving it according to relative refs and
    * coping with javascript: protocol if necessary.
    * 
@@ -2990,7 +2429,7 @@ public class JalviewLite extends Applet
         // form valid URL
         // Should really use docbase, not codebase.
         URL prepend;
-        url = resolveUrlForLocalOrAbsolute(url,
+        url = JalviewAppLoader.resolveUrlForLocalOrAbsolute(url,
                 prepend = getDefaultParameter("resolvetocodebase", false)
                         ? getCodeBase()
                         : getDocumentBase());
@@ -3023,6 +2462,65 @@ public class JalviewLite extends Applet
     }
   }
 
+  @Override
+  public AlignViewportI getViewport()
+  {
+    return loaderFrame.getAlignViewport();
+  }
+
+  @Override
+  public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
+          String[] chains, DataSourceType protocol)
+  {
+    loaderFrame.newStructureView(this, pdb, seqs, chains,
+            protocol);
+  }
+
+  @Override
+  public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
+          String[][] chains, String[] protocols)
+  {
+    loaderFrame.alignedStructureView(this, pdb, seqs, chains, protocols);
+  }
+
+  @Override
+  public void updateForLoader()
+  {
+    loaderFrame.alignPanel.fontChanged();
+    loaderFrame.alignPanel.setScrollValues(0, 0);
+  }
+
+  @Override
+  public void setFeatureGroupState(String[] groups, boolean state)
+  {
+    loaderFrame.setFeatureGroupState(groups, state);
+  }
+
+  @Override
+  public boolean parseFeaturesFile(String param, DataSourceType protocol)
+  {
+    return loaderFrame.parseFeaturesFile(param, protocol);
+  }
+
+  @Override
+  public void newFeatureSettings()
+  {
+    getViewport().setShowSequenceFeatures(true);
+    new FeatureSettings(loaderFrame.alignPanel);
+  }
+
+  @Override
+  public boolean loadScoreFile(String sScoreFile) throws IOException
+  {
+    return loaderFrame.loadScoreFile(sScoreFile);
+  }
+
+  @Override
+  public void loadTree(NewickFile tree, String treeFile) throws IOException
+  {
+    loaderFrame.loadTree(tree, treeFile);
+  }
+
   /**
    * bind structures in a viewer to any matching sequences in an alignFrame (use
    * sequenceIds to limit scope of search to specific sequences)
index 07e1b25..4535b7e 100644 (file)
@@ -43,20 +43,20 @@ public class JalviewLiteTest
   @Test(groups = "Functional")
   public void testSeparatorListToArray()
   {
-    assertNull(JalviewLite.separatorListToArray(null, "|"));
-    assertNull(JalviewLite.separatorListToArray("", "|"));
-    assertNull(JalviewLite.separatorListToArray("|", "|"));
-    assertNull(JalviewLite.separatorListToArray("abc", "abc"));
+    assertNull(JalviewAppLoader.separatorListToArray(null, "|"));
+    assertNull(JalviewAppLoader.separatorListToArray("", "|"));
+    assertNull(JalviewAppLoader.separatorListToArray("|", "|"));
+    assertNull(JalviewAppLoader.separatorListToArray("abc", "abc"));
 
-    String[] array = JalviewLite.separatorListToArray("abc|def|ghi|", "|");
+    String[] array = JalviewAppLoader.separatorListToArray("abc|def|ghi|", "|");
     assertEquals(3, array.length);
     assertEquals("abc", array[0]);
     assertEquals("def", array[1]);
     assertEquals("ghi", array[2]);
 
     assertEquals("[abc]",
-            Arrays.toString(JalviewLite.separatorListToArray("abc|", "|")));
-    assertEquals("[abc]", Arrays.toString(JalviewLite.separatorListToArray(
+            Arrays.toString(JalviewAppLoader.separatorListToArray("abc|", "|")));
+    assertEquals("[abc]", Arrays.toString(JalviewAppLoader.separatorListToArray(
             "abcxy", "xy")));
 
     // these fail: