Craig McClanahan wrote:
On 1/5/06, Laurie Harper <[EMAIL PROTECTED]> wrote:
Thanks to my unusual use of view identifiers carrying path-extra-info
information, I've discovered a bit of a limitation with
DefaultViewControllerMapper: if the result of applying the mapping
algorithm isn't legal as a value binding expression, you get an ugly
stack trace. I triggered this because I have view identifiers which may
include spaces or other 'special' characters which, to be fair, the
Javadoc explicitly states you shouldn't do :-)


There are some alternative ways to code a VB expression that might deal with
some of these issues.  It centers around the fact that, in EL expressions
(as in JavaScript), the following two expressions do the same thing:

    foo.bar

    foo['bar']

so if the "bar" part of your expression has characters that would mess you
up ... a period is the most common one that I've run into ... use the latter
syntax.  This is paticularly handy, for example, when using <f:loadBundle>,
where the message keys in your properties file have periods in them:

    <f:loadBundle name="messages" bundleName="com.mycompany.MyBundle"/>
    ...
    <h:outputLabel ... value="#{messages['username.label']}" .../>

Looking at the bigger picture, any mapper implementation that's not
well-behaved (in terms of returning a value that can be turned into a
value binding) is going to cause this behavior.

I thought it'd be a simple case of catching the exception when the value
binding expression is created (ReferenceSyntaxException from
createValueBinding() or EvaluationException from getValue()), but it
looks like the EL implementation I'm using (from Facelets) is throwing
an implementation exception rather than the correct, documented
exception -- I'm getting a com.sun.faces.el.impl.ElException from
createValueBinding() (using the RI).

Is there any clean way to deal with this, since catching
com.sun.faces.el.impl.ElException in Shale isn't really appropriate...


See above.

You're talking about either changing what's in the view ID, or changing how it's mapped. Both of those will fix the problem on a case-by-case basis, sure.

What I was getting at was more, can we make it so that a 'bad' view controller name doesn't cause a blow-up? What I was going to propose was changing ShaleViewController's setupViewController() method (and other places which use the mapping manager) something like this:

        // Retrieve an existing instance, or one created and configured by
        // the managed bean facility
-       ValueBinding vb =
- context.getApplication().createValueBinding("#{" + viewName + "}");
        ViewController vc = null;
        try {
+           ValueBinding vb =
+ context.getApplication().createValueBinding("#{" + viewName Object vcObject = vb.getValue(context);
            if (vcObject == null) {
                log.warn(messages.getMessage("view.noViewController",
new Object[] { viewId, viewName }));
                return;
            }
            vc = (ViewController) vcObject;
        } catch (ClassCastException e) {
            log.warn(messages.getMessage("view.notViewController",
new Object[] { viewId, viewName }));
            return;
+       } catch (ReferenceSyntaxException e) {
+           // ... log an error/warning and return
+       } catch (EvaluationException e) {
+           // ... log an error/warning and return
        }

The rationale is that

a) Shale users may plug in a naive or broken mapper; it'd be nicer to fail gracefully, letting them know what the problem is, rather than throw an exception

b) Third-party component libraries may (I think?) include navigation rules in their bundled faces-config that point to view IDs which don't conform to the constraints of whatever mapper may be installed

I guess it could just be 'catch Exception' but that seems a little over-protective ;-)

L.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to