Merge branch 'Jalview-JS/develop' into merge_js_develop
[jalview.git] / src / jalview / datamodel / features / FeatureAttributes.java
index bcf404b..a57fd55 100644 (file)
@@ -29,17 +29,29 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.TreeMap;
 
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
 /**
  * A singleton class to hold the set of attributes known for each feature type
  */
-public class FeatureAttributes
+public class FeatureAttributes implements ApplicationSingletonI
 {
   public enum Datatype
   {
     Character, Number, Mixed
   }
 
-  private static FeatureAttributes instance = new FeatureAttributes();
+  public static FeatureAttributes getInstance()
+  {
+    return (FeatureAttributes) ApplicationSingletonProvider
+            .getInstance(FeatureAttributes.class);
+  }
+
+  private FeatureAttributes()
+  {
+    attributes = new HashMap<>();
+  }
 
   /*
    * map, by feature type, of a map, by attribute name, of
@@ -120,12 +132,17 @@ public class FeatureAttributes
       if (value != null)
       {
         value = value.trim();
+        if (value.isEmpty())
+        {
+          return;
+        }
 
         /*
          * Parse numeric value unless we have previously
          * seen text data for this attribute type
          */
-        if (type == null || type == Datatype.Number)
+        if ((type == null && couldBeNumber(value))
+                || type == Datatype.Number)
         {
           try
           {
@@ -149,11 +166,23 @@ public class FeatureAttributes
             hasValue = false;
           }
         }
+        else
+        {
+          /*
+           * if not a number, and not seen before...
+           */
+          type = Datatype.Character;
+          min = 0f;
+          max = 0f;
+          hasValue = false;
+        }
       }
     }
 
     /**
-     * Answers the description of the attribute, if recorded and unique, or null if either no, or more than description is recorded
+     * Answers the description of the attribute, if recorded and unique, or null
+     * if either no, or more than description is recorded
+     * 
      * @return
      */
     public String getDescription()
@@ -193,21 +222,6 @@ public class FeatureAttributes
   }
 
   /**
-   * Answers the singleton instance of this class
-   * 
-   * @return
-   */
-  public static FeatureAttributes getInstance()
-  {
-    return instance;
-  }
-
-  private FeatureAttributes()
-  {
-    attributes = new HashMap<>();
-  }
-
-  /**
    * Answers the attribute names known for the given feature type, in
    * alphabetical order (not case sensitive), or an empty set if no attributes
    * are known. An attribute name is typically 'simple' e.g. "AC", but may be
@@ -227,6 +241,34 @@ public class FeatureAttributes
   }
 
   /**
+   * A partial check that the string is numeric - only checks the first
+   * character. Returns true if the first character is a digit, or if it is '.',
+   * '+' or '-' and not the only character. Otherwise returns false (including
+   * for an empty string). Note this is not a complete check as it returns true
+   * for (e.g.) "1A".
+   * 
+   * @param f
+   * @return
+   */
+  public static boolean couldBeNumber(String f)
+  {
+    int len = f.length();
+    if (len == 0)
+    {
+      return false;
+    }
+    char ch = f.charAt(0);
+    switch (ch)
+    {
+    case '.':
+    case '+':
+    case '-':
+      return len > 1;
+    }
+    return (ch <= '9' && ch >= '0');
+  }
+
+  /**
    * Answers true if at least one attribute is known for the given feature type,
    * else false
    * 
@@ -354,7 +396,7 @@ public class FeatureAttributes
     {
       return;
     }
-  
+
     Map<String[], AttributeData> atts = attributes.get(featureType);
     if (atts == null)
     {