Merge branch 'develop' into patch/JAL-3088_finalbracenotinrightplace
[jalview.git] / src / jalview / ws / sifts / SiftsClient.java
index 9790f79..92cb7af 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.ws.sifts;
 
+import java.util.Locale;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -45,17 +47,17 @@ import java.util.TreeMap;
 import java.util.zip.GZIPInputStream;
 
 import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamReader;
 
-import MCview.Atom;
-import MCview.PDBChain;
 import jalview.analysis.AlignSeq;
 import jalview.analysis.scoremodels.ScoreMatrix;
 import jalview.analysis.scoremodels.ScoreModels;
 import jalview.api.DBRefEntryI;
 import jalview.api.SiftsClientI;
+import jalview.bin.Console;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.SequenceI;
@@ -66,6 +68,7 @@ import jalview.structure.StructureMapping;
 import jalview.util.Comparison;
 import jalview.util.DBRefUtils;
 import jalview.util.Format;
+import jalview.util.Platform;
 import jalview.xml.binding.sifts.Entry;
 import jalview.xml.binding.sifts.Entry.Entity;
 import jalview.xml.binding.sifts.Entry.Entity.Segment;
@@ -73,6 +76,8 @@ import jalview.xml.binding.sifts.Entry.Entity.Segment.ListMapRegion.MapRegion;
 import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue;
 import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.CrossRefDb;
 import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.ResidueDetail;
+import mc_view.Atom;
+import mc_view.PDBChain;
 
 public class SiftsClient implements SiftsClientI
 {
@@ -112,7 +117,7 @@ public class SiftsClient implements SiftsClientI
 
   private static final String NOT_OBSERVED = "Not_Observed";
 
-  private static final String SIFTS_FTP_BASE_URL = "http://ftp.ebi.ac.uk/pub/databases/msd/sifts/xml/";
+  private static final String SIFTS_SPLIT_FTP_BASE_URL = "https://ftp.ebi.ac.uk/pub/databases/msd/sifts/split_xml/";
 
   private final static String NEWLINE = System.lineSeparator();
 
@@ -184,12 +189,13 @@ public class SiftsClient implements SiftsClientI
     try (InputStream in = new FileInputStream(siftFile);
             GZIPInputStream gzis = new GZIPInputStream(in);)
     {
-      // System.out.println("File : " + siftFile.getAbsolutePath());
+      // jalview.bin.Console.outPrintln("File : " + siftFile.getAbsolutePath());
       JAXBContext jc = JAXBContext.newInstance("jalview.xml.binding.sifts");
       XMLStreamReader streamReader = XMLInputFactory.newInstance()
               .createXMLStreamReader(gzis);
       Unmarshaller um = jc.createUnmarshaller();
-      return (Entry) um.unmarshal(streamReader);
+      JAXBElement<Entry> jbe = um.unmarshal(streamReader, Entry.class);
+      return jbe.getValue();
     } catch (Exception e)
     {
       e.printStackTrace();
@@ -216,12 +222,12 @@ public class SiftsClient implements SiftsClientI
     }
 
     String siftsFileName = SiftsSettings.getSiftDownloadDirectory()
-            + pdbId.toLowerCase() + ".xml.gz";
+            + pdbId.toLowerCase(Locale.ROOT) + ".xml.gz";
     File siftsFile = new File(siftsFileName);
     if (siftsFile.exists())
     {
       // The line below is required for unit testing... don't comment it out!!!
-      System.out.println(">>> SIFTS File already downloaded for " + pdbId);
+      jalview.bin.Console.outPrintln(">>> SIFTS File already downloaded for " + pdbId);
 
       if (isFileOlderThanThreshold(siftsFile,
               SiftsSettings.getCacheThresholdInDays()))
@@ -230,7 +236,7 @@ public class SiftsClient implements SiftsClientI
         BackupFiles.moveFileToFile(siftsFile, oldSiftsFile);
         try
         {
-          siftsFile = downloadSiftsFile(pdbId.toLowerCase());
+          siftsFile = downloadSiftsFile(pdbId.toLowerCase(Locale.ROOT));
           oldSiftsFile.delete();
           return siftsFile;
         } catch (IOException e)
@@ -247,7 +253,7 @@ public class SiftsClient implements SiftsClientI
     }
     try
     {
-      siftsFile = downloadSiftsFile(pdbId.toLowerCase());
+      siftsFile = downloadSiftsFile(pdbId.toLowerCase(Locale.ROOT));
     } catch (IOException e)
     {
       throw new SiftsException(e.getMessage());
@@ -276,7 +282,7 @@ public class SiftsClient implements SiftsClientI
       diffInDays = (int) ((new Date().getTime()
               - attr.lastModifiedTime().toMillis())
               / (1000 * 60 * 60 * 24));
-      // System.out.println("Diff in days : " + diffInDays);
+      // jalview.bin.Console.outPrintln("Diff in days : " + diffInDays);
     } catch (IOException e)
     {
       e.printStackTrace();
@@ -300,22 +306,36 @@ public class SiftsClient implements SiftsClientI
       pdbId = pdbId.replace(".cif", "");
     }
     String siftFile = pdbId + ".xml.gz";
-    String siftsFileFTPURL = SIFTS_FTP_BASE_URL + siftFile;
-    String downloadedSiftsFile = SiftsSettings.getSiftDownloadDirectory()
-            + siftFile;
-    File siftsDownloadDir = new File(
-            SiftsSettings.getSiftDownloadDirectory());
-    if (!siftsDownloadDir.exists())
+    String siftsFileFTPURL = getDownloadUrlFor(siftFile);
+
+    /*
+     * Download the file from URL to either
+     * Java: directory of cached downloaded SIFTS files
+     * Javascript: temporary 'file' (in-memory cache)
+     */
+    File downloadTo = null;
+    if (Platform.isJS())
+    {
+      downloadTo = File.createTempFile(siftFile, ".xml.gz");
+    }
+    else
     {
-      siftsDownloadDir.mkdirs();
+      downloadTo = new File(
+              SiftsSettings.getSiftDownloadDirectory() + siftFile);
+      File siftsDownloadDir = new File(
+              SiftsSettings.getSiftDownloadDirectory());
+      if (!siftsDownloadDir.exists())
+      {
+        siftsDownloadDir.mkdirs();
+      }
     }
-    // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
+
+    // jalview.bin.Console.outPrintln(">> Download ftp url : " + siftsFileFTPURL);
     // long now = System.currentTimeMillis();
     URL url = new URL(siftsFileFTPURL);
     URLConnection conn = url.openConnection();
     InputStream inputStream = conn.getInputStream();
-    FileOutputStream outputStream = new FileOutputStream(
-            downloadedSiftsFile);
+    FileOutputStream outputStream = new FileOutputStream(downloadTo);
     byte[] buffer = new byte[BUFFER_SIZE];
     int bytesRead = -1;
     while ((bytesRead = inputStream.read(buffer)) != -1)
@@ -324,9 +344,17 @@ public class SiftsClient implements SiftsClientI
     }
     outputStream.close();
     inputStream.close();
-    // System.out.println(">>> File downloaded : " + downloadedSiftsFile
+    // jalview.bin.Console.outPrintln(">>> File downloaded : " + downloadedSiftsFile
     // + " took " + (System.currentTimeMillis() - now) + "ms");
-    return new File(downloadedSiftsFile);
+    return downloadTo;
+  }
+
+  public static String getDownloadUrlFor(String siftFile)
+  {
+    String durl = SIFTS_SPLIT_FTP_BASE_URL+siftFile.substring(1, 3)+"/"+siftFile;
+    Console.trace("SIFTS URL for "+siftFile+" is "+durl);
+    return durl;
+    
   }
 
   /**
@@ -339,7 +367,7 @@ public class SiftsClient implements SiftsClientI
   public static boolean deleteSiftsFileByPDBId(String pdbId)
   {
     File siftsFile = new File(SiftsSettings.getSiftDownloadDirectory()
-            + pdbId.toLowerCase() + ".xml.gz");
+            + pdbId.toLowerCase(Locale.ROOT) + ".xml.gz");
     if (siftsFile.exists())
     {
       return siftsFile.delete();
@@ -413,8 +441,8 @@ public class SiftsClient implements SiftsClientI
                 .getMapRegion();
         for (MapRegion mapRegion : mapRegions)
         {
-          accessions
-                  .add(mapRegion.getDb().getDbAccessionId().toLowerCase());
+          accessions.add(mapRegion.getDb().getDbAccessionId()
+                  .toLowerCase(Locale.ROOT));
         }
       }
     }
@@ -431,7 +459,7 @@ public class SiftsClient implements SiftsClientI
       seq = seq.getDatasetSequence();
     }
     structId = (chain == null) ? pdbId : pdbId + "|" + chain;
-    System.out.println("Getting SIFTS mapping for " + structId + ": seq "
+    jalview.bin.Console.outPrintln("Getting SIFTS mapping for " + structId + ": seq "
             + seq.getName());
 
     final StringBuilder mappingDetails = new StringBuilder(128);
@@ -464,7 +492,7 @@ public class SiftsClient implements SiftsClientI
   {
     List<Integer> omitNonObserved = new ArrayList<>();
     int nonObservedShiftIndex = 0, pdbeNonObserved = 0;
-    // System.out.println("Generating mappings for : " + entityId);
+    // jalview.bin.Console.outPrintln("Generating mappings for : " + entityId);
     Entity entity = null;
     entity = getEntityById(entityId);
     String originalSeq = AlignSeq.extractGaps(
@@ -484,9 +512,11 @@ public class SiftsClient implements SiftsClientI
     HashSet<String> dbRefAccessionIdsString = new HashSet<String>();
     for (DBRefEntry dbref : seq.getDBRefs())
     {
-      dbRefAccessionIdsString.add(dbref.getAccessionId().toLowerCase());
+      dbRefAccessionIdsString
+              .add(dbref.getAccessionId().toLowerCase(Locale.ROOT));
     }
-    dbRefAccessionIdsString.add(sourceDBRef.getAccessionId().toLowerCase());
+    dbRefAccessionIdsString
+            .add(sourceDBRef.getAccessionId().toLowerCase(Locale.ROOT));
 
     curDBRefAccessionIdsString = dbRefAccessionIdsString;
     curSourceDBRef = sourceDBRef.getAccessionId();
@@ -514,7 +544,7 @@ public class SiftsClient implements SiftsClientI
 
     if (mapping.isEmpty())
     {
-      throw new SiftsException("SIFTS mapping failed");
+      throw new SiftsException("SIFTS mapping failed for "+entityId+" and "+seq.getName());
     }
     // also construct a mapping object between the seq-coord sys and the PDB
     // seq's coord sys
@@ -632,7 +662,7 @@ public class SiftsClient implements SiftsClientI
     int firstPDBResNum = UNASSIGNED;
     for (Segment segment : segments)
     {
-      // System.out.println("Mapping segments : " + segment.getSegId() + "\\"s
+      // jalview.bin.Console.outPrintln("Mapping segments : " + segment.getSegId() + "\\"s
       // + segStartEnd);
       List<Residue> residues = segment.getListResidue().getResidue();
       for (Residue residue : residues)
@@ -874,14 +904,15 @@ public class SiftsClient implements SiftsClientI
   {
     boolean isStrictMatch = true;
     return isStrictMatch ? curSourceDBRef.equalsIgnoreCase(accession)
-            : curDBRefAccessionIdsString.contains(accession.toLowerCase());
+            : curDBRefAccessionIdsString
+                    .contains(accession.toLowerCase(Locale.ROOT));
   }
 
   private boolean isFoundInSiftsEntry(String accessionId)
   {
     Set<String> siftsDBRefs = getAllMappingAccession();
     return accessionId != null
-            && siftsDBRefs.contains(accessionId.toLowerCase());
+            && siftsDBRefs.contains(accessionId.toLowerCase(Locale.ROOT));
   }
 
   /**
@@ -900,8 +931,8 @@ public class SiftsClient implements SiftsClientI
     // Arrays.sort(keys);
     int firstIndex = keys[0];
     int lastIndex = keys[keys.length - 1];
-    // System.out.println("Min value " + firstIndex);
-    // System.out.println("Max value " + lastIndex);
+    // jalview.bin.Console.outPrintln("Min value " + firstIndex);
+    // jalview.bin.Console.outPrintln("Max value " + lastIndex);
     for (int x = firstIndex; x <= lastIndex; x++)
     {
       if (!resNumMap.containsKey(x) && !omitNonObserved.contains(x))
@@ -934,7 +965,7 @@ public class SiftsClient implements SiftsClientI
    */
   public Entity getEntityByMostOptimalMatchedId(String chainId)
   {
-    // System.out.println("---> advanced greedy entityId matching block
+    // jalview.bin.Console.outPrintln("---> advanced greedy entityId matching block
     // entered..");
     List<Entity> entities = siftsEntry.getEntity();
     SiftsEntitySortPojo[] sPojo = new SiftsEntitySortPojo[entities.size()];
@@ -970,8 +1001,8 @@ public class SiftsClient implements SiftsClientI
       ++count;
     }
     Arrays.sort(sPojo, Collections.reverseOrder());
-    // System.out.println("highest matched entity : " + sPojo[0].entityId);
-    // System.out.println("highest matched pid : " + sPojo[0].pid);
+    // jalview.bin.Console.outPrintln("highest matched entity : " + sPojo[0].entityId);
+    // jalview.bin.Console.outPrintln("highest matched pid : " + sPojo[0].pid);
 
     if (sPojo[0].entityId != null)
     {