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