JAL-1645 source formatting and organise imports
[jalview.git] / src / com / stevesoft / pat / ReplaceRule.java
index 002ffa1..74a7a25 100755 (executable)
-//\r
-// This software is now distributed according to\r
-// the Lesser Gnu Public License.  Please see\r
-// http://www.gnu.org/copyleft/lesser.txt for\r
-// the details.\r
-//    -- Happy Computing!\r
-//\r
-package com.stevesoft.pat;\r
-\r
-import java.util.*;\r
-\r
-/** ReplaceRule is a singly linked list of Objects which describe how\r
-    to replace the matched portion of a String.  The only member method\r
-    that you absolutely need to define to use this class is apply(StringBuffer,RegRes) --\r
-    although you may want define toString1() and clone1() (if you are\r
-    unhappy with the default methods) that are needed by\r
-    the clone() or toString() methods on this class.\r
-    During the replacement process, each ReplaceRule tells the replacer\r
-    what to add to StringBuffer and uses the contents of the Regular\r
-    expression result to get the information it needs to\r
-    do this.  Here is an <a href="http://javaregex.com/code/fancy.java.html">example</a>\r
-\r
-    @see com.stevesoft.pat.NullRule\r
-    @see com.stevesoft.pat.AmpersandRule\r
-    @see com.stevesoft.pat.BackRefRule\r
-    @see com.stevesoft.pat.LeftRule\r
-    @see com.stevesoft.pat.RightRule\r
-    @see com.stevesoft.pat.StringRule\r
-    */\r
-public abstract class ReplaceRule {\r
-    /** points to the next ReplaceRule in the linked list. */\r
-    protected ReplaceRule next = null;\r
-    /** This function appends to the StringBufferLike the text you want\r
-        to replaced the portion of the String last matched. */\r
-    public abstract void apply(StringBufferLike sb,RegRes r);\r
-\r
-    /** A rule describing how to clone only the current ReplaceRule,\r
-        and none of the others in this linked list.  It is called by\r
-        clone() for each item in the list. */\r
-    public Object clone1() {\r
-        return new RuleHolder(this);\r
-    }\r
-    public final Object clone() {\r
-        ReplaceRule x = (ReplaceRule)clone1();\r
-        ReplaceRule xsav = x;\r
-        ReplaceRule y = this;\r
-        while(y.next != null) {\r
-            x.next = (ReplaceRule)y.next.clone1();\r
-            x.name = y.name;\r
-            x = x.next;\r
-            y = y.next;\r
-        }\r
-        return xsav;\r
-    }\r
-    static ReplaceRule add(ReplaceRule head,ReplaceRule adding) {\r
-        if(head == null)\r
-            return head = adding;\r
-        head.addRule(adding);\r
-        return head;\r
-    }\r
-    public ReplaceRule add(ReplaceRule adding) {\r
-        return add(this,adding);\r
-    }\r
-    /** Add another ReplaceRule to the linked list. */\r
-    public void addRule(ReplaceRule r) {\r
-        if(next == null) next = r;\r
-        else next.addRule(r);\r
-    }\r
-    static Regex getvar = null;\r
-    final static Regex getv() {\r
-        // Thanks to Michael Jimenez for pointing out the need\r
-        // to clone getvar rather than simply returning it.\r
-        // Previously this was not thread safe.\r
-        //if(getvar != null) return getvar;\r
-        if(getvar != null) return (Regex)getvar.clone();\r
-        getvar=\r
-            new Regex(\r
-           "(?:\\\\(\\d+)|"+ // ref 1\r
-           "\\$(?:"+\r
-             "(\\d+)|"+ // ref 2\r
-             "(\\w+)|"+ // ref 3\r
-              "([&'`])|"+ // ref 4\r
-             "\\{(?:(\\d+)|"+ // ref 5\r
-               "([^\n}\\\\]+))}"+ // ref 6\r
-             ")|"+ \r
-           "\\\\([nrbtaef])|"+ // ref 7\r
-           "\\\\c([\u0000-\uFFFF])|"+ // ref 8\r
-           "\\\\x([A-Fa-f0-9]{2})|"+ // ref 9\r
-           "\\\\([\u0000-\uFFFF])"+ // ref 10\r
-           ")");\r
-        getvar.optimize();\r
-        return getvar;\r
-    }\r
-    /** Compile a ReplaceRule using the text that would go between\r
-        the second and third /'s in a typical substitution pattern\r
-        in Perl: s/ ... / <i>The argument to ReplaceRule.perlCode</i> /.\r
-        */\r
-    public static ReplaceRule perlCode(String s) {\r
-        //String sav_backGs = Regex.backGs;\r
-        //int sav_backGto = Regex.backGto;\r
-        try {\r
-            int mf = 0, mt = 0;\r
-            Regex gv = getv();\r
-            ReplaceRule head = null;\r
-            Object tmp = null;\r
-            while(gv.searchFrom(s,mt)) {\r
-                int off=Regex.BackRefOffset-1;\r
-                mf = gv.matchedFrom();\r
-                if(mf > mt)\r
-                    head=add(head,\r
-                        new StringRule(s.substring(mt,mf)));\r
-                String var = null;\r
-                if((var=gv.stringMatched(1+off)) != null\r
-                        || (var=gv.stringMatched(2+off)) != null\r
-                        || (var=gv.stringMatched(5+off)) != null) {\r
-                    int d=0;\r
-                    for(int i=0;i<var.length();i++)\r
-                        d = 8*d+( var.charAt(i)-'0' );\r
-                   if(var.length() == 1)\r
-                      head=add(head,new BackRefRule(d));\r
-                   else\r
-                     head=new StringRule(""+(char)d);\r
-                } else if(\r
-                        (var=gv.stringMatched(10+off)) != null) {\r
-                    if("QELlUu".indexOf(var) >= 0)\r
-                        head=add(head,new CodeRule(var.charAt(0)) );\r
-                    else\r
-                        head=add(head,new StringRule(var) );\r
-                } else if(\r
-                        (var=gv.stringMatched(3+off)) != null\r
-                        || (var=gv.stringMatched(4+off)) != null\r
-                        || (var=gv.stringMatched(6+off)) != null) {\r
-                    String arg = "";\r
-                    int pc;\r
-                    if((pc=var.indexOf(':')) > 0) {\r
-                        arg = var.substring(pc+1);\r
-                        var = var.substring(0,pc);\r
-                    }\r
-                    if(var.equals("&")||var.equals("MATCH")) {\r
-                        head=add(head,new AmpersandRule());\r
-                    } else if(var.equals("`")||var.equals("PREMATCH")) {\r
-                        head=add(head,new LeftRule());\r
-                    } else if(var.equals("'")||var.equals("POSTMATCH")) {\r
-                        head=add(head,new RightRule());\r
-                    } else if(var.equals("WANT_MORE_TEXT")) {\r
-                        head=add(head,new WantMoreTextReplaceRule());\r
-                    } else if(var.equals("POP")) {\r
-                        head=add(head,new PopRule());\r
-                    } else if(var.startsWith("+") && (tmp=defs.get(var.substring(1))) != null) {\r
-                        if(tmp instanceof Regex)\r
-                            head=add(head,new PushRule(var.substring(1),(Regex)tmp));\r
-                        else if(tmp instanceof Transformer)\r
-                            head=add(head,new PushRule(var.substring(1),(Transformer)tmp));\r
-                        else head=add(head,new StringRule("${"+var+"}"));\r
-                    } else if(var.startsWith("=") && (tmp=defs.get(var.substring(1))) != null) {\r
-                        if(tmp instanceof Regex)\r
-                            head=add(head,new ChangeRule(var.substring(1),(Regex)tmp));\r
-                        else if(tmp instanceof Transformer)\r
-                            head=add(head,new ChangeRule(var.substring(1),(Transformer)tmp));\r
-                        else head=add(head,new StringRule("${"+var+"}"));\r
-                    } else if( (tmp=defs.get(var)) != null) {\r
-                        if(tmp instanceof ReplaceRule) {\r
-                            ReplaceRule alt = ((ReplaceRule)tmp).arg(arg);\r
-                            if(alt == null) alt = ((ReplaceRule)tmp);\r
-                            head=add(head,(ReplaceRule)(alt.clone()));\r
-                        }\r
-                    } else // can't figure out how to transform this thing...\r
-                        head=add(head,new StringRule("${"+var+"}"));\r
-                } else if(\r
-                 (var = gv.stringMatched(7+off)) != null) {\r
-                 char c = var.charAt(0);\r
-                 if(c == 'n')\r
-                   head=add(head,new StringRule("\n"));\r
-                 else if(c == 't')\r
-                   head=add(head,new StringRule("\t"));\r
-                 else if(c == 'r')\r
-                   head=add(head,new StringRule("\r"));\r
-                 else if(c == 'b')\r
-                   head=add(head,new StringRule("\r"));\r
-                 else if(c == 'a')\r
-                   head=add(head,new StringRule(""+(char)7));\r
-                 else if(c == 'e')\r
-                   head=add(head,new StringRule(""+(char)27));\r
-                 else if(c == 'f')\r
-                   head=add(head,new StringRule(""+(char)12));\r
-               } else if(\r
-                 (var = gv.stringMatched(8+off)) != null) {\r
-                 char c = var.charAt(0);\r
-                 if(c < Ctrl.cmap.length)\r
-                   c = Ctrl.cmap[c];\r
-                 head=add(head,new StringRule(""+c));\r
-               } else if(\r
-                 (var = gv.stringMatched(9+off)) != null) {\r
-                 int d =\r
-                   16*getHexDigit(var.charAt(0))+\r
-                   getHexDigit(var.charAt(1));\r
-                 head=add(head,new StringRule(""+(char)d));\r
-               }\r
-                mt = gv.matchedTo();\r
-            }\r
-            if(mt <= s.length())\r
-                head=add(head,new StringRule(s.substring(mt)));\r
-            return head;\r
-        } finally {\r
-            //Regex.backGs = sav_backGs;\r
-            //Regex.backGto = sav_backGto;\r
-        }\r
-    }\r
-    static Hashtable defs = new Hashtable();\r
-    public static boolean isDefined(String s) { return defs.get(s) != null; }\r
-    public static void define(String s,Regex r) { defs.put(s,r); }\r
-    public static void define(String s,ReplaceRule r) {\r
-        defs.put(s,r);\r
-        r.name = s;\r
-    }\r
-    String name = getClass().getName();\r
-    public static void define(String s,Transformer t) { defs.put(s,t); }\r
-    public static void undefine(String s) { defs.remove(s); }\r
-    /** This tells how to convert just the current element (and none\r
-        of the other items in the linked list) to a String. This\r
-        method is called by toString() for each item in the linked\r
-        list. */\r
-    public String toString1() {\r
-        return "${"+name+"}";\r
-    }\r
-    /** Convert to a String. */\r
-    public final String toString() {\r
-        StringBuffer sb = new StringBuffer();\r
-        sb.append(toString1());\r
-        ReplaceRule rr = this.next;\r
-        while(rr != null) {\r
-            sb.append(rr.toString1());\r
-            rr = rr.next;\r
-        }\r
-        return sb.toString();\r
-    }\r
-    /** Modified the behavior of a ReplaceRule by supplying\r
-        an argument.  If a ReplaceRule named "foo" is defined\r
-        and the pattern "s/x/${foo:5}/" is given to Regex.perlCode,\r
-        then the "foo" the definition of "foo" will be retrieved\r
-        and arg("5") will be called.  If the result is non-null,\r
-        that is the ReplaceRule that will be used.  If the result\r
-        is null, then the pattern works just as if it were\r
-        "s/x/${foo}/".\r
-        @see com.stevesoft.pat.Validator#arg(java.lang.String)\r
-        */\r
-    public ReplaceRule arg(String s) { return null; }\r
-    static int getHexDigit(char c) {\r
-      if(c >= '0' && c <= '9')\r
-        return c - '0';\r
-      if(c >= 'a' && c <= 'f')\r
-        return c - 'a'+10;\r
-      return c - 'A'+10;\r
-    }\r
-}\r
+//
+// This software is now distributed according to
+// the Lesser Gnu Public License.  Please see
+// http://www.gnu.org/copyleft/lesser.txt for
+// the details.
+//    -- Happy Computing!
+//
+package com.stevesoft.pat;
+
+import java.util.Hashtable;
+
+/**
+ * ReplaceRule is a singly linked list of Objects which describe how to replace
+ * the matched portion of a String. The only member method that you absolutely
+ * need to define to use this class is apply(StringBuffer,RegRes) -- although
+ * you may want define toString1() and clone1() (if you are unhappy with the
+ * default methods) that are needed by the clone() or toString() methods on this
+ * class. During the replacement process, each ReplaceRule tells the replacer
+ * what to add to StringBuffer and uses the contents of the Regular expression
+ * result to get the information it needs to do this. Here is an <a
+ * href="http://javaregex.com/code/fancy.java.html">example</a>
+ * 
+ * @see com.stevesoft.pat.NullRule
+ * @see com.stevesoft.pat.AmpersandRule
+ * @see com.stevesoft.pat.BackRefRule
+ * @see com.stevesoft.pat.LeftRule
+ * @see com.stevesoft.pat.RightRule
+ * @see com.stevesoft.pat.StringRule
+ */
+public abstract class ReplaceRule
+{
+  /** points to the next ReplaceRule in the linked list. */
+  protected ReplaceRule next = null;
+
+  /**
+   * This function appends to the StringBufferLike the text you want to replaced
+   * the portion of the String last matched.
+   */
+  public abstract void apply(StringBufferLike sb, RegRes r);
+
+  /**
+   * A rule describing how to clone only the current ReplaceRule, and none of
+   * the others in this linked list. It is called by clone() for each item in
+   * the list.
+   */
+  public Object clone1()
+  {
+    return new RuleHolder(this);
+  }
+
+  public final Object clone()
+  {
+    ReplaceRule x = (ReplaceRule) clone1();
+    ReplaceRule xsav = x;
+    ReplaceRule y = this;
+    while (y.next != null)
+    {
+      x.next = (ReplaceRule) y.next.clone1();
+      x.name = y.name;
+      x = x.next;
+      y = y.next;
+    }
+    return xsav;
+  }
+
+  static ReplaceRule add(ReplaceRule head, ReplaceRule adding)
+  {
+    if (head == null)
+    {
+      return head = adding;
+    }
+    head.addRule(adding);
+    return head;
+  }
+
+  public ReplaceRule add(ReplaceRule adding)
+  {
+    return add(this, adding);
+  }
+
+  /** Add another ReplaceRule to the linked list. */
+  public void addRule(ReplaceRule r)
+  {
+    if (next == null)
+    {
+      next = r;
+    }
+    else
+    {
+      next.addRule(r);
+    }
+  }
+
+  static Regex getvar = null;
+
+  final static Regex getv()
+  {
+    // Thanks to Michael Jimenez for pointing out the need
+    // to clone getvar rather than simply returning it.
+    // Previously this was not thread safe.
+    // if(getvar != null) return getvar;
+    if (getvar != null)
+    {
+      return (Regex) getvar.clone();
+    }
+    getvar = new Regex("(?:\\\\(\\d+)|" + // ref 1
+            "\\$(?:" + "(\\d+)|" + // ref 2
+            "(\\w+)|" + // ref 3
+            "([&'`])|" + // ref 4
+            "\\{(?:(\\d+)|" + // ref 5
+            "([^\n}\\\\]+))}" + // ref 6
+            ")|" + "\\\\([nrbtaef])|" + // ref 7
+            "\\\\c([\u0000-\uFFFF])|" + // ref 8
+            "\\\\x([A-Fa-f0-9]{2})|" + // ref 9
+            "\\\\([\u0000-\uFFFF])" + // ref 10
+            ")");
+    getvar.optimize();
+    return getvar;
+  }
+
+  /**
+   * Compile a ReplaceRule using the text that would go between the second and
+   * third /'s in a typical substitution pattern in Perl: s/ ... / <i>The
+   * argument to ReplaceRule.perlCode</i> /.
+   */
+  public static ReplaceRule perlCode(String s)
+  {
+    // String sav_backGs = Regex.backGs;
+    // int sav_backGto = Regex.backGto;
+    try
+    {
+      int mf = 0, mt = 0;
+      Regex gv = getv();
+      ReplaceRule head = null;
+      Object tmp = null;
+      while (gv.searchFrom(s, mt))
+      {
+        int off = Regex.BackRefOffset - 1;
+        mf = gv.matchedFrom();
+        if (mf > mt)
+        {
+          head = add(head, new StringRule(s.substring(mt, mf)));
+        }
+        String var = null;
+        if ((var = gv.stringMatched(1 + off)) != null
+                || (var = gv.stringMatched(2 + off)) != null
+                || (var = gv.stringMatched(5 + off)) != null)
+        {
+          int d = 0;
+          for (int i = 0; i < var.length(); i++)
+          {
+            d = 8 * d + (var.charAt(i) - '0');
+          }
+          if (var.length() == 1)
+          {
+            head = add(head, new BackRefRule(d));
+          }
+          else
+          {
+            head = new StringRule("" + (char) d);
+          }
+        }
+        else if ((var = gv.stringMatched(10 + off)) != null)
+        {
+          if ("QELlUu".indexOf(var) >= 0)
+          {
+            head = add(head, new CodeRule(var.charAt(0)));
+          }
+          else
+          {
+            head = add(head, new StringRule(var));
+          }
+        }
+        else if ((var = gv.stringMatched(3 + off)) != null
+                || (var = gv.stringMatched(4 + off)) != null
+                || (var = gv.stringMatched(6 + off)) != null)
+        {
+          String arg = "";
+          int pc;
+          if ((pc = var.indexOf(':')) > 0)
+          {
+            arg = var.substring(pc + 1);
+            var = var.substring(0, pc);
+          }
+          if (var.equals("&") || var.equals("MATCH"))
+          {
+            head = add(head, new AmpersandRule());
+          }
+          else if (var.equals("`") || var.equals("PREMATCH"))
+          {
+            head = add(head, new LeftRule());
+          }
+          else if (var.equals("'") || var.equals("POSTMATCH"))
+          {
+            head = add(head, new RightRule());
+          }
+          else if (var.equals("WANT_MORE_TEXT"))
+          {
+            head = add(head, new WantMoreTextReplaceRule());
+          }
+          else if (var.equals("POP"))
+          {
+            head = add(head, new PopRule());
+          }
+          else if (var.startsWith("+")
+                  && (tmp = defs.get(var.substring(1))) != null)
+          {
+            if (tmp instanceof Regex)
+            {
+              head = add(head, new PushRule(var.substring(1), (Regex) tmp));
+            }
+            else if (tmp instanceof Transformer)
+            {
+              head = add(head, new PushRule(var.substring(1),
+                      (Transformer) tmp));
+            }
+            else
+            {
+              head = add(head, new StringRule("${" + var + "}"));
+            }
+          }
+          else if (var.startsWith("=")
+                  && (tmp = defs.get(var.substring(1))) != null)
+          {
+            if (tmp instanceof Regex)
+            {
+              head = add(head,
+                      new ChangeRule(var.substring(1), (Regex) tmp));
+            }
+            else if (tmp instanceof Transformer)
+            {
+              head = add(head, new ChangeRule(var.substring(1),
+                      (Transformer) tmp));
+            }
+            else
+            {
+              head = add(head, new StringRule("${" + var + "}"));
+            }
+          }
+          else if ((tmp = defs.get(var)) != null)
+          {
+            if (tmp instanceof ReplaceRule)
+            {
+              ReplaceRule alt = ((ReplaceRule) tmp).arg(arg);
+              if (alt == null)
+              {
+                alt = ((ReplaceRule) tmp);
+              }
+              head = add(head, (ReplaceRule) (alt.clone()));
+            }
+          }
+          else
+          // can't figure out how to transform this thing...
+          {
+            head = add(head, new StringRule("${" + var + "}"));
+          }
+        }
+        else if ((var = gv.stringMatched(7 + off)) != null)
+        {
+          char c = var.charAt(0);
+          if (c == 'n')
+          {
+            head = add(head, new StringRule("\n"));
+          }
+          else if (c == 't')
+          {
+            head = add(head, new StringRule("\t"));
+          }
+          else if (c == 'r')
+          {
+            head = add(head, new StringRule("\r"));
+          }
+          else if (c == 'b')
+          {
+            head = add(head, new StringRule("\r"));
+          }
+          else if (c == 'a')
+          {
+            head = add(head, new StringRule("" + (char) 7));
+          }
+          else if (c == 'e')
+          {
+            head = add(head, new StringRule("" + (char) 27));
+          }
+          else if (c == 'f')
+          {
+            head = add(head, new StringRule("" + (char) 12));
+          }
+        }
+        else if ((var = gv.stringMatched(8 + off)) != null)
+        {
+          char c = var.charAt(0);
+          if (c < Ctrl.cmap.length)
+          {
+            c = Ctrl.cmap[c];
+          }
+          head = add(head, new StringRule("" + c));
+        }
+        else if ((var = gv.stringMatched(9 + off)) != null)
+        {
+          int d = 16 * getHexDigit(var.charAt(0))
+                  + getHexDigit(var.charAt(1));
+          head = add(head, new StringRule("" + (char) d));
+        }
+        mt = gv.matchedTo();
+      }
+      if (mt <= s.length())
+      {
+        head = add(head, new StringRule(s.substring(mt)));
+      }
+      return head;
+    } finally
+    {
+      // Regex.backGs = sav_backGs;
+      // Regex.backGto = sav_backGto;
+    }
+  }
+
+  static Hashtable defs = new Hashtable();
+
+  public static boolean isDefined(String s)
+  {
+    return defs.get(s) != null;
+  }
+
+  public static void define(String s, Regex r)
+  {
+    defs.put(s, r);
+  }
+
+  public static void define(String s, ReplaceRule r)
+  {
+    defs.put(s, r);
+    r.name = s;
+  }
+
+  String name = getClass().getName();
+
+  public static void define(String s, Transformer t)
+  {
+    defs.put(s, t);
+  }
+
+  public static void undefine(String s)
+  {
+    defs.remove(s);
+  }
+
+  /**
+   * This tells how to convert just the current element (and none of the other
+   * items in the linked list) to a String. This method is called by toString()
+   * for each item in the linked list.
+   */
+  public String toString1()
+  {
+    return "${" + name + "}";
+  }
+
+  /** Convert to a String. */
+  public final String toString()
+  {
+    StringBuffer sb = new StringBuffer();
+    sb.append(toString1());
+    ReplaceRule rr = this.next;
+    while (rr != null)
+    {
+      sb.append(rr.toString1());
+      rr = rr.next;
+    }
+    return sb.toString();
+  }
+
+  /**
+   * Modified the behavior of a ReplaceRule by supplying an argument. If a
+   * ReplaceRule named "foo" is defined and the pattern "s/x/${foo:5}/" is given
+   * to Regex.perlCode, then the "foo" the definition of "foo" will be retrieved
+   * and arg("5") will be called. If the result is non-null, that is the
+   * ReplaceRule that will be used. If the result is null, then the pattern
+   * works just as if it were "s/x/${foo}/".
+   * 
+   * @see com.stevesoft.pat.Validator#arg(java.lang.String)
+   */
+  public ReplaceRule arg(String s)
+  {
+    return null;
+  }
+
+  static int getHexDigit(char c)
+  {
+    if (c >= '0' && c <= '9')
+    {
+      return c - '0';
+    }
+    if (c >= 'a' && c <= 'f')
+    {
+      return c - 'a' + 10;
+    }
+    return c - 'A' + 10;
+  }
+}