// // 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 jalview.util.MessageManager; import com.stevesoft.pat.wrap.StringWrap; /** * Replacement rule used by the Transformer. * * @see com.stevesoft.pat.Transformer */ class TransRepRule extends ReplaceRule { Transformer t; TransRepRule(Transformer t) { this.t = t; } public String toString1() { return ""; } public Object clone1() { return new TransRepRule(t); } public void apply(StringBufferLike sb, RegRes rr) { // get the ReplaceRule of the Regex that matched. next = t.tp.ra[t.tp.pn].getReplaceRule(); } } /** * Sometimes you want to replace a whole bunch of things that might occur within * a single line of text. One efficient way to do this, both in terms of * performance and programming ease, is with Transformer. The Transformer * contains an array of Regex's and uses the Regex that matches earliest within * the text to do the replacing, if two Regex's match at the same time it uses * the one put in the Transformer first. *
* This feature can be used to prevent transformations from occurring in certain * regions. For example, if I add the rule s'//.*'$&' and then add the rule * s/hello/goodbye/ the Transformer will replace "hello" with "goodbye" except * when it occurs inside a double-slash style of comment. The transformation on * the comment goes first, does nothing, and precludes transformation on the * same region of text as the s/hello/goodbye/ rule. *
* So far, at least, this class does not have the capability of turning into a * giant robot :-) */ public class Transformer { TransPat tp; Regex rp = new Regex(); boolean auto_optimize; /** * Get a replacer to that works with the current Regex. * * @see com.stevesoft.pat.Replacer */ public Replacer getReplacer() { return rp.getReplacer(); } /** Instantiate a new Transformer object. */ public Transformer(boolean auto) { auto_optimize = auto; tp = new TransPat(); rp.setReplaceRule(new TransRepRule(this)); rp.thePattern = tp; } /** Add a new Regex to the set of Regex's. */ public void add(Regex r) { if (auto_optimize) { r.optimize(); } tp.ra[tp.ra_len++] = r; if (tp.ra.length == tp.ra_len) { Regex[] ra2 = new Regex[tp.ra_len + 10]; for (int i = 0; i < tp.ra_len; i++) { ra2[i] = tp.ra[i]; } tp.ra = ra2; } rp.numSubs_ = r.numSubs_ > rp.numSubs_ ? r.numSubs_ : rp.numSubs_; } /** Returns the number of Regex's in this Transformer. */ public int patterns() { return tp.ra_len; } /** Get the Regex at position i in this Transformer. */ public Regex getRegexAt(int i) { if (i >= tp.ra_len) { throw new ArrayIndexOutOfBoundsException("i=" + i + ">=" + patterns()); } if (i < 0) { throw new ArrayIndexOutOfBoundsException("i=" + i + "< 0"); } return tp.ra[i]; } /** Set the Regex at position i in this Transformer. */ public void setRegexAt(Regex rx, int i) { if (i >= tp.ra_len) { throw new ArrayIndexOutOfBoundsException("i=" + i + ">=" + patterns()); } if (i < 0) { throw new ArrayIndexOutOfBoundsException("i=" + i + "< 0"); } tp.ra[i] = rx; } /** * Add a new Regex by calling Regex.perlCode * * @see com.stevesoft.pat.Regex#perlCode(java.lang.String) */ public void add(String rs) { Regex r = Regex.perlCode(rs); if (r == null) { throw new NullPointerException(MessageManager.formatMessage( "exception.bad_pattern_to_regex_perl_code", new String[] { rs })); } add(r); } /** * Add an array of Strings (which will be converted to Regex's via the * Regex.perlCode method. * * @see com.stevesoft.pat.Regex#perlCode(java.lang.String) */ public void add(String[] array) { for (int i = 0; i < array.length; i++) { add(array[i]); } } /** Replace all matches in the current String. */ public String replaceAll(String s) { return dorep(s, 0, s.length()); } public StringLike replaceAll(StringLike s) { return dorep(s, 0, s.length()); } /** Replace all matching patterns beginning at position start. */ public String replaceAllFrom(String s, int start) { return dorep(s, start, s.length()); } /** * Replace all matching patterns beginning between the positions start and end * inclusive. */ public String replaceAllRegion(String s, int start, int end) { return dorep(s, start, end); } Replacer repr = new Replacer(); final StringLike dorep(StringLike s, int start, int end) { StringLike tfmd = repr.replaceAllRegion(s, rp, start, end); tp.lastMatchedTo = repr.lastMatchedTo; return tfmd; } final String dorep(String s, int start, int end) { return dorep(new StringWrap(s), start, end).toString(); } /** Replace the first matching pattern in String s. */ public String replaceFirst(String s) { return dorep(s, 0, s.length()); } /** * Replace the first matching pattern after position start in String s. */ public String replaceFirstFrom(String s, int start) { return dorep(s, start, s.length()); } /** * Replace the first matching pattern that begins between start and end * inclusive. */ public String replaceFirstRegion(String s, int start, int end) { return dorep(s, start, end); } }