Merge commit 'alpha/update_2_12_for_2_11_2_series_merge^2' into HEAD
[jalview.git] / src / jalview / datamodel / PDBEntry.java
index c1dc77c..d0ab8bf 100755 (executable)
  */
 package jalview.datamodel;
 
-import jalview.util.CaseInsensitiveString;
-
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.Hashtable;
 
+import jalview.util.CaseInsensitiveString;
+
 public class PDBEntry
 {
 
@@ -38,6 +38,8 @@ public class PDBEntry
 
   private static final int PDB_ID_LENGTH = 4;
 
+  private static final String FAKED_ID = "faked_pdbid";
+
   private String file;
 
   private String type;
@@ -48,7 +50,7 @@ public class PDBEntry
   {
     // TODO is FILE needed; if not is this enum needed, or can we
     // use FileFormatI for PDB, MMCIF?
-    PDB("pdb", "pdb"), MMCIF("mmcif", "cif"), FILE("?", "?");
+    PDB("pdb", "pdb"), MMCIF("mmcif", "cif"), BCIF("bcif","bcif"),FILE("?", "?");
 
     /*
      * file extension for cached structure file; must be one that
@@ -152,6 +154,32 @@ public class PDBEntry
   {
   }
 
+  /**
+   * Entry point when file is not known and fileType may be string
+   * @param pdbId
+   * @param chain may be null
+   * @param fileType "pdb", "mmcif", or "bcif"; null defaults to mmcif
+   */
+  public PDBEntry(String pdbId, String chain, String fileType) {
+    this.id = pdbId.toLowerCase();
+    setChainCode(chain); // I note that PDB Chains ARE case-sensitive now
+    if (fileType == null)
+      fileType = "mmcif";
+    switch (fileType.toLowerCase()) {
+    case "pdb":
+      this.type = Type.PDB.toString();
+      break;
+    case "mmcif":
+      this.type = Type.MMCIF.toString();
+      break;
+    default:
+    case "bcif":
+      System.out.println("format " + fileType + " has not been implemented; using mmCIF");
+      this.type = Type.MMCIF.toString();
+      break;
+    }
+  }
+  
   public PDBEntry(String pdbId, String chain, PDBEntry.Type type,
           String filePath)
   {
@@ -253,6 +281,12 @@ public class PDBEntry
     return id;
   }
 
+  /**
+   * TODO 
+   * 
+   * @param key  "protocol" 
+   * @param value
+   */
   public void setProperty(String key, Object value)
   {
     if (this.properties == null)
@@ -384,21 +418,40 @@ public class PDBEntry
       return false; // shouldn't happen
     }
 
-    /*
-     * id has to match (ignoring case)
-     */
-    if (!getId().equalsIgnoreCase(newId))
-    {
-      return false;
-    }
+    boolean idMatches = getId().equalsIgnoreCase(newId);
 
     /*
      * Don't update if associated with different structure files
      */
     String newFile = newEntry.getFile();
-    if (newFile != null && getFile() != null && !newFile.equals(getFile()))
+    if (newFile != null && getFile() != null)
     {
-      return false;
+      if (!newFile.equals(getFile()))
+      {
+        return false;
+      }
+      else
+      {
+        // files match.
+        if (!idMatches)
+        {
+          // this shouldn't happen, but could do if the id from the
+          // file is not the same as the id from the authority that provided
+          // the file
+          if (!newEntry.fakedPDBId())
+          {
+            return false;
+          } // otherwise we can update
+        }
+      }
+    }
+    else
+    {
+      // one has data, one doesn't ..
+      if (!idMatches)
+      {
+        return false;
+      } // otherwise maybe can update
     }
 
     /*
@@ -453,6 +506,11 @@ public class PDBEntry
        */
       String key = newProps.nextElement();
       Object value = newEntry.getProperty(key);
+      if (FAKED_ID.equals(key))
+      {
+        // we never update the fake ID property
+        continue;
+      }
       if (!value.equals(getProperty(key)))
       {
         setProperty(key, value);
@@ -460,4 +518,111 @@ public class PDBEntry
     }
     return true;
   }
+  
+  /**
+   * set when Jalview has manufactured the ID using a local filename
+   * @return
+   */
+  public boolean fakedPDBId()
+  {
+    if (_hasProperty(FAKED_ID))
+    {
+      return true;
+    }
+    return false;
+  }
+  public void setFakedPDBId(boolean faked)
+  {
+    if (faked)
+    {
+      setProperty(FAKED_ID, Boolean.TRUE);
+    }
+    else 
+    {
+      if (properties!=null) {
+        properties.remove(FAKED_ID);
+      }
+    }
+  }
+
+  private boolean _hasProperty(final String key)
+  {
+    return (properties != null && properties.containsKey(key));
+  }
+
+  private static final String RETRIEVE_FROM = "RETRIEVE_FROM";
+
+  private static final String PROVIDER = "PROVIDER";
+
+  private static final String MODELPAGE = "PROVIDERPAGE";
+
+  /**
+   * Permanent URI for retrieving the original structure data
+   * 
+   * @param urlStr
+   */
+  public void setRetrievalUrl(String urlStr)
+  {
+    setProperty(RETRIEVE_FROM, urlStr);
+  }
+
+  public boolean hasRetrievalUrl()
+  {
+    return _hasProperty(RETRIEVE_FROM);
+  }
+
+  /**
+   * get the Permanent URI for retrieving the original structure data
+   */
+  public String getRetrievalUrl()
+  {
+    return (String) getProperty(RETRIEVE_FROM);
+  }
+
+  /**
+   * Data provider name - from 3D Beacons
+   * 
+   * @param provider
+   */
+  public void setProvider(String provider)
+  {
+    setProperty(PROVIDER, provider);
+  }
+
+  /**
+   * Get Data provider name - from 3D Beacons
+   * 
+   */
+  public String getProvider()
+  {
+    return (String) getProperty(PROVIDER);
+  }
+
+  /**
+   * Permanent URI for retrieving the original structure data
+   * 
+   * @param urlStr
+   */
+  public void setProviderPage(String urlStr)
+  {
+    setProperty(MODELPAGE, urlStr);
+  }
+
+  /**
+   * get the Permanent URI for retrieving the original structure data
+   */
+  public String getProviderPage()
+  {
+    return (String) getProperty(MODELPAGE);
+  }
+
+  public boolean hasProviderPage()
+  {
+    return _hasProperty(MODELPAGE);
+  }
+
+  public boolean hasProvider()
+  {
+    return _hasProperty(PROVIDER);
+  }
 }