JAL-3626 Regex optimization from JAL-3253-applet; also minor
authorBobHanson <hansonr@stolaf.edu>
Mon, 1 Jun 2020 21:10:28 +0000 (16:10 -0500)
committerBobHanson <hansonr@stolaf.edu>
Mon, 1 Jun 2020 21:10:28 +0000 (16:10 -0500)
StockholmFile for loop opt.

16 files changed:
src/jalview/analysis/Finder.java
src/jalview/analysis/ParseProperties.java
src/jalview/ext/ensembl/EnsemblCdna.java
src/jalview/ext/ensembl/EnsemblGene.java
src/jalview/ext/ensembl/EnsemblProtein.java
src/jalview/ext/ensembl/EnsemblSequenceFetcher.java
src/jalview/io/ModellerDescription.java
src/jalview/io/NewickFile.java
src/jalview/io/RnamlFile.java
src/jalview/io/StockholmFile.java
src/jalview/util/DBRefUtils.java
src/jalview/util/Platform.java
src/jalview/ws/dbsources/EmblCdsSource.java
src/jalview/ws/dbsources/EmblSource.java
src/jalview/ws/dbsources/Pdb.java
src/jalview/ws/dbsources/Uniprot.java

index 3cbef6d..f21d7da 100644 (file)
@@ -31,6 +31,7 @@ import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.VisibleContigsIterator;
 import jalview.util.Comparison;
+import jalview.util.Platform;
 
 import java.util.List;
 import java.util.Vector;
@@ -129,7 +130,7 @@ public class Finder implements FinderI
   {
     String searchString = matchCase ? theSearchString
             : theSearchString.toUpperCase();
-    Regex searchPattern = new Regex(searchString);
+    Regex searchPattern = Platform.newRegex(searchString);
     searchPattern.setIgnoreCase(!matchCase);
 
     searchResults = new SearchResults();
index 4b68d93..bfd4d6a 100644 (file)
@@ -23,6 +23,7 @@ package jalview.analysis;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
+import jalview.util.Platform;
 
 import com.stevesoft.pat.Regex;
 
@@ -90,7 +91,7 @@ public class ParseProperties
           String[] ScoreDescriptions, String regex, boolean repeat)
   {
     int count = 0;
-    Regex pattern = new Regex(regex);
+    Regex pattern = Platform.newRegex(regex);
     if (pattern.numSubs() > ScoreNames.length)
     {
       // Check that we have enough labels and descriptions for any parsed
index e01ad17..ec7318f 100644 (file)
@@ -23,6 +23,7 @@ package jalview.ext.ensembl;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.io.gff.SequenceOntologyI;
+import jalview.util.Platform;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -44,7 +45,7 @@ public class EnsemblCdna extends EnsemblSeqProxy
    * or ENSMUST or similar for other species
    * or CCDSnnnnn.nn with at least 3 digits
    */
-  private static final Regex ACCESSION_REGEX = new Regex(
+  private static final Regex ACCESSION_REGEX = Platform.newRegex(
           "(ENS([A-Z]{3}|)[TG][0-9]{11}$)" + "|" + "(CCDS[0-9.]{3,}$)");
 
   /*
index 0e3d84b..157b8b9 100644 (file)
@@ -55,7 +55,7 @@ public class EnsemblGene extends EnsemblSeqProxy
    * accepts anything as we will attempt lookup of gene or 
    * transcript id or gene name
    */
-  private static final Regex ACCESSION_REGEX = new Regex(".*");
+  private static final Regex ACCESSION_REGEX = Platform.newRegex(".*");
 
   private static final EnsemblFeatureType[] FEATURES_TO_FETCH = {
       EnsemblFeatureType.gene, EnsemblFeatureType.transcript,
index 0280f16..468f05d 100644 (file)
@@ -23,6 +23,7 @@ package jalview.ext.ensembl;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.util.Platform;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -42,7 +43,7 @@ public class EnsemblProtein extends EnsemblSeqProxy
    * or ENSMUSP or similar for other species
    * or CCDSnnnnn.nn with at least 3 digits
    */
-  private static final Regex ACCESSION_REGEX = new Regex(
+  private static final Regex ACCESSION_REGEX = Platform.newRegex(
           "(ENS([A-Z]{3}|)P[0-9]{11}$)" + "|" + "(CCDS[0-9.]{3,}$)");
 
   /**
index 7454eb6..2008fb6 100644 (file)
@@ -23,6 +23,7 @@ package jalview.ext.ensembl;
 import jalview.analysis.AlignmentUtils;
 import jalview.bin.Cache;
 import jalview.datamodel.DBRefSource;
+import jalview.util.Platform;
 import jalview.ws.seqfetcher.DbSourceProxyImpl;
 
 import com.stevesoft.pat.Regex;
@@ -50,7 +51,7 @@ abstract class EnsemblSequenceFetcher extends DbSourceProxyImpl
    * or ENSMUSP or similar for other species
    * or CCDSnnnnn.nn with at least 3 digits
    */
-  private static final Regex ACCESSION_REGEX = new Regex(
+  private static final Regex ACCESSION_REGEX = Platform.newRegex(
           "(ENS([A-Z]{3}|)[GTEP]{1}[0-9]{11}$)" + "|"
                   + "(CCDS[0-9.]{3,}$)");
 
index a56f2af..48a6903 100755 (executable)
@@ -22,6 +22,7 @@ package jalview.io;
 
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.SequenceI;
+import jalview.util.Platform;
 
 import java.util.List;
 
@@ -95,12 +96,20 @@ public class ModellerDescription
     }
   };
 
+  private static Regex VALIDATION_REGEX;
+
+  private static Regex getRegex()
+  {
+    return (VALIDATION_REGEX == null
+            ? VALIDATION_REGEX = Platform
+                    .newRegex("\\s*((([-0-9]+).?)|FIRST|LAST|@)", null)
+            : VALIDATION_REGEX);
+  }
+
   private resCode validResidueCode(String field)
   {
     Integer val = null;
-    Regex r = new Regex(
-            "\\s*((([-0-9]+).?)|FIRST|LAST|@)");
-
+    Regex r = getRegex();
     if (!r.search(field))
     {
       return null; // invalid
index f3eaa45..ea31e67 100755 (executable)
@@ -28,6 +28,7 @@ package jalview.io;
 
 import jalview.datamodel.SequenceNode;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -37,6 +38,8 @@ import java.util.StringTokenizer;
 
 import com.stevesoft.pat.Regex;
 
+// TODO This class does not conform to Java standards for field name capitalization.
+
 /**
  * Parse a new hanpshire style tree Caveats: NHX files are NOT supported and the
  * tree distances and topology are unreliable when they are parsed. TODO: on
@@ -76,7 +79,7 @@ import com.stevesoft.pat.Regex;
  */
 public class NewickFile extends FileParse
 {
-  SequenceNode root;
+  private SequenceNode root;
 
   private boolean HasBootstrap = false;
 
@@ -85,21 +88,90 @@ public class NewickFile extends FileParse
   private boolean RootHasDistance = false;
 
   // File IO Flags
-  boolean ReplaceUnderscores = false;
+  private boolean ReplaceUnderscores = false;
+
+  private boolean printRootInfo = true;
+
+  private static final int REGEX_PERL_NODE_REQUIRE_QUOTE = 0;
+
+  private static final int REGEX_PERL_NODE_ESCAPE_QUOTE = 1;
+
+  private static final int REGEX_PERL_NODE_UNQUOTED_WHITESPACE = 2;
+
+  private static final int REGEX_MAJOR_SYMS = 3;
+
+  private static final int REGEX_QNODE_NAME = 4;
+
+  private static final int REGEX_COMMENT = 5;
+
+  private static final int REGEX_UQNODE_NAME = 6;
 
-  boolean printRootInfo = true;
+  private static final int REGEX_NBOOTSTRAP = 7;
+
+  private static final int REGEX_NDIST = 8;
+
+  private static final int REGEX_NO_LINES = 9;
+
+  private static final int REGEX_PERL_EXPAND_QUOTES = 10;
+
+  private static final int REGEX_MAX = 11;
+
+  private static final Regex[] REGEX = new Regex[REGEX_MAX];
+
+  private static Regex getRegex(int id)
+  {
+    if (REGEX[id] == null)
+    {
+      String code = null;
+      String code2 = null;
+      String codePerl = null;
+      switch (id)
+      {
+      case REGEX_PERL_NODE_REQUIRE_QUOTE:
+        codePerl = "m/[\\[,:'()]/";
+        break;
+      case REGEX_PERL_NODE_ESCAPE_QUOTE:
+        codePerl = "s/'/''/";
+        break;
+      case REGEX_PERL_NODE_UNQUOTED_WHITESPACE:
+        codePerl = "s/\\/w/_/";
+        break;
+      case REGEX_PERL_EXPAND_QUOTES:
+        codePerl = "s/''/'/";
+        break;
+      case REGEX_MAJOR_SYMS:
+        code = "[(\\['),;]";
+        break;
+      case REGEX_QNODE_NAME:
+        code = "'([^']|'')+'";
+        break;
+      case REGEX_COMMENT:
+        code = "]";
+        break;
+      case REGEX_UQNODE_NAME:
+        code = "\\b([^' :;\\](),]+)";
+        break;
+      case REGEX_NBOOTSTRAP:
+        code = "\\s*([0-9+]+)\\s*:";
+        break;
+      case REGEX_NDIST:
+        code = ":([-0-9Ee.+]+)";
+        break;
+      case REGEX_NO_LINES:
+        code = "\n+";
+        code2 = "";
+        break;
+      default:
+        return null;
+      }
+      return codePerl == null ? Platform.newRegex(code, code2)
+              : Platform.newRegexPerl(codePerl);
+    }
+    return REGEX[id];
+  }
 
-  private Regex[] NodeSafeName = new Regex[] {
-      new Regex().perlCode("m/[\\[,:'()]/"), // test for
-      // requiring
-      // quotes
-      new Regex().perlCode("s/'/''/"), // escaping quote
-      // characters
-      new Regex().perlCode("s/\\/w/_/") // unqoted whitespace
-      // transformation
-  };
 
-  char QuoteChar = '\'';
+  private char quoteChar = '\'';
 
   /**
    * Creates a new NewickFile object.
@@ -257,6 +329,7 @@ public class NewickFile extends FileParse
    */
   public void parse() throws IOException
   {
+    Platform.ensureRegex();
     String nf;
 
     { // fill nf with complete tree file
@@ -294,8 +367,7 @@ public class NewickFile extends FileParse
     boolean ascending = false; // flag indicating that we are leaving the
     // current node
 
-    Regex majorsyms = new Regex(
-            "[(\\['),;]");
+    Regex majorsyms = getRegex(REGEX_MAJOR_SYMS); // "[(\\['),;]"
 
     int nextcp = 0;
     int ncp = cp;
@@ -354,8 +426,7 @@ public class NewickFile extends FileParse
       // Deal with quoted fields
       case '\'':
 
-        Regex qnodename = new Regex(
-                "'([^']|'')+'");
+        Regex qnodename = getRegex(REGEX_QNODE_NAME);// "'([^']|'')+'");
 
         if (qnodename.searchFrom(nf, fcp))
         {
@@ -363,8 +434,7 @@ public class NewickFile extends FileParse
           nodename = new String(
                   qnodename.stringMatched().substring(1, nl - 1));
           // unpack any escaped colons
-          Regex xpandquotes = Regex
-                  .perlCode("s/''/'/");
+          Regex xpandquotes = getRegex(REGEX_PERL_EXPAND_QUOTES);
           String widernodename = xpandquotes.replaceAll(nodename);
           nodename = widernodename;
           // jump to after end of quoted nodename
@@ -398,8 +468,7 @@ public class NewickFile extends FileParse
            * '"+nf.substring(cp,fcp)+"'"); }
            */
           // verify termination.
-          Regex comment = new Regex(
-                  "]");
+          Regex comment = getRegex(REGEX_COMMENT); // "]"
           if (comment.searchFrom(nf, fcp))
           {
             // Skip the comment field
@@ -430,12 +499,9 @@ public class NewickFile extends FileParse
                   + fstring.substring(cend + 1);
 
         }
-        Regex uqnodename = new Regex(
-                "\\b([^' :;\\](),]+)");
-        Regex nbootstrap = new Regex(
-                "\\s*([0-9+]+)\\s*:");
-        Regex ndist = new Regex(
-                ":([-0-9Ee.+]+)");
+        Regex uqnodename = getRegex(REGEX_UQNODE_NAME);// "\\b([^' :;\\](),]+)"
+        Regex nbootstrap = getRegex(REGEX_NBOOTSTRAP);// "\\s*([0-9+]+)\\s*:");
+        Regex ndist = getRegex(REGEX_NDIST);// ":([-0-9Ee.+]+)");
 
         if (!parsednodename && uqnodename.search(fstring)
                 && ((uqnodename.matchedFrom(1) == 0) || (fstring
@@ -790,7 +856,7 @@ public class NewickFile extends FileParse
    */
   char getQuoteChar()
   {
-    return QuoteChar;
+    return quoteChar;
   }
 
   /**
@@ -803,8 +869,8 @@ public class NewickFile extends FileParse
    */
   char setQuoteChar(char c)
   {
-    char old = QuoteChar;
-    QuoteChar = c;
+    char old = quoteChar;
+    quoteChar = c;
 
     return old;
   }
@@ -819,13 +885,15 @@ public class NewickFile extends FileParse
    */
   private String nodeName(String name)
   {
-    if (NodeSafeName[0].search(name))
+    if (getRegex(REGEX_PERL_NODE_REQUIRE_QUOTE).search(name))
     {
-      return QuoteChar + NodeSafeName[1].replaceAll(name) + QuoteChar;
+      return quoteChar
+              + getRegex(REGEX_PERL_NODE_ESCAPE_QUOTE).replaceAll(name)
+              + quoteChar;
     }
     else
     {
-      return NodeSafeName[2].replaceAll(name);
+      return getRegex(REGEX_PERL_NODE_UNQUOTED_WHITESPACE).replaceAll(name);
     }
   }
 
@@ -972,7 +1040,7 @@ public class NewickFile extends FileParse
       trf.parse();
       System.out.println("Original file :\n");
 
-      Regex nonl = new Regex("\n+", "");
+      Regex nonl = getRegex(REGEX_NO_LINES);// "\n+", "");
       System.out.println(nonl.replaceAll(newickfile.toString()) + "\n");
 
       System.out.println("Parsed file.\n");
index 4d3ddc1..9551992 100644 (file)
@@ -26,6 +26,7 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 
 import java.io.BufferedReader;
 import java.io.FileNotFoundException;
@@ -227,7 +228,7 @@ public class RnamlFile extends AlignFile
       dataName = dataName.substring(0, b - 1);
     }
     b = 0;
-    Regex m = new Regex("[\\/]?([-A-Za-z0-9]+)\\.?");
+    Regex m = Platform.newRegex("[\\/]?([-A-Za-z0-9]+)\\.?");
     String mm = dataName;
     while (m.searchFrom(dataName, b))
     {
index 8b26757..92f73f4 100644 (file)
  */
 package jalview.io;
 
+import jalview.analysis.Rna;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
+import jalview.util.Format;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
 import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
@@ -39,21 +54,6 @@ import com.stevesoft.pat.Regex;
 import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
 import fr.orsay.lri.varna.factories.RNAFactory;
 import fr.orsay.lri.varna.models.rna.RNA;
-import jalview.analysis.Rna;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.DBRefEntry;
-import jalview.datamodel.DBRefSource;
-import jalview.datamodel.Mapping;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceI;
-import jalview.schemes.ResidueProperties;
-import jalview.util.Comparison;
-import jalview.util.DBRefUtils;
-import jalview.util.Format;
-import jalview.util.MessageManager;
 
 // import org.apache.log4j.*;
 
@@ -77,20 +77,105 @@ public class StockholmFile extends AlignFile
 {
   private static final String ANNOTATION = "annotation";
 
-//  private static final Regex OPEN_PAREN = new Regex("(<|\\[)", "(");
-//
-//  private static final Regex CLOSE_PAREN = new Regex("(>|\\])", ")");
-
-  public static final Regex DETECT_BRACKETS = new Regex(
-          "(<|>|\\[|\\]|\\(|\\)|\\{|\\})");
+  // WUSS extended symbols. Avoid ambiguity with protein SS annotations by using
+  // NOT_RNASS first.
 
-  // WUSS extended symbols. Avoid ambiguity with protein SS annotations by using NOT_RNASS first.
   public static final String RNASS_BRACKETS = "<>[](){}AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
 
+  public static final int REGEX_STOCKHOLM = 0;
+
+  public static final int REGEX_BRACKETS = 1;
+
   // use the following regex to decide an annotations (whole) line is NOT an RNA
   // SS (it contains only E,H,e,h and other non-brace/non-alpha chars)
-  private static final Regex NOT_RNASS = new Regex(
-          "^[^<>[\\](){}A-DF-Za-df-z]*$");
+  public static final int REGEX_NOT_RNASS = 2;
+
+  private static final int REGEX_ANNOTATION = 3;
+
+  private static final int REGEX_PFAM = 4;
+
+  private static final int REGEX_RFAM = 5;
+
+  private static final int REGEX_ALIGN_END = 6;
+
+  private static final int REGEX_SPLIT_ID = 7;
+
+  private static final int REGEX_SUBTYPE = 8;
+
+  private static final int REGEX_ANNOTATION_LINE = 9;
+
+  private static final int REGEX_REMOVE_ID = 10;
+
+  private static final int REGEX_OPEN_PAREN = 11;
+
+  private static final int REGEX_CLOSE_PAREN = 12;
+
+  public static final int REGEX_MAX = 13;
+
+  private static Regex REGEX[] = new Regex[REGEX_MAX];
+
+  /**
+   * Centralize all actual Regex instantialization in Platform.
+   * 
+   * @param id
+   * @return
+   */
+  private static Regex getRegex(int id)
+  {
+    if (REGEX[id] == null)
+    {
+      String pat = null, pat2 = null;
+      switch (id)
+      {
+      case REGEX_STOCKHOLM:
+        pat = "# STOCKHOLM ([\\d\\.]+)";
+        break;
+      case REGEX_BRACKETS:
+        // for reference; not used
+        pat = "(<|>|\\[|\\]|\\(|\\)|\\{|\\})";
+        break;
+      case REGEX_NOT_RNASS:
+        pat = "^[^<>[\\](){}A-DF-Za-df-z]*$";
+        break;
+      case REGEX_ANNOTATION:
+        pat = "(\\w+)\\s*(.*)";
+        break;
+      case REGEX_PFAM:
+        pat = "PF[0-9]{5}(.*)";
+        break;
+      case REGEX_RFAM:
+        pat = "RF[0-9]{5}(.*)";
+        break;
+      case REGEX_ALIGN_END:
+        pat = "^\\s*\\/\\/";
+        break;
+      case REGEX_SPLIT_ID:
+        pat = "(\\S+)\\/(\\d+)\\-(\\d+)";
+        break;
+      case REGEX_SUBTYPE:
+        pat = "(\\S+)\\s+(\\S*)\\s+(.*)";
+        break;
+      case REGEX_ANNOTATION_LINE:
+        pat = "#=(G[FSRC]?)\\s+(.*)";
+        break;
+      case REGEX_REMOVE_ID:
+        pat = "(\\S+)\\s+(\\S+)";
+        break;
+      case REGEX_OPEN_PAREN:
+        pat = "(<|\\[)";
+        pat2 = "(";
+        break;
+      case REGEX_CLOSE_PAREN:
+        pat = "(>|\\])";
+        pat2 = ")";
+        break;
+      default:
+        return null;
+      }
+      REGEX[id] = Platform.newRegex(pat, pat2);
+    }
+    return REGEX[id];
+  }
 
   StringBuffer out; // output buffer
 
@@ -215,7 +300,7 @@ public class StockholmFile extends AlignFile
     // First, we have to check that this file has STOCKHOLM format, i.e. the
     // first line must match
 
-    r = new Regex("# STOCKHOLM ([\\d\\.]+)");
+    r = getRegex(REGEX_STOCKHOLM);
     if (!r.search(nextLine()))
     {
       throw new IOException(MessageManager
@@ -229,19 +314,22 @@ public class StockholmFile extends AlignFile
     }
 
     // We define some Regexes here that will be used regularily later
-    rend = new Regex("^\\s*\\/\\/"); // Find the end of an alignment
-    p = new Regex("(\\S+)\\/(\\d+)\\-(\\d+)"); // split sequence id in
+    rend = getRegex(REGEX_ALIGN_END);//"^\\s*\\/\\/"); // Find the end of an alignment
+    p = getRegex(REGEX_SPLIT_ID);//"(\\S+)\\/(\\d+)\\-(\\d+)"); // split sequence id in
     // id/from/to
-    s = new Regex("(\\S+)\\s+(\\S*)\\s+(.*)"); // Parses annotation subtype
-    r = new Regex("#=(G[FSRC]?)\\s+(.*)"); // Finds any annotation line
-    x = new Regex("(\\S+)\\s+(\\S+)"); // split id from sequence
+    s = getRegex(REGEX_SUBTYPE);// "(\\S+)\\s+(\\S*)\\s+(.*)"); // Parses
+                                // annotation subtype
+    r = getRegex(REGEX_ANNOTATION_LINE);// "#=(G[FSRC]?)\\s+(.*)"); // Finds any
+                                        // annotation line
+    x = getRegex(REGEX_REMOVE_ID);// "(\\S+)\\s+(\\S+)"); // split id from
+                                  // sequence
 
     // Convert all bracket types to parentheses (necessary for passing to VARNA)
-    Regex openparen = new Regex("(<|\\[)", "(");
-    Regex closeparen = new Regex("(>|\\])", ")");
+    Regex openparen = getRegex(REGEX_OPEN_PAREN);//"(<|\\[)", "(");
+    Regex closeparen = getRegex(REGEX_CLOSE_PAREN);//"(>|\\])", ")");
 
 //    // Detect if file is RNA by looking for bracket types
-//    Regex detectbrackets = new Regex("(<|>|\\[|\\]|\\(|\\))");
+    // Regex detectbrackets = getRegex("(<|>|\\[|\\]|\\(|\\))");
 
     rend.optimize();
     p.optimize();
@@ -263,8 +351,8 @@ public class StockholmFile extends AlignFile
         this.noSeqs = seqs.size();
 
         String dbsource = null;
-        Regex pf = new Regex("PF[0-9]{5}(.*)"); // Finds AC for Pfam
-        Regex rf = new Regex("RF[0-9]{5}(.*)"); // Finds AC for Rfam
+        Regex pf = getRegex(REGEX_PFAM); // Finds AC for Pfam
+        Regex rf = getRegex(REGEX_RFAM); // Finds AC for Rfam
         if (getAlignmentProperty("AC") != null)
         {
           String dbType = getAlignmentProperty("AC").toString();
@@ -333,14 +421,17 @@ public class StockholmFile extends AlignFile
 
           if (accAnnotations != null && accAnnotations.containsKey("AC"))
           {
-            String dbr = (String) accAnnotations.get("AC");
-            if (dbr != null)
+            if (dbsource != null)
             {
-              // we could get very clever here - but for now - just try to
-              // guess accession type from type of sequence, source of alignment plus
-              // structure
-              // of accession
-              guessDatabaseFor(seqO, dbr, dbsource);
+              String dbr = (String) accAnnotations.get("AC");
+              if (dbr != null)
+              {
+                // we could get very clever here - but for now - just try to
+                // guess accession type from source of alignment plus structure
+                // of accession
+                guessDatabaseFor(seqO, dbr, dbsource);
+
+              }
             }
             // else - do what ? add the data anyway and prompt the user to
             // specify what references these are ?
@@ -505,7 +596,7 @@ public class StockholmFile extends AlignFile
            */
           // Let's save the annotations, maybe we'll be able to do something
           // with them later...
-          Regex an = new Regex("(\\w+)\\s*(.*)");
+          Regex an = getRegex(REGEX_ANNOTATION);
           if (an.search(annContent))
           {
             if (an.stringMatched(1).equals("NH"))
@@ -525,9 +616,6 @@ public class StockholmFile extends AlignFile
               treeName = an.stringMatched(2);
               treeString = new StringBuffer();
             }
-            // TODO: JAL-3532 - this is where GF comments and database references are lost
-            // suggest overriding this method for Stockholm files to catch and properly
-            // process CC, DR etc into multivalued properties
             setAlignmentProperty(an.stringMatched(1), an.stringMatched(2));
           }
         }
@@ -756,12 +844,6 @@ public class StockholmFile extends AlignFile
         st = -1;
       }
     }
-    if (dbsource == null)
-    {
-      // make up an origin based on whether the sequence looks like it is nucleotide
-      // or protein
-      dbsource = (seqO.isProtein()) ? "PFAM" : "RFAM";
-    }
     if (dbsource.equals("PFAM"))
     {
       seqdb = "UNIPROT";
@@ -844,7 +926,8 @@ public class StockholmFile extends AlignFile
     if (type.equalsIgnoreCase("secondary structure"))
     {
       ss = true;
-      isrnass = !NOT_RNASS.search(annots); // sorry about the double negative
+      isrnass = !getRegex(REGEX_NOT_RNASS).search(annots); // sorry about the double
+                                                     // negative
                                            // here (it's easier for dealing with
                                            // other non-alpha-non-brace chars)
     }
@@ -937,11 +1020,6 @@ public class StockholmFile extends AlignFile
     return annot;
   }
 
-  private String dbref_to_ac_record(DBRefEntry ref)
-  {
-    return ref.getSource().toString() + " ; "
-            + ref.getAccessionId().toString();
-  }
   @Override
   public String print(SequenceI[] s, boolean jvSuffix)
   {
@@ -956,7 +1034,6 @@ public class StockholmFile extends AlignFile
     int slen = s.length;
     SequenceI seq;
     Hashtable<String, String> dataRef = null;
-    boolean isAA = s[in].isProtein();
     while ((in < slen) && ((seq = s[in]) != null))
     {
       String tmp = printId(seq, jvSuffix);
@@ -974,29 +1051,14 @@ public class StockholmFile extends AlignFile
         {
           dataRef = new Hashtable<>();
         }
-        List<DBRefEntry> primrefs = seq.getPrimaryDBRefs();
-        if (primrefs.size() >= 1)
+        for (int idb = 0; idb < ndb; idb++)
         {
-          dataRef.put(tmp, dbref_to_ac_record(primrefs.get(0)));
-        }
-        else
-        {
-          for (int idb = 0; idb < seq.getDBRefs().size(); idb++)
-          {
-            DBRefEntry dbref = seq.getDBRefs().get(idb);
-            dataRef.put(tmp, dbref_to_ac_record(dbref));
-            // if we put in a uniprot or EMBL record then we're done:
-            if (isAA && DBRefSource.UNIPROT
-                    .equals(DBRefUtils.getCanonicalName(dbref.getSource())))
-            {
-              break;
-            }
-            if (!isAA && DBRefSource.EMBL
-                    .equals(DBRefUtils.getCanonicalName(dbref.getSource())))
-            {
-              break;
-            }
-          }
+
+          DBRefEntry ref = seqrefs.get(idb);
+          String datAs1 = ref.getSource().toString()
+                  + " ; "
+                  + ref.getAccessionId().toString();
+          dataRef.put(tmp, datAs1);
         }
       }
       in++;
@@ -1029,8 +1091,7 @@ public class StockholmFile extends AlignFile
         String type = dataRef.remove(idd);
         out.append(new Format("%-" + (maxid - 2) + "s")
                 .form("#=GS " + idd.toString() + " "));
-        if (isAA && type.contains("UNIPROT")
-                || (!isAA && type.contains("EMBL")))
+        if (type.contains("PFAM") || type.contains("RFAM"))
         {
 
           out.append(" AC " + type.substring(type.indexOf(";") + 1));
index ae0243e..07e8a56 100755 (executable)
@@ -307,6 +307,15 @@ public class DBRefUtils
 
        };
 
+  private static Regex PARSE_REGEX;
+
+  private static Regex getParseRegex()
+  {
+    return (PARSE_REGEX == null ? PARSE_REGEX = Platform.newRegex(
+            "([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;\\s*([0-9]+)-([0-9]+)")
+            : PARSE_REGEX);
+  }
+
   /**
    * Parses a DBRefEntry and adds it to the sequence, also a PDBEntry if the
    * database is PDB.
@@ -334,8 +343,7 @@ public class DBRefUtils
          * Check for PFAM style stockhom PDB accession id citation e.g.
          * "1WRI A; 7-80;"
          */
-        Regex r = new com.stevesoft.pat.Regex(
-                "([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;\\s*([0-9]+)-([0-9]+)");
+        Regex r = getParseRegex();
         if (r.search(acn.trim()))
         {
           String pdbid = r.stringMatched(1);
index fea40c3..2fa807a 100644 (file)
@@ -692,6 +692,11 @@ public class Platform
 
   }
 
+  public static Regex newRegex(String regex)
+  {
+    return newRegex(regex, null);
+  }
+
   public static Regex newRegex(String searchString, String replaceString)
   {
     ensureRegex();
@@ -818,6 +823,4 @@ public class Platform
 
   }
 
-  
-
 }
index a73af61..796f6e9 100644 (file)
@@ -22,11 +22,13 @@ package jalview.ws.dbsources;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefSource;
+import jalview.util.Platform;
 
 import com.stevesoft.pat.Regex;
 
 public class EmblCdsSource extends EmblXmlSource
 {
+  private Regex ACCESSION_REGEX = null;
 
   public EmblCdsSource()
   {
@@ -42,9 +44,14 @@ public class EmblCdsSource extends EmblXmlSource
   @Override
   public Regex getAccessionValidator()
   {
-    return new Regex("^[A-Z]+[0-9]+");
+    if (ACCESSION_REGEX == null)
+    {
+      ACCESSION_REGEX = Platform.newRegex("^[A-Z]+[0-9]+");
+    }
+    return ACCESSION_REGEX;
   }
 
+
   @Override
   public String getDbSource()
   {
index 6bbe2e1..114f6df 100644 (file)
@@ -22,6 +22,7 @@ package jalview.ws.dbsources;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefSource;
+import jalview.util.Platform;
 
 import com.stevesoft.pat.Regex;
 
@@ -32,6 +33,8 @@ import com.stevesoft.pat.Regex;
 public class EmblSource extends EmblXmlSource
 {
 
+  private static Regex ACCESSION_REGEX;
+
   public EmblSource()
   {
     super();
@@ -57,7 +60,11 @@ public class EmblSource extends EmblXmlSource
   @Override
   public Regex getAccessionValidator()
   {
-    return new Regex("^[A-Z]+[0-9]+");
+    if (ACCESSION_REGEX == null)
+    {
+      ACCESSION_REGEX = Platform.newRegex("^[A-Z]+[0-9]+");
+    }
+    return ACCESSION_REGEX;
   }
 
   /*
index a658089..8951a6e 100644 (file)
@@ -36,6 +36,7 @@ import jalview.io.FormatAdapter;
 import jalview.io.PDBFeatureSettings;
 import jalview.structure.StructureImportSettings;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 import jalview.ws.ebi.EBIFetchClient;
 
 import java.io.File;
@@ -56,6 +57,8 @@ public class Pdb extends EbiFileRetrievedProxy
 
   private static final int PDB_ID_LENGTH = 4;
 
+  private static Regex ACCESSION_REGEX;
+
   public Pdb()
   {
     super();
@@ -80,7 +83,12 @@ public class Pdb extends EbiFileRetrievedProxy
   @Override
   public Regex getAccessionValidator()
   {
-    return new Regex("([1-9][0-9A-Za-z]{3}):?([ _A-Za-z0-9]?)");
+    if (ACCESSION_REGEX == null)
+    {
+      ACCESSION_REGEX = Platform
+              .newRegex("([1-9][0-9A-Za-z]{3}):?([ _A-Za-z0-9]?)");
+    }
+    return ACCESSION_REGEX;
   }
 
   /*
index 6f5f033..6fc913b 100644 (file)
@@ -29,7 +29,9 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.Preferences;
 import jalview.schemes.ResidueProperties;
+import jalview.util.Platform;
 import jalview.util.StringUtils;
 import jalview.ws.seqfetcher.DbSourceProxyImpl;
 import jalview.xml.binding.embl.ROOT;
@@ -71,6 +73,8 @@ public class Uniprot extends DbSourceProxyImpl
 
   private static final String BAR_DELIMITER = "|";
 
+  private static Regex ACCESSION_REGEX;
+
   /**
    * Constructor
    */
@@ -103,7 +107,12 @@ public class Uniprot extends DbSourceProxyImpl
   @Override
   public Regex getAccessionValidator()
   {
-    return new Regex("([A-Z]+[0-9]+[A-Z0-9]+|[A-Z0-9]+_[A-Z0-9]+)");
+    if (ACCESSION_REGEX == null)
+    {
+      ACCESSION_REGEX = Platform
+              .newRegex("([A-Z]+[0-9]+[A-Z0-9]+|[A-Z0-9]+_[A-Z0-9]+)");
+    }
+    return ACCESSION_REGEX;
   }
 
   /*