develop merge
[jalview.git] / src / jalview / io / gff / GffHelperFactory.java
diff --git a/src/jalview/io/gff/GffHelperFactory.java b/src/jalview/io/gff/GffHelperFactory.java
new file mode 100644 (file)
index 0000000..8bd5115
--- /dev/null
@@ -0,0 +1,70 @@
+package jalview.io.gff;
+
+
+/**
+ * A factory to serve instances of GFF helper classes
+ */
+public class GffHelperFactory
+{
+
+  /**
+   * Returns a class to process the GFF line based on inspecting its column
+   * data. This may return a general-purpose GFF2 or GFF3 helper, or a
+   * specialisation for a flavour of GFF generated by a particular tool.
+   * 
+   * @param gff
+   * @return
+   */
+  public static GffHelperI getHelper(String[] gff)
+  {
+    if (gff == null || gff.length < 6)
+    {
+      return null;
+    }
+
+    GffHelperI result = null;
+    if (ExonerateHelper.recognises(gff))
+    {
+      result = new ExonerateHelper();
+    }
+    else if (InterProScanHelper.recognises(gff))
+    {
+      result = new InterProScanHelper();
+    }
+    else if (looksLikeGff3(gff))
+    {
+      result = new Gff3Helper();
+    }
+    else
+    {
+      result = new Gff2Helper();
+    }
+
+    return result;
+  }
+
+  /**
+   * Heuristic rule: if column 9 seems to have Name=Value entries, assume this
+   * is GFF3. GFF3 uses '=' as name-value separator, GFF2 uses space ' '.
+   * 
+   * @param gff
+   * @return
+   */
+  protected static boolean looksLikeGff3(String[] gff)
+  {
+    if (gff.length >= 9)
+    {
+      String attributes = gff[8].trim();
+      int pos1 = attributes.indexOf(';');
+      int pos2 = attributes.indexOf('=');
+      if (pos2 != -1 && (pos1 == -1 || pos2 < pos1))
+      {
+        // there is an '=' before the first ';' (if any)
+        // not foolproof as theoretically GFF2 could be like "Name Value=123;"
+        return true;
+      }
+    }
+    return false;
+  }
+
+}