JAL-2114 more helpful reporting of parse failures
[jalview.git] / src / jalview / util / DnaUtils.java
index 9ab4fda..9582e2e 100644 (file)
@@ -1,5 +1,6 @@
 package jalview.util;
 
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -9,13 +10,22 @@ public class DnaUtils
 
   /**
    * Parses an ENA/GenBank format location specifier and returns a list of
-   * [start, end] ranges. Returns null if not able to parse.
+   * [start, end] ranges. Throws an exception if not able to parse.
+   * <p>
+   * Currently we do not parse "order()" specifiers, or indeterminate ranges of
+   * the format "&lt;start..end" or "start..&gt;end" or "start.end" or
+   * "start^end"
    * 
    * @param location
    * @return
+   * @throws ParseException
+   *           if unable to parse the location (the exception message is the
+   *           location specifier being parsed); we use ParseException in
+   *           preference to the unchecked IllegalArgumentException
    * @see http://www.insdc.org/files/feature_table.html#3.4
    */
   public static List<int[]> parseLocation(String location)
+          throws ParseException
   {
     if (location.startsWith("join("))
     {
@@ -25,12 +35,9 @@ public class DnaUtils
     {
       return parseComplement(location);
     }
-    String errorMessage = "Unable to process location specifier: "
-            + location;
     if (location.startsWith("order("))
     {
-      System.err.println(errorMessage);
-      return null;
+      throw new ParseException(location, 0);
     }
 
     /*
@@ -49,8 +56,7 @@ public class DnaUtils
         /*
          * could be a location like <1..888 or 1..>888
          */
-        System.err.println(errorMessage);
-        return null;
+        throw new ParseException(location, 0);
       }
     }
     else
@@ -58,8 +64,7 @@ public class DnaUtils
       /*
        * could be a location like 102.110 or 123^124
        */
-      System.err.println(errorMessage);
-      return null;
+      throw new ParseException(location, 0);
     }
   }
 
@@ -68,26 +73,20 @@ public class DnaUtils
    * 
    * @param location
    * @return
+   * @throws ParseException
    */
-  static List<int[]> parseComplement(String location)
+  static List<int[]> parseComplement(String location) throws ParseException
   {
     /*
      * take what is inside complement()
      */
     if (!location.endsWith(")"))
     {
-      return null;
+      throw new ParseException(location, 0);
     }
     String toComplement = location.substring("complement(".length(),
             location.length() - 1);
     List<int[]> ranges = parseLocation(toComplement);
-    if (ranges == null)
-    {
-      /*
-       * something bad in there
-       */
-      return null;
-    }
 
     /*
      * reverse the order and direction of ranges
@@ -107,8 +106,9 @@ public class DnaUtils
    * 
    * @param location
    * @return
+   * @throws ParseException
    */
-  static List<int[]> parseJoin(String location)
+  static List<int[]> parseJoin(String location) throws ParseException
   {
     List<int[]> ranges = new ArrayList<int[]>();
 
@@ -117,7 +117,7 @@ public class DnaUtils
      */
     if (!location.endsWith(")"))
     {
-      return null;
+      throw new ParseException(location, 0);
     }
     String joinedLocs = location.substring("join(".length(),
             location.length() - 1);
@@ -125,17 +125,7 @@ public class DnaUtils
     for (String loc : locations)
     {
       List<int[]> range = parseLocation(loc);
-      if (range == null)
-      {
-        /*
-         * something bad in there
-         */
-        return null;
-      }
-      else
-      {
-        ranges.addAll(range);
-      }
+      ranges.addAll(range);
     }
     return ranges;
   }