Hi Thiago,
I've never tried a ComponentRequestFilter for doing things that involved redirection, as they are invoked way later in the Tapestry processing pipeline. Please post if it works. ;)
It turned out that ComponentRequestFilter has several advandatages over RequestFilter: 1.) If a locale is present in the uri, the PersistentLocale is set. No workaround using ComponentEventLinkEncoder's decodeXXX methods needed. 2.) The ThreadLocale already contains a supported locale that can be safely used to set the PersistentLocale. In RequestFilter the ThreadLocale is still the raw one taken from the request. Which might not be in supported-locales. 3.) The methods handlePageRender(...) and handleComponentEvent(...) are a directer way of distiguishing between the two types. In RequestFilter.service(...) you would have to distinguish them on your own by decoding the request with ComponentEventLinkEncoder. 4.) In handleComponentEvent you only have to set the persistent locale. Tapestry generates redirects for component events anyway. So you don't need to bother.

The only (slightly) hard part is building a redirect mechanism in handlePageRender(...). I surfed through Tapestry's source code and found out that PageRenderRequestHandlerImpl uses a ComponentEventResultProcessor for that purpose. I have done that too.

Thanks to you and Howard for helping. And speeking of locales. Its almost 03:00 am local time now. I really need to go to bed. My boss is gonna kill me, if I oversleep (again).
Cheers, nillehammer

P.S. The code:
PersistentLocaleFilter.java:
/**
* Checks, if persistent locale is set. If not will do so and send redirect, if
 * necessary.
 */
final class PersistentLocaleFilter implements ComponentRequestFilter {

    /**
* Used to set the persistent locale (that's what this filter is all about).
     */
    private final PersistentLocale persistentLocale;

    /**
     * Used to determine current locale, if persistent locale is not set.
     */
    private final ThreadLocale threadLocale;

    /**
     * Used to generate a page render link in
* {@link #handlePageRender(PageRenderRequestParameters, ComponentRequestHandler)}
     * .
     */
    private final ComponentEventLinkEncoder componentEventLinkEncoder;

    /**
     * Used to add request parameters to the page render link.
     */
    private final Request request;

    /**
     * Used to process the page render link as a redirect.
     */
private final ComponentEventResultProcessor<Link> componentEventResultProcessor;

    /**
     * Constructor injecting all dependencies.
     *
     * @param persistentLocale
     * @param threadLocale
     * @param componentEventLinkEncoder
     * @param request
     * @param componentEventResultProcessor
     */
    PersistentLocaleFilter(final PersistentLocale persistentLocale,
            final ThreadLocale threadLocale,
            final ComponentEventLinkEncoder componentEventLinkEncoder,
            final Request request,
final ComponentEventResultProcessor<Link> componentEventResultProcessor) {

        this.persistentLocale = persistentLocale;

        this.threadLocale = threadLocale;

        this.componentEventLinkEncoder = componentEventLinkEncoder;

        this.request = request;

        this.componentEventResultProcessor = componentEventResultProcessor;
    }

    /**
* Sets persistent locale if necessary and hands over to the rest of the * chain. Tapestry is generating redirects for component events anyway, so we
     * do not need to do that.
     */
    @Override
    public final void handleComponentEvent(
            final ComponentEventRequestParameters parameters,
            final ComponentRequestHandler handler ) throws IOException {

        setPersistentLocaleIfNecessary();

        handler.handleComponentEvent(parameters);
    }

    /**
* Sets persistent locale if necessary and creates a page render link to
     * redirect to.
     */
    @Override
    public final void handlePageRender(
            final PageRenderRequestParameters parameters,
            final ComponentRequestHandler handler ) throws IOException {

        if (setPersistentLocaleIfNecessary()) {

            final Link pageRedirectLink = this.componentEventLinkEncoder
                    .createPageRenderLink(parameters);

            /*
* pageRedirectLink lacks possible request parameters. We add them * manually. Anchor needs not be added. It stays in the address bar by
             * some magic I don't understand.
             */
for (final String paramName : this.request.getParameterNames()) {

                pageRedirectLink.addParameter(paramName,
                        this.request.getParameter(paramName));
            }

this.componentEventResultProcessor.processResultValue(pageRedirectLink);

            return;
        }

        handler.handlePageRender(parameters);
    }

    /**
     * Checks if persistent locale is set and will set it if necessary.
     *
* @return true, if persistent locale WAS NOT set and therefore had to be set,
     *         otherwise false
     */
    private final boolean setPersistentLocaleIfNecessary() {

        if (!this.persistentLocale.isSet()) {

            /*
* ThreadLocale contains a supported locale. So we can safely use that
             * here. No need for LocalizationSetter.
             */
            this.persistentLocale.set(this.threadLocale.getLocale());

            return true;
        }

        return false;
    }
}

And in AppModule.java:
    public static final ComponentRequestFilter buildPersistentLocaleFilter(
            final PersistentLocale persistentLocale,
            final ThreadLocale threadLocale,
            final ComponentEventLinkEncoder componentEventLinkEncoder,
            final Request request,
            @InjectService("ComponentEventResultProcessor")
final ComponentEventResultProcessor<Link> componentEventResultProcessor ) {

        return new PersistentLocaleFilter(persistentLocale, threadLocale,
componentEventLinkEncoder, request, componentEventResultProcessor);
    }

    public static final void contributeComponentRequestHandler(
final OrderedConfiguration<ComponentRequestFilter> configuration, @InjectService("persistentLocaleFilter") final ComponentRequestFilter persistentLocaleFilter ) {

        configuration.add("persistentLocaleFilter", persistentLocaleFilter,
                "before:*");
    }


--
http://www.winfonet.eu


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to