Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

This is a sample class using Rhino (1.7R4). I need it because in the context of JSON Schema, regexes should be ECMA 262. One requirement is that it is thread safe, and it is.

But I'm not sure I actually use it correctly. Can you comment?

public final class RhinoHelper
{
    /**
     * JavaScript scriptlet defining functions {@link #regexIsValid}
     * and {@link #regMatch}
     */
    private static final String jsAsString
        = "function regexIsValid(re)"
        + '{'
        + "    try {"
        + "         new RegExp(re);"
        + "         return true;"
        + "    } catch (e) {"
        + "        return false;"
        + "    }"
        + '}'
        + ""
        + "function regMatch(re, input)"
        + '{'
        + "    return new RegExp(re).test(input);"
        + '}';

    /**
     * Script context to use
     */
    private static final Context ctx;

    /**
     * Script scope
     */
    private static final Scriptable sharedScope;

    /**
     * Reference to Javascript function for regex validation
     */
    private static final Function regexIsValid;

    /**
     * Reference to Javascript function for regex matching
     */
    private static final Function regMatch;

    private RhinoHelper()
    {
    }

    static {
        ctx = Context.enter();
        sharedScope = ctx.initStandardObjects();
        ctx.evaluateString(sharedScope, jsAsString, "re", 1, null);
        regexIsValid = (Function) sharedScope.get("regexIsValid", sharedScope);
        regMatch = (Function) sharedScope.get("regMatch", sharedScope);
        ctx.seal(null);
    }

    /**
     * Validate that a regex is correct
     *
     * @param regex the regex to validate
     * @return true if the regex is valid
     */
    public static boolean regexIsValid(final String regex)
    {
        final Context context = Context.enter();
        try {
            final Scriptable scope = context.newObject(sharedScope);
            scope.setPrototype(sharedScope);
            scope.setParentScope(null);
            return (Boolean) regexIsValid.call(context, scope, scope,
                new Object[]{ regex });
        } finally {
            Context.exit();
        }
    }

    /**
     * <p>Matches an input against a given regex, in the <b>real</b> sense
     * of matching, that is, the regex can match anywhere in the input. Java's
     * {@link java.util.regex} makes the unfortunate mistake to make people
     * believe that matching is done on the whole input... Which is not true.
     * </p>
     *
     * <p>Also note that the regex MUST have been validated at this point
     * (using {@link #regexIsValid(String)}).</p>
     *
     * @param regex the regex to use
     * @param input the input to match against (and again, see description)
     * @return true if the regex matches the input
     */
    public static boolean regMatch(final String regex, final String input)
    {
        final Context context = Context.enter();
        try {
            final Scriptable scope = context.newObject(sharedScope);
            scope.setPrototype(sharedScope);
            scope.setParentScope(null);
            return (Boolean) regMatch.call(context, scope, scope,
                new Object[]{ regex, input });
        } finally {
            Context.exit();
        }

    }
}
share|improve this question

1 Answer 1

private static final Context ctx;

If possible, try to give class variables more descriptive names. ctx could easily be expanded to context.

share|improve this answer
    
I don't know enough about rhino to give you a full answer. –  Pimgd Apr 30 at 11:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.