You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oro-dev@jakarta.apache.org by Laurens Pit <la...@moonshake.com> on 2001/06/07 18:07:43 UTC

MethodSubstitution

Hi All,

Below is a piece of code I created for several projects I do, and which I
like to contribute to ORO if it seems useful. It's a pretty simple yet
powerful class. Also, attached is a file called STA.java, which shows
example usage of MethodSubstitution (and the other types of substitutions).



Greets,
Laurens

-----------------------------------

import java.lang.reflect.*;
import org.apache.oro.text.regex.*;

/**
 * Implements the /e modifier of perl regular expressions that makes
 * Perl interpret the expression before processing it. This class is
 * intended for use with {@link Util#substitute Util.substitute}.
 * <p>
 * In perl you can do something like:
 * <pre><b>s/A(.*?)B(.*?)C/&MyMethod($1, $2)/ge</b></pre>
 * When the match is made this will call the sub "MyMethod", pass it
 * the two matched variables, and finally the match is substituted
 * by whatever the sub returns.
 * <p>
 * MethodSubstitution works in a similar way. You can do something like:
 * <pre><b>
 * MethodSubstitution sub = new MethodSubstitution(this, "myMethod");
 * substitute("A(.*?)B(.*?)C", sub);
 * </b></pre>
 * See also {@link Util#substitute Util.substitute}).
 * Here the object "this" must have a public method "myMethod". The
 * signature of the method must be:
 * <pre><b>public String myMethod(MatchResult match)</b></pre>
 * So when the match "A(.*?)B(.*?)C" is made the method will
 * be called where the parenthesized subgroups of the match will
 * be available through the MatchResult parameter. The match will
 * be replaced by the String that the method returns.
 * <p>
 * You can also construct a MethodSubstitution like this:
 * <pre><b>
 * MethodSubstitution sub =
 *              new MethodSubstitution(MyClass.class, "myMethod");
 * </b></pre>
 * In this case there must be a public static method "myMethod" present
 * in the class "MyClass". For example:
 * <pre><b>public static String myMethod(MatchResult match)</b></pre>
 * <p>
 * @author <a href="mailto:laurens@moonshake.com">Laurens Pit</a>
 * @version @version@
 * @see Util
 * @see Util#substitute
 * @see Substitution
 * @see StringSubstitution
 * @see Perl5Substitution
 */
public class MethodSubstitution implements Substitution
{
    /* parameters signature of methods */
    private static final Class[] paramTypes = new Class[]
{MatchResult.class};

    private Object obj;
    private Method method;

    /**
     * Creates a MethodSubstitution where a Java method will be responsible
     * for returning the String to replace a match.
     * <p>
     * If obj is a class the signature of the method must look like:
     * <pre> public static String methodName(MatchResult match) </pre>
     * <p>
     * If obj is not a class the signature of the method must look like:
     * <pre> public String methodName(MatchResult match) </pre>
     * <p>
     * @param obj the class or object having the public method that will
     *            return the substitution
     * @param methodName the name of the method that will return the
     *                   substitution
     * @exception NoSuchMethodException if a matching method is not found
     *            or if the name is "<init>"or "<clinit>"
     * @exception SecurityException if access to the information is denied
     */
    public MethodSubstitution(Object obj, String methodName)
            throws NoSuchMethodException, SecurityException
    {
        this.obj = obj;
        if (obj instanceof Class) {
            this.method = ((Class) obj).getMethod(methodName, paramTypes);
        } else {
            this.method = obj.getClass().getMethod(methodName, paramTypes);
        }
    }

    /**
     * Appends the substitution to a buffer containing the original input
     * with substitutions applied for the pattern matches found so far.
     * See
     * {@link Substitution#appendSubstitution
Substitution.appendSubstition()}
     * for more details regarding the expected behavior of this method.
     * <p>
     * @param appendBuffer The buffer containing the new string resulting
     * from performing substitutions on the original input.
     * @param match The current match causing a substitution to be made.
     * @param substitutionCount  The number of substitutions that have been
     *  performed so far by Util.substitute.
     * @param originalInput The original input upon which the substitutions
     * are being performed.  This is a read-only parameter and is not
     * modified.
     * @param matcher The PatternMatcher used to find the current match.
     * @param pattern The Pattern used to find the current match.
     */
    public void appendSubstitution(StringBuffer appendBuffer,
                 MatchResult match,
                 int substitutionCount,
                 PatternMatcherInput originalInput,
                 PatternMatcher matcher, Pattern pattern)
    {
        try {
            appendBuffer.append(method.invoke(obj, new Object[] {match}));
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}