JAL-1807 still testing
[jalviewjs.git] / unused / com / stevesoft / pat / Transformer.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 /**\r
15  * Replacement rule used by the Transformer.\r
16  * \r
17  * @see com.stevesoft.pat.Transformer\r
18  */\r
19 class TransRepRule extends ReplaceRule\r
20 {\r
21   Transformer t;\r
22 \r
23   TransRepRule(Transformer t)\r
24   {\r
25     this.t = t;\r
26   }\r
27 \r
28   public String toString1()\r
29   {\r
30     return "";\r
31   }\r
32 \r
33   public Object clone1()\r
34   {\r
35     return new TransRepRule(t);\r
36   }\r
37 \r
38   public void apply(StringBufferLike sb, RegRes rr)\r
39   {\r
40     // get the ReplaceRule of the Regex that matched.\r
41     next = t.tp.ra[t.tp.pn].getReplaceRule();\r
42   }\r
43 }\r
44 \r
45 /**\r
46  * Sometimes you want to replace a whole bunch of things that might occur within\r
47  * a single line of text. One efficient way to do this, both in terms of\r
48  * performance and programming ease, is with Transformer. The Transformer\r
49  * contains an array of Regex's and uses the Regex that matches earliest within\r
50  * the text to do the replacing, if two Regex's match at the same time it uses\r
51  * the one put in the Transformer first.\r
52  * <p>\r
53  * This feature can be used to prevent transformations from occurring in certain\r
54  * regions. For example, if I add the rule s'//.*'$&' and then add the rule\r
55  * s/hello/goodbye/ the Transformer will replace "hello" with "goodbye" except\r
56  * when it occurs inside a double-slash style of comment. The transformation on\r
57  * the comment goes first, does nothing, and precludes transformation on the\r
58  * same region of text as the s/hello/goodbye/ rule.\r
59  * <p>\r
60  * So far, at least, this class does not have the capability of turning into a\r
61  * giant robot :-)\r
62  */\r
63 public class Transformer\r
64 {\r
65   TransPat tp;\r
66 \r
67   Regex rp = new Regex();\r
68 \r
69   boolean auto_optimize;\r
70 \r
71   /**\r
72    * Get a replacer to that works with the current Regex.\r
73    * \r
74    * @see com.stevesoft.pat.Replacer\r
75    */\r
76   public Replacer getReplacer()\r
77   {\r
78     return rp.getReplacer();\r
79   }\r
80 \r
81   /** Instantiate a new Transformer object. */\r
82   public Transformer(boolean auto)\r
83   {\r
84     auto_optimize = auto;\r
85     tp = new TransPat();\r
86     rp.setReplaceRule(new TransRepRule(this));\r
87     rp.thePattern = tp;\r
88   }\r
89 \r
90   /** Add a new Regex to the set of Regex's. */\r
91   public void add(Regex r)\r
92   {\r
93     if (auto_optimize)\r
94     {\r
95       r.optimize();\r
96     }\r
97     tp.ra[tp.ra_len++] = r;\r
98     if (tp.ra.length == tp.ra_len)\r
99     {\r
100       Regex[] ra2 = new Regex[tp.ra_len + 10];\r
101       for (int i = 0; i < tp.ra_len; i++)\r
102       {\r
103         ra2[i] = tp.ra[i];\r
104       }\r
105       tp.ra = ra2;\r
106     }\r
107     rp.numSubs_ = r.numSubs_ > rp.numSubs_ ? r.numSubs_ : rp.numSubs_;\r
108   }\r
109 \r
110   /** Returns the number of Regex's in this Transformer. */\r
111   public int patterns()\r
112   {\r
113     return tp.ra_len;\r
114   }\r
115 \r
116   /** Get the Regex at position i in this Transformer. */\r
117   public Regex getRegexAt(int i)\r
118   {\r
119     if (i >= tp.ra_len)\r
120     {\r
121       throw new ArrayIndexOutOfBoundsException("i=" + i + ">=" + patterns());\r
122     }\r
123     if (i < 0)\r
124     {\r
125       throw new ArrayIndexOutOfBoundsException("i=" + i + "< 0");\r
126     }\r
127     return tp.ra[i];\r
128   }\r
129 \r
130   /** Set the Regex at position i in this Transformer. */\r
131   public void setRegexAt(Regex rx, int i)\r
132   {\r
133     if (i >= tp.ra_len)\r
134     {\r
135       throw new ArrayIndexOutOfBoundsException("i=" + i + ">=" + patterns());\r
136     }\r
137     if (i < 0)\r
138     {\r
139       throw new ArrayIndexOutOfBoundsException("i=" + i + "< 0");\r
140     }\r
141     tp.ra[i] = rx;\r
142   }\r
143 \r
144   /**\r
145    * Add a new Regex by calling Regex.perlCode\r
146    * \r
147    * @see com.stevesoft.pat.Regex#perlCode(java.lang.String)\r
148    */\r
149   public void add(String rs)\r
150   {\r
151     Regex r = Regex.perlCode(rs);\r
152     if (r == null)\r
153     {\r
154       throw new NullPointerException(MessageManager.formatMessage("exception.bad_pattern_to_regex_perl_code", new String[]{rs}));\r
155     }\r
156     add(r);\r
157   }\r
158 \r
159   /**\r
160    * Add an array of Strings (which will be converted to Regex's via the\r
161    * Regex.perlCode method.\r
162    * \r
163    * @see com.stevesoft.pat.Regex#perlCode(java.lang.String)\r
164    */\r
165   public void add(String[] array)\r
166   {\r
167     for (int i = 0; i < array.length; i++)\r
168     {\r
169       add(array[i]);\r
170     }\r
171   }\r
172 \r
173   /** Replace all matches in the current String. */\r
174   public String replaceAll(String s)\r
175   {\r
176     return dorep(s, 0, s.length());\r
177   }\r
178 \r
179   public StringLike replaceAll(StringLike s)\r
180   {\r
181     return dorep(s, 0, s.length());\r
182   }\r
183 \r
184   /** Replace all matching patterns beginning at position start. */\r
185   public String replaceAllFrom(String s, int start)\r
186   {\r
187     return dorep(s, start, s.length());\r
188   }\r
189 \r
190   /**\r
191    * Replace all matching patterns beginning between the positions start and end\r
192    * inclusive.\r
193    */\r
194   public String replaceAllRegion(String s, int start, int end)\r
195   {\r
196     return dorep(s, start, end);\r
197   }\r
198 \r
199   Replacer repr = new Replacer();\r
200 \r
201   final StringLike dorep(StringLike s, int start, int end)\r
202   {\r
203     StringLike tfmd = repr.replaceAllRegion(s, rp, start, end);\r
204     tp.lastMatchedTo = repr.lastMatchedTo;\r
205     return tfmd;\r
206   }\r
207 \r
208   final String dorep(String s, int start, int end)\r
209   {\r
210     return dorep(new StringWrap(s), start, end).toString();\r
211   }\r
212 \r
213   /** Replace the first matching pattern in String s. */\r
214   public String replaceFirst(String s)\r
215   {\r
216     return dorep(s, 0, s.length());\r
217   }\r
218 \r
219   /**\r
220    * Replace the first matching pattern after position start in String s.\r
221    */\r
222   public String replaceFirstFrom(String s, int start)\r
223   {\r
224     return dorep(s, start, s.length());\r
225   }\r
226 \r
227   /**\r
228    * Replace the first matching pattern that begins between start and end\r
229    * inclusive.\r
230    */\r
231   public String replaceFirstRegion(String s, int start, int end)\r
232   {\r
233     return dorep(s, start, end);\r
234   }\r
235 }\r