Merge branch 'patch/r2_11_1_branch_JAL-3703_closing_files' into releases/Release_2_11...
authorJim Procter <j.procter@dundee.ac.uk>
Mon, 17 Jan 2022 12:39:58 +0000 (12:39 +0000)
committerJim Procter <j.procter@dundee.ac.uk>
Mon, 17 Jan 2022 12:39:58 +0000 (12:39 +0000)
RELEASE
help/help/html/releases.html
help/help/html/whatsNew.html
src/jalview/io/AlignFile.java
src/jalview/io/FastaFile.java
src/jalview/io/FeaturesFile.java
src/jalview/project/Jalview2XML.java
test/jalview/io/BackupFilesTest.java
test/jalview/io/WindowsFileLoadAndSaveTest.java [new file with mode: 0644]

diff --git a/RELEASE b/RELEASE
index 70525f7..2f6ffff 100644 (file)
--- a/RELEASE
+++ b/RELEASE
@@ -1,2 +1,2 @@
 jalview.release=releases/Release_2_11_1_Branch
-jalview.version=2.11.1.6
+jalview.version=2.11.1.7
index 7b74947..f1813ce 100755 (executable)
@@ -59,17 +59,22 @@ li:before {
       <tr>
         <td width="60" align="center" nowrap><strong><a
             id="Jalview.2.11.1">2.11.1</a><a id="Jalview.2.11.1.7">.7</a><br />
-            <em></em></strong>
+            <em>18/01/2022</em></strong>
         </td>
         <td>
         </td>
         <td align="left" valign="top"><em>Security</em>
           <ul>
-            <li>
-              <!-- JAL-3937 -->Enable AIA download of HTTPS intermediate certificates.
-            </li>
-          </ul>
-        </td>
+          <li>
+            <!-- JAL-3937 -->Enable AIA download of HTTPS intermediate
+            certificates.
+          </li>
+          <li>
+            <!-- JAL-3703, JAL-3935 -->Files open in Jalview cannot be
+            updated by Jalview or other applications (Windows, other non
+            Unix/BSD OSs)
+          </li>
+        </ul></td>
       </tr>
       <tr>
       <td width="60" align="center" nowrap><strong><a
index a909616..40b51d1 100755 (executable)
 </head>
 <body>
   <p>
-    <strong>Jalview 2.11.1.6</strong>
+    <strong>Jalview 2.11.1.7</strong>
   </p>
-  <p>Jalview 2.11.1.6 is a critical patch release that updates one
-    of the open source components, log4j, that Jalview relies on. The
-    update addresses the widely reported log4shell security
-    vunerability.</p>
+  <p>Jalview 2.11.1.7 is a patch release that addresses connectivity
+    issues for third party services over HTTPS, and problems experienced
+    by Windows users when saving files from Jalview.</p>
   <p>
     For the full release notes, see <a
-      href="releases.html#Jalview.2.11.1.6">the Jalview 2.11.1.6
+      href="releases.html#Jalview.2.11.1.7">the Jalview 2.11.1.7
       release notes</a>.
   </p>
 </body>
index 497f0a5..b30fe33 100755 (executable)
  */
 package jalview.io;
 
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.util.MessageManager;
-
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Enumeration;
@@ -34,6 +27,13 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.Vector;
 
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
+
 /**
  * DOCUMENT ME!
  * 
@@ -79,6 +79,8 @@ public abstract class AlignFile extends FileParse
 
   private boolean parseImmediately = true;
 
+  private boolean dataClosed = false;
+
   /**
    * @return if doParse() was called at construction time
    */
@@ -164,6 +166,12 @@ public abstract class AlignFile extends FileParse
   public AlignFile(boolean parseImmediately, FileParse source)
           throws IOException
   {
+    this(parseImmediately, source, true);
+  }
+
+  public AlignFile(boolean parseImmediately, FileParse source,
+          boolean closeData) throws IOException
+  {
     super(source);
     initData();
 
@@ -173,7 +181,7 @@ public abstract class AlignFile extends FileParse
 
     if (parseImmediately)
     {
-      doParse();
+      doParse(closeData);
     }
   }
 
@@ -184,6 +192,11 @@ public abstract class AlignFile extends FileParse
    */
   public void doParse() throws IOException
   {
+    doParse(true);
+  }
+
+  public void doParse(boolean closeData) throws IOException
+  {
     if (parseCalled)
     {
       throw new IOException(
@@ -192,6 +205,11 @@ public abstract class AlignFile extends FileParse
     }
     parseCalled = true;
     parse();
+    if (closeData && !dataClosed)
+    {
+      dataIn.close();
+      dataClosed = true;
+    }
   }
 
   /**
index 9acd7da..c698a31 100755 (executable)
  */
 package jalview.io;
 
+import java.io.IOException;
+
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 
-import java.io.IOException;
-
 /**
  * DOCUMENT ME!
  * 
@@ -69,7 +69,12 @@ public class FastaFile extends AlignFile
 
   public FastaFile(FileParse source) throws IOException
   {
-    super(source);
+    this(source, true);
+  }
+
+  public FastaFile(FileParse source, boolean closeData) throws IOException
+  {
+    super(true, source, closeData);
   }
 
   public FastaFile(SequenceI[] seqs)
index 7e62f6b..3f1cdd1 100755 (executable)
@@ -1393,7 +1393,9 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
     } catch (IOException q)
     {
     }
-    FastaFile parser = new FastaFile(this);
+    // Opening a FastaFile object with the remainder of this object's dataIn.
+    // Tell the constructor to NOT close the dataIn when finished.
+    FastaFile parser = new FastaFile(this, false);
     List<SequenceI> includedseqs = parser.getSeqs();
 
     SequenceIdMatcher smatcher = new SequenceIdMatcher(newseqs);
index 0e062ac..4f92736 100644 (file)
@@ -53,6 +53,7 @@ import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -2071,9 +2072,9 @@ public class Jalview2XML
     {
       final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
       final String pdbId = pdbentry.getId();
-      if (!pdbId.equals(entry.getId())
-              && !(entry.getId().length() > 4 && entry.getId().toLowerCase()
-                      .startsWith(pdbId.toLowerCase())))
+      if (!pdbId.equals(entry.getId()) && !(entry.getId().length() > 4
+              && entry.getId().toLowerCase(Locale.ROOT)
+                      .startsWith(pdbId.toLowerCase(Locale.ROOT))))
       {
         /*
          * not interested in a binding to a different PDB entry here
@@ -2898,6 +2899,7 @@ public class Jalview2XML
           entryCount++;
         }
       } while (jarentry != null);
+      jin.close();
       resolveFrefedSequences();
     } catch (IOException ex)
     {
index 1386bfe..d9f28c5 100644 (file)
@@ -278,7 +278,13 @@ public class BackupFilesTest
   @AfterClass(alwaysRun = true)
   private void cleanupTmpFiles()
   {
-    File newfile = new File(newFile);
+    cleanupTmpFiles(newFile, suffix, digits);
+  }
+
+  protected static void cleanupTmpFiles(String file, String mysuffix,
+          int mydigits)
+  {
+    File newfile = new File(file);
     if (newfile.exists())
     {
       newfile.delete();
diff --git a/test/jalview/io/WindowsFileLoadAndSaveTest.java b/test/jalview/io/WindowsFileLoadAndSaveTest.java
new file mode 100644 (file)
index 0000000..2dd27b4
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import jalview.datamodel.AlignmentI;
+import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+
+/**
+ * WindowsFileSaveTest simply opens an alignment file and then tries to save it.
+ * This failed in Windows from 2.11.0 to 2.11.1.6 due to a combination of the
+ * opening file handle being left open ad infinitum, causing the BackupFiles
+ * operation of moving the saved (temp) file onto the original filename to fail,
+ * but only in Windows. See: https://issues.jalview.org/browse/JAL-3628
+ * https://issues.jalview.org/browse/JAL-3703
+ * https://issues.jalview.org/browse/JAL-3935 These issues are really all fixed
+ * by JAL-3703 This test is to ensure it doesn't start again, but note that this
+ * test will only fail in Windows.
+ */
+public class WindowsFileLoadAndSaveTest
+{
+
+  private final static String fileName = "examples" + File.separator
+          + "uniref50.fa";
+
+  private final static String testFileName = fileName + "-TEST";
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  /**
+   * Test saving and re-reading in a specified format
+   * 
+   * @throws IOException
+   */
+  @Test(groups = { "Functional" })
+  public void loadAndSaveAlignment() throws IOException
+  {
+    File file = new File(fileName);
+    File testFile = new File(testFileName);
+    Files.copy(file.toPath(), testFile.toPath(),
+            StandardCopyOption.REPLACE_EXISTING);
+    FormatAdapter fa = new FormatAdapter();
+    AlignmentI a = fa.readFile(testFile, DataSourceType.FILE,
+            FileFormat.Fasta);
+
+    AlignFrame af = new AlignFrame(a, 500, 500);
+    af.saveAlignment(testFileName, FileFormat.Fasta);
+
+    Assert.assertTrue(af.isSaveAlignmentSuccessful());
+  }
+
+  @AfterClass(alwaysRun = true)
+  private void cleanupTmpFiles()
+  {
+    BackupFilesPresetEntry bfpe = BackupFilesPresetEntry
+            .getSavedBackupEntry();
+    BackupFilesTest.cleanupTmpFiles(testFileName, bfpe.suffix, bfpe.digits);
+  }
+
+}