8de80215c3d2ea038dcc8b1874cfc8f41ab38c53
[jalviewjs.git] / unused / com / stevesoft / pat / Replacer.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 jalview.util.MessageManager;\r
11 \r
12 import com.stevesoft.pat.wrap.*;\r
13 \r
14 /** Internally used class. */\r
15 class RegHolder\r
16 {\r
17   Regex me = null;\r
18 \r
19   RegHolder prev = null;\r
20 }\r
21 \r
22 /**\r
23  * Internally used class.\r
24  * \r
25  * @see CodeRule\r
26  */\r
27 class CodeVal\r
28 {\r
29   int pos;\r
30 \r
31   char code;\r
32 \r
33   CodeVal(int p, char c)\r
34   {\r
35     pos = p;\r
36     code = c;\r
37   }\r
38 \r
39   public String toString()\r
40   {\r
41     return "(" + pos + "," + code + ")";\r
42   }\r
43 }\r
44 \r
45 /**\r
46  * To use this class, first use either the getReplacer() method from Transformer\r
47  * or Regex. You can then use replaceAll, replaceFirst, etc. methods on the\r
48  * Replacer in the same way that you can from either of those two classes.\r
49  * <p>\r
50  * The only potential difference between using the methods of Replacer to do the\r
51  * replacing is that Replacer remembers changes to the replacing object between\r
52  * calls to replaceAll, replaceFirst etc. For details, see the example file <a\r
53  * href="http://javaregex.com/code/trans3.java.html">trans3.java</a>.\r
54  * \r
55  * @see com.stevesoft.pat.Transformer\r
56  * @see com.stevesoft.pat.Regex\r
57  */\r
58 public class Replacer\r
59 {\r
60   boolean first;\r
61 \r
62   /** Instantiate a new Replacer. */\r
63   public Replacer()\r
64   {\r
65   }\r
66 \r
67   public StringLike replaceFirstRegion(String s, Regex r, int start, int end)\r
68   {\r
69     return replaceFirstRegion(new StringWrap(s), r, start, end);\r
70   }\r
71 \r
72   /**\r
73    * This method replaces the first occurence of the Regex in the String\r
74    * starting with position pos according to the Replacer rule of this object.\r
75    */\r
76   public StringLike replaceFirstRegion(StringLike s, Regex r, int start,\r
77           int end)\r
78   {\r
79     first = true;\r
80     rh.me = r;\r
81     rh.prev = null;\r
82     return dorep(s, start, end);\r
83   }\r
84 \r
85   public StringLike replaceFirst(StringLike s)\r
86   {\r
87     return replaceFirstRegion(s, 0, s.length());\r
88   }\r
89 \r
90   public StringLike replaceFirstFrom(StringLike s, int start)\r
91   {\r
92     return replaceFirstRegion(s, start, s.length());\r
93   }\r
94 \r
95   public StringLike replaceFirstRegion(StringLike s, int start, int end)\r
96   {\r
97     first = true;\r
98     return dorep(s, start, end);\r
99   }\r
100 \r
101   RegHolder rh = new RegHolder();\r
102 \r
103   public StringLike replaceAllRegion(String s, Regex r, int start, int end)\r
104   {\r
105     return replaceAllRegion(new StringWrap(s), r, start, end);\r
106   }\r
107 \r
108   /**\r
109    * This method replaces all occurences of the Regex in the String starting\r
110    * with postition pos according to the Replacer rule of this object.\r
111    */\r
112   public StringLike replaceAllRegion(StringLike s, Regex r, int start,\r
113           int end)\r
114   {\r
115     first = false;\r
116     // reset\r
117     rh.me = r;\r
118     rh.prev = null;\r
119     return dorep(s, start, end);\r
120   }\r
121 \r
122   public StringLike replaceAll(StringLike s)\r
123   {\r
124     return replaceAllRegion(s, 0, s.length());\r
125   }\r
126 \r
127   public StringLike replaceAllFrom(StringLike s, int start)\r
128   {\r
129     return replaceAllRegion(s, start, s.length());\r
130   }\r
131 \r
132   public StringLike replaceAllRegion(StringLike s, int start, int end)\r
133   {\r
134     first = false;\r
135     return dorep(s, start, end);\r
136   }\r
137 \r
138   public String replaceAll(String s)\r
139   {\r
140     return replaceAllRegion(new StringWrap(s), 0, s.length()).toString();\r
141   }\r
142 \r
143   public String replaceAllFrom(String s, int start)\r
144   {\r
145     return replaceAllRegion(new StringWrap(s), start, s.length())\r
146             .toString();\r
147   }\r
148 \r
149   public String replaceAllRegion(String s, int start, int end)\r
150   {\r
151     first = false;\r
152     return dorep(new StringWrap(s), start, end).toString();\r
153   }\r
154 \r
155   final public boolean isSpecial(ReplaceRule x)\r
156   {\r
157     while (x != null)\r
158     {\r
159       if (x instanceof SpecialRule\r
160               || (x instanceof RuleHolder && ((RuleHolder) x).held instanceof SpecialRule))\r
161       {\r
162         return true;\r
163       }\r
164       x = x.next;\r
165     }\r
166     return false;\r
167   }\r
168 \r
169   final public void apply1(RegRes rr)\r
170   {\r
171     rr.charsMatched_++;\r
172     apply(rr, null);\r
173     rr.charsMatched_--;\r
174   }\r
175 \r
176   final StringLike dorep(StringLike s, int start, int end)\r
177   {\r
178     StringLike ret = s;\r
179     want_more_text = false;\r
180     lastMatchedTo = 0;\r
181     if (rh.me == null)\r
182     {\r
183       throw new NullPointerException(MessageManager.getString("exception.replace_null_regex_pointer"));\r
184     }\r
185     if (rh.me._search(s, start, end))\r
186     {\r
187       int rmn = rh.me.matchedTo();\r
188       if (rh.me.charsMatched() == 0 && !isSpecial(rh.me.getReplaceRule()))\r
189       {\r
190         apply1(rh.me);\r
191         rmn++;\r
192       }\r
193       apply(rh.me);\r
194       if (!first)\r
195       {\r
196         for (int i = rmn; !want_more_text && rh.me._search(s, i, end); i = rmn)\r
197         {\r
198           rmn = rh.me.matchedTo();\r
199           if (rh.me.charsMatched() == 0)\r
200           {\r
201             if (!isSpecial(rh.me.getReplaceRule()))\r
202             {\r
203               apply1(rh.me);\r
204             }\r
205             rmn++;\r
206           }\r
207           apply(rh.me);\r
208         }\r
209       }\r
210       ret = finish();\r
211       ret = ret == null ? s : ret;\r
212     }\r
213     return ret;\r
214   }\r
215 \r
216   StringBufferLike sb = null;\r
217 \r
218   StringLike src = null;\r
219 \r
220   int pos = 0;\r
221 \r
222   /**\r
223    * This method allows you to apply the results of several matches in a\r
224    * sequence to modify a String of text. Each call in the sequence must operate\r
225    * on the same piece of text and the matchedFrom() of each RegRes given to\r
226    * this method must be greater in value than the preceeding RegRes's\r
227    * matchedTo() value.\r
228    */\r
229   public void apply(RegRes r, ReplaceRule rp)\r
230   {\r
231     if (rp == null || (rp.next == null && rp instanceof AmpersandRule))\r
232     {\r
233       return;\r
234     }\r
235     if (r.didMatch())\r
236     {\r
237       if (src == null)\r
238       {\r
239         src = r.getStringLike();\r
240       }\r
241       if (sb == null)\r
242       {\r
243         sb = new StringBufferLike(src.newStringBufferLike());\r
244       }\r
245       int rmf = r.matchedFrom();\r
246       for (int ii = pos; ii < rmf; ii++)\r
247       {\r
248         sb.appendChar(src.charAt(ii));\r
249       }\r
250 \r
251       for (ReplaceRule x = rp; x != null; x = x.next)\r
252       {\r
253         x.apply(sb, r);\r
254         if (x instanceof SpecialRule)\r
255         {\r
256           if (x instanceof WantMoreTextReplaceRule && want_more_text_enable)\r
257           {\r
258             want_more_text = true;\r
259           }\r
260           else if (x instanceof PushRule)\r
261           {\r
262             RegHolder rh2 = new RegHolder();\r
263             rh2.me = ((PushRule) x).NewRule;\r
264             rh2.prev = rh;\r
265             rh = rh2;\r
266           }\r
267           else if (x instanceof PopRule)\r
268           {\r
269             if (rh.prev != null)\r
270             {\r
271               rh = rh.prev;\r
272             }\r
273           }\r
274           else if (x instanceof ChangeRule)\r
275           {\r
276             rh.me = ((ChangeRule) x).NewRule;\r
277           }\r
278         }\r
279       }\r
280       if (!want_more_text)\r
281       {\r
282         pos = r.matchedTo();\r
283       }\r
284     }\r
285   }\r
286 \r
287   boolean want_more_text = false, want_more_text_enable = false;\r
288 \r
289   public boolean WantMoreText()\r
290   {\r
291     return want_more_text;\r
292   }\r
293 \r
294   /**\r
295    * Another form of apply, it is the same as apply(r,r.getReplaceRule()).\r
296    */\r
297   public void apply(Regex r)\r
298   {\r
299     apply(r, r.getReplaceRule());\r
300   }\r
301 \r
302   /**\r
303    * This finishes the replacement, appending the right() part of the last\r
304    * RegRes given to substitute(RegRes). After this method is called, the\r
305    * Replace object is reset to perform another substitution. If no RegRes\r
306    * objects with a true didMatch are applied, this returns null.\r
307    */\r
308   public StringLike finish()\r
309   {\r
310     if (src == null)\r
311     {\r
312       return null;\r
313     }\r
314     // sb.append(src.substring(pos,src.length()));\r
315     int s_end = src.length();\r
316     for (int ii = pos; ii < s_end; ii++)\r
317     {\r
318       sb.appendChar(src.charAt(ii));\r
319     }\r
320     src = null;\r
321     lastMatchedTo = pos;\r
322     pos = 0;\r
323     StringLike retstr = sb.toStringLike();\r
324     sb = null;\r
325     return retstr;\r
326   }\r
327 \r
328   int lastMatchedTo = 0;\r
329 \r
330   public Object clone()\r
331   {\r
332     Replacer r = new Replacer();\r
333     r.first = first;\r
334     r.src = src;\r
335     r.sb = sb;\r
336     r.pos = pos;\r
337     r.lastMatchedTo = lastMatchedTo;\r
338     r.want_more_text = want_more_text;\r
339     r.want_more_text_enable = want_more_text_enable;\r
340     r.rh.me = rh.me;\r
341     r.rh.prev = rh.prev;\r
342     return r;\r
343   }\r
344 \r
345   public int lastMatchedTo()\r
346   {\r
347     return lastMatchedTo;\r
348   }\r
349 \r
350   public Regex getRegex()\r
351   {\r
352     return rh.me;\r
353   }\r
354 \r
355   public void setSource(StringLike sl)\r
356   {\r
357     src = sl;\r
358   }\r
359 \r
360   public void setBuffer(StringBufferLike sbl)\r
361   {\r
362     sb = sbl;\r
363   }\r
364 \r
365   public void setPos(int pos)\r
366   {\r
367     this.pos = pos;\r
368   }\r
369 }\r