JAL-1807 still testing
[jalviewjs.git] / unused / com / stevesoft / pat / ReplaceRule.java
1 //\r
2 // This software is now distributed according to\r
3 // the Lesser Gnu Public License.  Please see\r
4 // http://www.gnu.org/copyleft/lesser.txt for\r
5 // the details.\r
6 //    -- Happy Computing!\r
7 //\r
8 package com.stevesoft.pat;\r
9 \r
10 import java.util.Hashtable;\r
11 \r
12 /**\r
13  * ReplaceRule is a singly linked list of Objects which describe how to replace\r
14  * the matched portion of a String. The only member method that you absolutely\r
15  * need to define to use this class is apply(StringBuffer,RegRes) -- although\r
16  * you may want define toString1() and clone1() (if you are unhappy with the\r
17  * default methods) that are needed by the clone() or toString() methods on this\r
18  * class. During the replacement process, each ReplaceRule tells the replacer\r
19  * what to add to javajs.util.SB and uses the contents of the Regular expression\r
20  * result to get the information it needs to do this. Here is an <a\r
21  * href="http://javaregex.com/code/fancy.java.html">example</a>\r
22  * \r
23  * @see com.stevesoft.pat.NullRule\r
24  * @see com.stevesoft.pat.AmpersandRule\r
25  * @see com.stevesoft.pat.BackRefRule\r
26  * @see com.stevesoft.pat.LeftRule\r
27  * @see com.stevesoft.pat.RightRule\r
28  * @see com.stevesoft.pat.StringRule\r
29  */\r
30 public abstract class ReplaceRule\r
31 {\r
32   /** points to the next ReplaceRule in the linked list. */\r
33   protected ReplaceRule next = null;\r
34 \r
35   /**\r
36    * This function appends to the StringBufferLike the text you want to replaced\r
37    * the portion of the String last matched.\r
38    */\r
39   public abstract void apply(StringBufferLike sb, RegRes r);\r
40 \r
41   /**\r
42    * A rule describing how to clone only the current ReplaceRule, and none of\r
43    * the others in this linked list. It is called by clone() for each item in\r
44    * the list.\r
45    */\r
46   public Object clone1()\r
47   {\r
48     return new RuleHolder(this);\r
49   }\r
50 \r
51   public final Object clone()\r
52   {\r
53     ReplaceRule x = (ReplaceRule) clone1();\r
54     ReplaceRule xsav = x;\r
55     ReplaceRule y = this;\r
56     while (y.next != null)\r
57     {\r
58       x.next = (ReplaceRule) y.next.clone1();\r
59       x.name = y.name;\r
60       x = x.next;\r
61       y = y.next;\r
62     }\r
63     return xsav;\r
64   }\r
65 \r
66   static ReplaceRule add(ReplaceRule head, ReplaceRule adding)\r
67   {\r
68     if (head == null)\r
69     {\r
70       return head = adding;\r
71     }\r
72     head.addRule(adding);\r
73     return head;\r
74   }\r
75 \r
76   public ReplaceRule add(ReplaceRule adding)\r
77   {\r
78     return add(this, adding);\r
79   }\r
80 \r
81   /** Add another ReplaceRule to the linked list. */\r
82   public void addRule(ReplaceRule r)\r
83   {\r
84     if (next == null)\r
85     {\r
86       next = r;\r
87     }\r
88     else\r
89     {\r
90       next.addRule(r);\r
91     }\r
92   }\r
93 \r
94   static Regex getvar = null;\r
95 \r
96   final static Regex getv()\r
97   {\r
98     // Thanks to Michael Jimenez for pointing out the need\r
99     // to clone getvar rather than simply returning it.\r
100     // Previously this was not thread safe.\r
101     // if(getvar != null) return getvar;\r
102     if (getvar != null)\r
103     {\r
104       return (Regex) getvar.clone();\r
105     }\r
106     getvar = new Regex("(?:\\\\(\\d+)|" + // ref 1\r
107             "\\$(?:" + "(\\d+)|" + // ref 2\r
108             "(\\w+)|" + // ref 3\r
109             "([&'`])|" + // ref 4\r
110             "\\{(?:(\\d+)|" + // ref 5\r
111             "([^\n}\\\\]+))}" + // ref 6\r
112             ")|" + "\\\\([nrbtaef])|" + // ref 7\r
113             "\\\\c([\u0000-\uFFFF])|" + // ref 8\r
114             "\\\\x([A-Fa-f0-9]{2})|" + // ref 9\r
115             "\\\\([\u0000-\uFFFF])" + // ref 10\r
116             ")");\r
117     getvar.optimize();\r
118     return getvar;\r
119   }\r
120 \r
121   static Hashtable defs = new Hashtable();\r
122 \r
123   public static boolean isDefined(String s)\r
124   {\r
125     return defs.get(s) != null;\r
126   }\r
127 \r
128   public static void define(String s, Regex r)\r
129   {\r
130     defs.put(s, r);\r
131   }\r
132 \r
133   public static void define(String s, ReplaceRule r)\r
134   {\r
135     defs.put(s, r);\r
136     r.name = s;\r
137   }\r
138 \r
139   String name = getClass().getName();\r
140 \r
141   public static void define(String s, Transformer t)\r
142   {\r
143     defs.put(s, t);\r
144   }\r
145 \r
146   public static void undefine(String s)\r
147   {\r
148     defs.remove(s);\r
149   }\r
150 \r
151   /**\r
152    * This tells how to convert just the current element (and none of the other\r
153    * items in the linked list) to a String. This method is called by toString()\r
154    * for each item in the linked list.\r
155    */\r
156   public String toString1()\r
157   {\r
158     return "${" + name + "}";\r
159   }\r
160 \r
161   /** Convert to a String. */\r
162   public final String toString()\r
163   {\r
164     javajs.util.SB sb = new javajs.util.SB();\r
165     sb.append(toString1());\r
166     ReplaceRule rr = this.next;\r
167     while (rr != null)\r
168     {\r
169       sb.append(rr.toString1());\r
170       rr = rr.next;\r
171     }\r
172     return sb.toString();\r
173   }\r
174 \r
175   /**\r
176    * Modified the behavior of a ReplaceRule by supplying an argument. If a\r
177    * ReplaceRule named "foo" is defined and the pattern "s/x/${foo:5}/" is given\r
178    * to Regex.perlCode, then the "foo" the definition of "foo" will be retrieved\r
179    * and arg("5") will be called. If the result is non-null, that is the\r
180    * ReplaceRule that will be used. If the result is null, then the pattern\r
181    * works just as if it were "s/x/${foo}/".\r
182    * \r
183    * @see com.stevesoft.pat.Validator#arg(java.lang.String)\r
184    */\r
185   public ReplaceRule arg(String s)\r
186   {\r
187     return null;\r
188   }\r
189 \r
190   static int getHexDigit(char c)\r
191   {\r
192     if (c >= '0' && c <= '9')\r
193     {\r
194       return c - '0';\r
195     }\r
196     if (c >= 'a' && c <= 'f')\r
197     {\r
198       return c - 'a' + 10;\r
199     }\r
200     return c - 'A' + 10;\r
201   }\r
202 }\r