Merge branch 'releases/Release_2_11_3_Branch'
[jalview.git] / src / jalview / util / DnaUtils.java
index 9ab4fda..654b03a 100644 (file)
@@ -1,5 +1,26 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.util;
 
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -9,14 +30,24 @@ 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
   {
+    location = location.trim(); // failsafe for untidy input data
     if (location.startsWith("join("))
     {
       return parseJoin(location);
@@ -25,12 +56,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 +77,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 +85,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 +94,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 +127,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 +138,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 +146,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;
   }