users@jersey.java.net

Error-recovery for resource syntax

From: Casper Bang <casper.bang_at_gmail.com>
Date: Tue, 10 Nov 2009 10:15:19 +0100

Hey Jersey list,

Currently, resource mapping for Jersey revolves around regular
expressions. This is simple and powerful of course, however it makes it
hard to assist the user in regard to correct syntax usage. I require
complex expressions, inspired by the Google Charts API, to fetch and
chart meter data in a flexible fashion. To do this, I model a form of
AST by combining regular expressions as tokens, along the line of this
(simplified):

    public final static String registration_type_expression =
            "(" + registration_type + "|" + registration_type_list + ")";

    public final static String meter_list =
            "\\(" + METER +
            "("+
                COMMA +
                METER +
            "){0,4}" +
            "\\)";

    public final static String meter_registration =
            "(" + METER + "|" + meter_list + ")" +
            "(" +
                ":" +
                registration_type_expression +
            ")?";

    public final static String meterRegistrationsExpression =
            meter_registration +
            "("+
                COMMA +
                meter_registration +
            "){0,4}";


Now, in the WADL this becomes relatively useless but it does serve to
validate the expression:

<resource path="meters/{meterRegistrationsExpression:
(\d{1,10}|\(\d{1,10}(,\d{1,10}){0,4}\))(:(([mM][eE][tT][eE][rR][vV][aA][lL][uU][eE]|[tT][eE][mM][pP]/
[eE][rR][aA][tT][uU][rR][eE][cC][uU][rR][rR][eE][nN][tT]|[dD][eE][wW][pP][oO][iI][nN][tT]|[hH][uU]/
[mM][iI][dD][iI][tT][yY]|[cC][oO][nN][sS][uU][mM][pP][tT][iI][oO][nN])|\(([mM][eE][tT][eE][rR][vV][aA]/
[lL][uU][eE]|[tT][eE][mM][pP][eE][rR][aA][tT][uU][rR][eE][cC][uU][rR][rR][eE][nN][tT]|[dD][eE][wW]/
[pP][oO][iI][nN][tT]|[hH][uU][mM][iI][dD][iI][tT][yY]|[cC][oO][nN][sS][uU][mM][pP][tT][iI][oO][nN])(,/
([mM][eE][tT][eE][rR][vV][aA][lL][uU][eE]|[tT][eE][mM][pP][eE][rR][aA][tT][uU][rR][eE][cC][uU][rR]/
[rR][eE][nN][tT]|[dD][eE][wW][pP][oO][iI][nN][tT]|[hH][uU][mM][iI][dD][iI][tT][yY]|[cC][oO][nN][sS]/
[uU][mM][pP][tT][iI][oO][nN])){0,4}\)))?(,(\d{1,10}|\(\d{1,10}(,\d{1,10}){0,4}\))(:(([mM][eE][tT][eE]/
[rR][vV][aA][lL][uU][eE]|[tT][eE][mM][pP][eE][rR][aA][tT][uU][rR][eE][cC][uU][rR][rR][eE][nN][tT]|/
[dD][eE][wW][pP][oO][iI][nN][tT]|[hH][uU][mM][iI][dD][iI][tT][yY]|[cC][oO][nN][sS][uU][mM][pP][tT]/
[iI][oO][nN])|\(([mM][eE][tT][eE][rR][vV][aA][lL][uU][eE]|[tT][eE][mM][pP][eE][rR][aA][tT][uU][rR][eE]/
[cC][uU][rR][rR][eE][nN][tT]|[dD][eE][wW][pP][oO][iI][nN][tT]|[hH][uU][mM][iI][dD][iI][tT][yY]|[cC]/
[oO][nN][sS][uU][mM][pP][tT][iI][oO][nN])(,([mM][eE][tT][eE][rR][vV][aA][lL][uU][eE]|[tT][eE][mM]/
[pP][eE][rR][aA][tT][uU][rR][eE][cC][uU][rR][rR][eE][nN][tT]|[dD][eE][wW][pP][oO][iI][nN][tT]|[hH]/
[uU][mM][iI][dD][iI][tT][yY]|[cC][oO][nN][sS][uU][mM][pP][tT][iI][oO][nN])){0,4}\)))?){0,4}}.png">

However, the problem is how to guide the user. When Jersey can't match a
query to a resource, it ends in a pretty useless 404.

So here's the question: Is it possible to hook into the resource mapping
itself, in a fail-fast fashion such that I can point out to the user
what went wrong? I guess this this will be hard right, realizing that
this is not a classical lookahead(1) parser but done exclusively with
large regular expressions? So perhaps the most obvious thing to do is to
replace the default 404 handler with a custom error-recovery parser?

Any input appreciated, thanks,
Casper