Craig McClanahan wrote:
On 1/5/06, Laurie Harper <[EMAIL PROTECTED]> wrote:
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


Something like this does make sense ... let's be as explicit as we can when
we run into probems.

That being said, in this case its still something *we* (Shale) are doing, by
composing a value binding expression that might not be valid.  It's also
worth figuring out if we can use an alternate syntax so that a vew
identifier like "foo.bar" would still work.

But ... wait ... its even easier than that.  We should be using the
VariableResolver directly, instead of composing a value binding expression.
This won't care about the syntax, and will be a bit more efficient to boot.

So the variable resolver can look up variable names that contain arbitrary strings? That might work better.

Something that doesn't work as a value binding expression isn't going to be useble in your views for referencing the view controller, of course, but that's already a problem and at least it's probably a little more clear what's wrong then.

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

+1 ... exceptions from the view controller's constructor are the user's
problem :-).

Heh :) Well, this isn't in the user's view controller, it's in ShaleViewController, but I take your point :-)

L.


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

Reply via email to